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

--- Comment #4 from ktkachov at gcc dot gnu.org ---
A carry-setting instruction gets deleted. Among the disassembly the non-failing
assembly has this:

        cmp     x13, 0
        asr     w0, w0, w4
        cset    w4, ne
        sxtw    x0, w0
        adrp    x12, d
        sub     w4, w7, w4
        sxtw    x9, w7
        add     w4, w4, w6
        asr     x6, x0, 63
        cmn     x4, x2  // sets the carry flag
        asr     x1, x9, 63
        cinc    x3, x3, cs // Uses the carry flag

The bad disassembly has this:

        cmp     x4, 0
        adrp    x13, d
        cset    w4, ne
        asr     x7, x0, 63
        sxtw    x6, w8
        cinc    x1, x3, cs // use of carry flag, but the setter was eliminated

Combine ends up eliminating the carry-setting instruction:
(insn 55 52 56 2 (set (reg:CC_C 66 cc)
        (ne:CC_C (plus:TI (zero_extend:TI (reg:DI 165))
                (zero_extend:TI (reg:DI 2 x2 [ h ])))
            (zero_extend:TI (plus:DI (reg:DI 165)
                    (reg:DI 2 x2 [ h ]))))) "bad.c":23 104
{*adddi3_compareC_cconly}
     (nil))

From what I can see in the combine logs:

Trying 55 -> 70:
   55:
{cc:CC_C=zero_extend(r165:DI)+zero_extend(x2:DI)!=zero_extend(r165:DI+x2:DI);r167:DI=r165:DI+x2:DI;}
      REG_DEAD x2:DI
      REG_DEAD r165:DI
   70: r178:DI=r167:DI
      REG_DEAD r167:DI

After a few failed PARALLEL formation it succeeds twice with:
Successfully matched this instruction:
(set (reg:CC_C 66 cc)
    (ne:CC_C (plus:TI (zero_extend:TI (reg:DI 165))
            (zero_extend:TI (reg:DI 2 x2 [ h ])))
        (zero_extend:TI (plus:DI (reg:DI 165)
                (reg:DI 2 x2 [ h ])))))
Successfully matched this instruction:
(set (reg:DI 178)
    (plus:DI (reg:DI 165)
        (reg:DI 2 x2 [ h ])))
allowing combination of insns 55 and 70
original costs 0 + 0 = 0
replacement costs 24 + 4 = 28
deferring deletion of insn with uid = 55.
modifying insn i2    55:
cc:CC_C=zero_extend(r165:DI)+zero_extend(x2:DI)!=zero_extend(r165:DI+x2:DI)
deferring rescan insn with uid = 55.
modifying insn i3    70: r178:DI=r165:DI+x2:DI
      REG_DEAD r165:DI
      REG_DEAD x2:DI
deferring rescan insn with uid = 70.

so it seems like it deletes insn 55 but then also modifies it?

Reply via email to