built in abs (and perhaps other) function creates two loads for optimisation -02,-O3 and -Os (-O1 does not have problem)
Also seen on 4.0 head testcase, assembler and RTL dump are attached below. back to back loads of volatile operand i1 are generated in initial RTL. This remains throughout code generation. The second example xi1 without "volatile" also has extra load in initial RTL - but is optimised away. Problem is due to creation of unwanted fetch. extern int xi1; extern volatile int i1; void main (void) { /* First 'abs' on volatile results in TWO loads from stack. */ /* Second 'abs' from global results in two but one is optimised away */ i1 = 1; if (abs (i1) != 1) abort (); if (abs (xi1) != 1) abort (); } 1 .file "testabs-2.c" 2 .arch atmega169 3 __SREG__ = 0x3f 4 __SP_H__ = 0x3e 5 __SP_L__ = 0x3d 6 __tmp_reg__ = 0 7 __zero_reg__ = 1 8 .global __do_copy_data 9 .global __do_clear_bss 17 .Ltext0: 18 .global main 20 main: 21 .LFB2: 22 .LM1: 23 /* prologue: frame size=0 */ 24 0000 C0E0 ldi r28,lo8(__stack - 0) 25 0002 D0E0 ldi r29,hi8(__stack - 0) 26 0004 DEBF out __SP_H__,r29 27 0006 CDBF out __SP_L__,r28 28 /* prologue end (size=4) */ 29 .LM2: 30 0008 81E0 ldi r24,lo8(1) 31 000a 90E0 ldi r25,hi8(1) 32 000c 9093 0000 sts (i1)+1,r25 33 0010 8093 0000 sts i1,r24 34 .LBB2: 35 .LM3: 36 0014 8091 0000 lds r24,i1 37 0018 9091 0000 lds r25,(i1)+1 38 001c 8091 0000 lds r24,i1 39 0020 9091 0000 lds r25,(i1)+1 40 0024 97FD sbrc r25,7 41 0026 0BC0 rjmp .L8 42 .L3: 43 .LM4: 44 0028 0197 sbiw r24,1 45 002a 89F4 brne .L6 46 .LBE2: 47 .LBB3: 48 .LM5: 49 002c 8091 0000 lds r24,xi1 50 0030 9091 0000 lds r25,(xi1)+1 51 0034 97FD sbrc r25,7 52 0036 07C0 rjmp .L9 53 .L5: 54 0038 0197 sbiw r24,1 55 003a 59F0 breq .L1 56 003c 08C0 rjmp .L6 57 .L8: 58 .LBE3: 59 .LBB4: 60 .LM6: 61 003e 9095 com r25 62 0040 8195 neg r24 63 0042 9F4F sbci r25,lo8(-1) 64 0044 F1CF rjmp .L3 65 .L9: 66 .LBE4: 67 .LBB5: 68 .LM7: 69 0046 9095 com r25 70 0048 8195 neg r24 71 004a 9F4F sbci r25,lo8(-1) 72 004c F5CF rjmp .L5 73 .L6: 74 .LBB6: 75 .LM8: 76 004e 0E94 0000 call abort 77 .L1: 78 .LBE6: 79 .LBE5: 80 /* epilogue: frame size=0 */ 81 0052 0C94 0000 jmp exit 82 /* epilogue end (size=2) */ 83 /* function main size 45 (39) */ 84 .LFE2: 86 .Letext0: DEFINED SYMBOLS *ABS*:00000000 testabs-2.c *ABS*:0000003f __SREG__ *ABS*:0000003e __SP_H__ *ABS*:0000003d __SP_L__ *ABS*:00000000 __tmp_reg__ *ABS*:00000001 __zero_reg__ c:\DOCUME~1\Andy\LOCALS~1\Temp/ccgXaaaa.s:20 .text:00000000 main UNDEFINED SYMBOLS __do_copy_data __do_clear_bss __stack i1 xi1 abort exit ;; Function main (note 1 0 2 ("testabs-2.c") 5) (note 2 1 3 NOTE_INSN_DELETED) (note 3 2 4 NOTE_INSN_FUNCTION_BEG) (note 4 3 5 NOTE_INSN_DELETED) (note 5 4 6 007292A8 NOTE_INSN_BLOCK_BEG) (note 6 5 7 NOTE_INSN_DELETED) (note 7 6 8 ("testabs-2.c") 9) (insn 8 7 9 (set (reg:HI 41) (const_int 1 [0x1])) -1 (nil) (nil)) (insn 9 8 10 (set (mem/v/f:HI (symbol_ref:HI ("i1") [flags 0x40] <var_decl 007CCBD0 i1>) [2 i1+0 S2 A8]) (reg:HI 41)) -1 (nil) (nil)) (note 10 9 11 00729230 NOTE_INSN_BLOCK_BEG) (note 11 10 12 NOTE_INSN_DELETED) (note 12 11 13 ("testabs-2.c") 11) (insn 13 12 14 (set (reg:HI 42) (mem/v/f:HI (symbol_ref:HI ("i1") [flags 0x40] <var_decl 007CCBD0 i1>) [2 i1+0 S2 A8])) -1 (nil) (nil)) (insn 14 13 15 (set (reg:HI 43) (mem/v/f:HI (symbol_ref:HI ("i1") [flags 0x40] <var_decl 007CCBD0 i1>) [2 i1+0 S2 A8])) -1 (nil) (nil)) (insn 15 14 16 (set (cc0) (reg:HI 43)) -1 (nil) (nil)) (jump_insn 16 15 17 (set (pc) (if_then_else (ge (cc0) (const_int 0 [0x0])) (label_ref 18) (pc))) -1 (nil) (nil)) (insn 17 16 18 (set (reg:HI 43) (neg:HI (reg:HI 43))) -1 (nil) (nil)) (code_label 18 17 19 3 "" [0 uses]) (insn 19 18 20 (parallel [ (set (cc0) (compare (reg:HI 43) (const_int 1 [0x1]))) (clobber (scratch:QI)) ]) -1 (nil) (nil)) (jump_insn 20 19 21 (set (pc) (if_then_else (eq (cc0) (const_int 0 [0x0])) (label_ref 27) (pc))) -1 (nil) (nil)) (note 21 20 22 00729208 NOTE_INSN_BLOCK_BEG) (note 22 21 23 NOTE_INSN_DELETED) (note 23 22 24 ("testabs-2.c") 12) (call_insn 24 23 25 (call (mem:HI (symbol_ref:HI ("abort") [flags 0x41] <function_decl 00779690 abort>) [0 S2 A8]) (const_int 0 [0x0])) -1 (nil) (expr_list:REG_NORETURN (const_int 0 [0x0]) (expr_list:REG_EH_REGION (const_int 0 [0x0]) (nil))) (nil)) (barrier 25 24 26) (note 26 25 27 00729208 NOTE_INSN_BLOCK_END) (code_label 27 26 28 2 "" [0 uses]) (note 28 27 29 00729230 NOTE_INSN_BLOCK_END) (note 29 28 30 00729280 NOTE_INSN_BLOCK_BEG) (note 30 29 31 NOTE_INSN_DELETED) (note 31 30 32 ("testabs-2.c") 13) (insn 32 31 33 (set (reg:HI 44) (mem/f:HI (symbol_ref:HI ("xi1") [flags 0x40] <var_decl 007CCAF0 xi1>) [2 xi1+0 S2 A8])) -1 (nil) (nil)) (insn 33 32 34 (set (reg:HI 45) (mem/f:HI (symbol_ref:HI ("xi1") [flags 0x40] <var_decl 007CCAF0 xi1>) [2 xi1+0 S2 A8])) -1 (nil) (nil)) (insn 34 33 35 (set (cc0) (reg:HI 45)) -1 (nil) (nil)) (jump_insn 35 34 36 (set (pc) (if_then_else (ge (cc0) (const_int 0 [0x0])) (label_ref 37) (pc))) -1 (nil) (nil)) (insn 36 35 37 (set (reg:HI 45) (neg:HI (reg:HI 45))) -1 (nil) (nil)) (code_label 37 36 38 5 "" [0 uses]) (insn 38 37 39 (parallel [ (set (cc0) (compare (reg:HI 45) (const_int 1 [0x1]))) (clobber (scratch:QI)) ]) -1 (nil) (nil)) (jump_insn 39 38 40 (set (pc) (if_then_else (eq (cc0) (const_int 0 [0x0])) (label_ref 46) (pc))) -1 (nil) (nil)) (note 40 39 41 00729258 NOTE_INSN_BLOCK_BEG) (note 41 40 42 NOTE_INSN_DELETED) (note 42 41 43 ("testabs-2.c") 14) (call_insn 43 42 44 (call (mem:HI (symbol_ref:HI ("abort") [flags 0x41] <function_decl 00779690 abort>) [0 S2 A8]) (const_int 0 [0x0])) -1 (nil) (expr_list:REG_NORETURN (const_int 0 [0x0]) (expr_list:REG_EH_REGION (const_int 0 [0x0]) (nil))) (nil)) (barrier 44 43 45) (note 45 44 46 00729258 NOTE_INSN_BLOCK_END) (code_label 46 45 47 4 "" [0 uses]) (note 47 46 48 00729280 NOTE_INSN_BLOCK_END) (note 48 47 49 007292A8 NOTE_INSN_BLOCK_END) (note 49 48 50 NOTE_INSN_FUNCTION_END) (note 50 49 51 ("testabs-2.c") 16) (code_label 51 50 0 1 "" [0 uses]) -- Summary: [AVR] Double load of volatile operand Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: andrewhutchinson at cox dot net CC: gcc-bugs at gcc dot gnu dot org GCC target triplet: avr http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20222