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;
}

Reply via email to