[Bug middle-end/87852] [9 Regression] FAIL: gcc.c-torture/execute/pr53465.c

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Nov 2 11:01:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87852

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ebotcazou at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we have, after inserting the backedge copy

  <bb 3> [local count: 1034442873]:
  # c_22 = PHI <c_10(D)(2), d_14(6)>
  c_2 = c_22;
  d_14 = MEM[base: x_12(D), index: _9, step: 4, offset: 0B];
  if (d_14 == 0)
    goto <bb 7>; [3.66%]
  else
    goto <bb 4>; [96.34%]

  <bb 4> [local count: 996582264]:
  _4 = b_21 != 0;
  _5 = d_14 <= c_2;
  _6 = _4 & _5;
  if (_6 != 0)

and we coalesce c_22 and d_14 (as desired).

But then somehow fwprop comes along and changes

(insn 14 13 15 4 (set (reg/v:SI 83 [ c ])
        (reg/v:SI 88 [ d ])) 67 {*movsi_internal}
     (nil))
(insn 15 14 16 4 (set (reg/v:SI 88 [ d ])
        (mem:SI (plus:SI (mult:SI (reg/v:SI 89 [ i ])
                    (const_int 4 [0x4]))
                (reg/v/f:SI 90 [ x ])) [0 MEM[base: x_12(D), index: _9, step:
4, offset: 0B]+0 S4 A32]))
"/space/rguenther/src/gcc-slpcost/gcc/testsuite/gcc.c-torture/execute/pr53465.c":15:11
67 {*movsi_internal}
     (nil))
...
(insn 23 42 24 6 (set (reg:CCGC 17 flags)
        (compare:CCGC (reg/v:SI 88 [ d ])
            (reg/v:SI 83 [ c ])))
"/space/rguenther/src/gcc-slpcost/gcc/testsuite/gcc.c-torture/execute/pr53465.c":18:18
11 {*cmpsi_1}
     (nil))


In insn 23, replacing
 (compare:CCGC (reg/v:SI 88 [ d ])
        (reg/v:SI 83 [ c ]))
 with (compare:CCGC (reg/v:SI 88 [ d ])
        (reg/v:SI 88 [ d ]))

it looks like it forwards the copy in insn 14 across the setter of 88 in insn
15!?  Note that 88 is initially undefined!

In fwprop use_killed_between returns false because of the following which
is of course bogus if you consider backedges and coalescing with
uninitialized regs.  That is, what applies to hard regs also applies
to regs that are used uninitialized.

  /* Check if the reg in USE has only one definition.  We already
     know that this definition reaches use, or we wouldn't be here.
     However, this is invalid for hard registers because if they are
     live at the beginning of the function it does not mean that we
     have an uninitialized access.  */
  regno = DF_REF_REGNO (use);
  def = DF_REG_DEF_CHAIN (regno);
  if (def
      && DF_REF_NEXT_REG (def) == NULL
      && regno >= FIRST_PSEUDO_REGISTER)
    return false;

So maybe this is what triggers the issue - the copy that is inserted
references an uninitialized value (well, on SSA the PHI node constitutes
a copy from that uninit value already).

Eric, you added partitions_for_undefined_values and IIRC that was just narrow
scope enough to fix a specific issue but not generally address shortcomings
within RTL?


More information about the Gcc-bugs mailing list