Bug 20222 - Double load of volatile operand for abs builtin
Double load of volatile operand for abs builtin
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: middle-end
3.4.3
: P2 normal
: 4.3.0
Assigned To: Not yet assigned to anyone
: wrong-code
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2005-02-26 15:28 UTC by andy hutchinson
Modified: 2007-09-24 03:58 UTC (History)
4 users (show)

See Also:
Host:
Target: avr
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-13 03:55:41


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description andy hutchinson 2005-02-26 15:28:36 UTC
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])
Comment 1 Andrew Pinski 2005-03-04 20:19:49 UTC
This is a bug in the middle-end:
;; if (ABS_EXPR <xi1> != 1) (void) 0; else goto <L3>;
(insn 29 27 30 (set (reg:HI 44)
        (mem/i:HI (symbol_ref:HI ("xi1") [flags 0x40] <var_decl 0x415784a4 xi1>) [2 xi1+0 S2 A8])) -1 
(nil)
    (nil))

(insn 30 29 31 (set (reg:HI 45)
        (mem/i:HI (symbol_ref:HI ("xi1") [flags 0x40] <var_decl 0x415784a4 xi1>) [2 xi1+0 S2 A8])) -1 
(nil)
    (nil))
Comment 2 Paul Schlie 2005-07-28 21:25:56 UTC
(In reply to comment #0)

- just for the record, it appears that the bug is that when a function is
  inlined using a built-in, a volatile parameter should be accessed only
  once and placed into a temporary, which is then substitued for references
  to that paramter within the body of the function, not the volatile reference
  itself. please see: http://gcc.gnu.org/ml/gcc/2005-07/msg00704.html
Comment 3 Richard Biener 2007-09-23 12:35:05 UTC
Please re-confirm this if this still happens on the mainline as I cannot reproduce
this with a i686 target.
Comment 4 Eric Weddington 2007-09-24 01:45:12 UTC
Subject: RE:  Double load of volatile operand for abs
 builtin



> ------- Comment #3 from rguenth at gcc dot gnu dot org
> 2007-09-23 12:35 -------
> Please re-confirm this if this still happens on the mainline
> as I cannot
> reproduce
> this with a i686 target.

I cannot reproduce bug with 4.3.0 20070914 snapshot.


Comment 5 Wolfgang Bangerth 2007-09-24 03:58:47 UTC
Appears fixed now.