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?