https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83157
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |aoliva at gcc dot gnu.org --- Comment #16 from Jakub Jelinek <jakub at gcc dot gnu.org> --- For the non-LTO -O3 -g case, the issue is that while in the original testcase the value was intentionally used afterwards, main in guality.h ignores the result and so if guality_main is inlined into main, the argc > 0 ? 1 : -1 expression is only used by the guality_check call and so is stored only in a call clobbered register %rsi; that is something we can't use from within the call, so vartrack emits: (note 489 259 262 13 (var_location b (reg:SI 4 si [orig:218 b ] [218])) NOTE_INSN_VAR_LOCATION) (call_insn:TI 262 489 490 13 (call (mem:QI (symbol_ref:DI ("guality_check.constprop.1") [flags 0x3] <function_decl 0x7fe57f634100 guality_check.co...) (note/c 490 262 445 13 (var_location b (nil)) NOTE_INSN_VAR_LOCATION) ... (note 492 491 493 13 (var_location b (nil)) NOTE_INSN_VAR_LOCATION) which says that b lives in %esi on the call insn, but after entering the call it is already optimized away (the note/c) and after the call, as it is gone, it isn't available either. Before var-tracking we have: (insn 399 398 261 13 (set (reg:CCNO 17 flags) (compare:CCNO (reg:SI 3 bx [orig:118 _36 ] [118]) (const_int 0 [0]))) "pr41616-1.c":17 7 {*cmpsi_ccno_1} (expr_list:REG_DEAD (reg:SI 3 bx [orig:118 _36 ] [118]) (nil))) (insn 261 399 400 13 (set (reg:DI 5 di) (symbol_ref/f:DI ("*.LC17") [flags 0x2] <var_decl 0x7fe57f69dcf0 *.LC17>)) "pr41616-1.c":18 85 {*movdi_internal} (nil)) (insn:TI 400 261 325 13 (set (strict_low_part (reg:QI 4 si [orig:133 b ] [133])) (gt:QI (reg:CCNO 17 flags) (const_int 0 [0]))) "pr41616-1.c":17 669 {*setcc_qi_slp} (expr_list:REG_DEAD (reg:CCNO 17 flags) (nil))) (insn:TI 325 400 257 13 (set (reg/v:SI 4 si [orig:133 b ] [133]) (plus:SI (mult:SI (reg/v:SI 4 si [orig:133 b ] [133]) (const_int 2 [0x2])) (const_int -1 [0xffffffffffffffff]))) "pr41616-1.c":17 217 {*leasi} (nil)) (debug_insn 257 325 258 13 (var_location:SI b (reg/v:SI 4 si [orig:133 b ] [133])) -1 (nil)) (nil)) (call_insn:TI 262 259 263 13 (call (mem:QI (symbol_ref:DI ("guality_check.constprop.1") [flags 0x3] <function_decl 0x7fe57f634100 guality_check.co...) ... (debug_insn 267 266 268 13 (var_location:SI b (clobber (const_int 0 [0]))) "guality.h":275 -1 (nil)) The value of b before and during the call is I think: (value/u:SI 131:8790 @0x4cf82b0/0x4ca8e90) locs: from insn 325 (reg/v:SI 4 si [orig:133 b ] [133]) from insn 325 (plus:SI (mult:SI (value/u:SI 130:130 @0x4cf8298/0x4ca8e60) (const_int 2 [0x2])) (const_int -1 [0xffffffffffffffff])) no addrs but unfortunately we don't have locations for: (value/u:SI 130:130 @0x4cf8298/0x4ca8e60) no locs no addrs which is the result of insn 400. Not sure if the problem for var-tracking is strict_low_part or the comparison. If it is the strict_low_part, theoretically we could figure out that the register has been previously set to 0 (current value) and so we could handle it the same as (set (reg:SI 4 si [orig:133 b ] [133])) (gt:SI (reg:SI 3 bx [orig:118 _36 ] [118]) (const_int 0))) because comparisons only set 0 or 1. Small self-contained testcase for that (-g -O2): void bar (int); int foo (int x) { bar (0); int b = x > 0 ? -1 : 1; bar (b); return 0; }