At -g -O2 var1 has a location attribute, but var2 does not. extern unsigned int extfn (char *x); static inline int foo (const char *x, int y) { int a = 0; a = extfn (y ? __builtin_strdup (x) : (char *) x); const char *var1 = x; int var2 = a; __asm__ volatile ("/* %0 %1 */" : : "r" (var1), "r" (var2)); return a; } int bar (const char *x) { return foo (x, 1); } int baz (const char *x) { return foo (x, 0); } although obviously there is a register in which var2 is present (the one passed to the inline asm. The debug stmt is reset during inlining: ./cc1 -O2 -g rh552376.i -fdump-ipa-all -quiet; grep var rh552376.i.04[12]* rh552376.i.041i.cp: # DEBUG var1 => x_4(D) rh552376.i.041i.cp: # DEBUG var2 => a_9 rh552376.i.042i.inline: # DEBUG var1 => x_4(D) rh552376.i.042i.inline: # DEBUG var2 => a_9 rh552376.i.042i.inline: # DEBUG var1 => x_4(D) rh552376.i.042i.inline: # DEBUG var2 => a_9 rh552376.i.042i.inline: # DEBUG var1 => x_1(D) rh552376.i.042i.inline: # DEBUG var2 => NULL rh552376.i.042i.inline: # DEBUG var1 => x_1(D) rh552376.i.042i.inline: # DEBUG var2 => NULL
Created attachment 19506 [details] gcc45-pr42657.patch Inliner fix I'm bootstrapping/regtesting ATM. Unfortunately this isn't enough to fix the testcase. While the debug stmts/insns are preserved until var-tracking - in compgotos we have: (debug_insn 13 10 14 2 rh552376.i:7 (var_location:SI a (reg:SI 0 ax [orig:58 D.2702 ] [58])) -1 (nil)) (debug_insn 14 13 15 2 rh552376.i:8 (var_location:DI var1 (reg/v/f:DI 3 bx [orig:61 x ] [61])) -1 (nil)) (debug_insn 15 14 16 2 rh552376.i:9 (var_location:SI var2 (reg:SI 0 ax [orig:58 D.2702 ] [58])) -1 (nil)) (insn:TI 16 15 27 2 rh552376.i:10 (parallel [ (asm_operands/v ("/* %0 %1 */") ("") 0 [ (reg/v/f:DI 3 bx [orig:61 x ] [61]) (reg:SI 0 ax [orig:58 D.2702 ] [58]) ] [ (asm_input:DI ("r") (null):0) (asm_input:SI ("r") (null):0) ] [] rh552376.i:24) (clobber (reg:QI 18 fpsr)) (clobber (reg:QI 17 flags)) ]) -1 (expr_list:REG_DEAD (reg/v/f:DI 3 bx [orig:61 x ] [61]) (expr_list:REG_UNUSED (reg:QI 18 fpsr) (expr_list:REG_UNUSED (reg:QI 17 flags) (nil))))) var-tracking only gives location for x and var1 and not a and var2: (note/c 44 10 43 2 (var_location x (expr_list:REG_DEP_TRUE (reg/v/f:DI 3 bx [orig:61 x ] [61]) (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION) (note/c 43 44 45 2 (var_location x (expr_list:REG_DEP_TRUE (reg/v/f:DI 3 bx [orig:61 x ] [61]) (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION) (note 45 43 46 2 (var_location a (expr_list:REG_DEP_TRUE (reg:SI 0 ax [orig:58 D.2702 ] [58]) (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION) (note 46 45 48 2 (var_location var1 (expr_list:REG_DEP_TRUE (reg/v/f:DI 3 bx [orig:61 x ] [61]) (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION) (note 48 46 47 2 (var_location var2 (nil)) NOTE_INSN_VAR_LOCATION) (note 47 48 16 2 (var_location a (nil)) NOTE_INSN_VAR_LOCATION) (insn:TI 16 47 27 2 rh552376.i:10 (parallel [ (asm_operands/v ("/* %0 %1 */") ("") 0 [ (reg/v/f:DI 3 bx [orig:61 x ] [61]) (reg:SI 0 ax [orig:58 D.2702 ] [58]) ] The patch actually makes things worse in this testcase, but only in the vartrack phase - that's because compared to without the patch var-tracking now adds both the note 48 and note 47, before that there was neither of these notes. Which means that not only it doesn't know where var2 lives (it didn't know it before either), but doesn't know where a lives either, eventhough the a in %eax was correct. So we need to also fix var-tracking...
http://gcc.gnu.org/ml/gcc-patches/2010-01/msg00430.html http://gcc.gnu.org/ml/gcc-patches/2010-01/msg00431.html
Subject: Bug 42657 Author: jakub Date: Thu Jan 14 22:38:29 2010 New Revision: 155917 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=155917 Log: PR debug/42657 * tree-inline.c (copy_debug_stmt): Don't reset debug stmt just because its first operand is a non-localized variable. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-inline.c
Fixed.