On Wed, Feb 12, 2025 at 4:16 PM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> Uros Bizjak <ubiz...@gmail.com> writes:
> > The combine pass is trying to combine:
> >
> > Trying 16, 22, 21 -> 23:
> >    16: r104:QI=flags:CCNO>0
> >    22: {r120:QI=r104:QI^0x1;clobber flags:CC;}
> >       REG_UNUSED flags:CC
> >    21: r119:QI=flags:CCNO<=0
> >       REG_DEAD flags:CCNO
>
> It looks like something has already gone wrong in this sequence,
> in that insn 21 is using the flags after the register has been clobbered.
> If the flags result of insn 22 is useful, the insn should be setting the
> flags using a parallel of two sets.

Please note that the insn sequence before combine pass is correct:

   16: r104:QI=flags:CCNO>0
   21: r119:QI=flags:CCNO<=0
      REG_DEAD flags:CCNO
   22: {r120:QI=r104:QI^0x1;clobber flags:CC;}
      REG_UNUSED flags:CC
   23: {r110:QI=r119:QI|r120:QI;clobber flags:CC;}
      REG_DEAD r120:QI
      REG_DEAD r119:QI
      REG_UNUSED flags:CC

then combine tries to make the combined insn with:

Trying 16, 22, 21 -> 23:

where:

Failed to match this instruction:
(parallel [
        (set (reg:QI 110 [ d_lsm_flag.20 ])
            (le:QI (reg:CCNO 17 flags)
                (const_int 0 [0])))
        (clobber (reg:CC 17 flags))
        (set (reg:QI 104 [ _36 ])
            (gt:QI (reg:CCNO 17 flags)
                (const_int 0 [0])))
    ])
Failed to match this instruction:
(parallel [
        (set (reg:QI 110 [ d_lsm_flag.20 ])
            (le:QI (reg:CCNO 17 flags)
                (const_int 0 [0])))
        (set (reg:QI 104 [ _36 ])
            (gt:QI (reg:CCNO 17 flags)
                (const_int 0 [0])))
    ])
Successfully matched this instruction:
(set (reg:QI 104 [ _36 ])
    (gt:QI (reg:CCNO 17 flags)
        (const_int 0 [0])))
Successfully matched this instruction:
(set (reg:QI 110 [ d_lsm_flag.20 ])
    (le:QI (reg:CCNO 17 flags)
        (const_int 0 [0])))
allowing combination of insns 16, 21, 22 and 23
original costs 4 + 4 + 4 + 4 = 16
replacement costs 4 + 4 = 8
deferring deletion of insn with uid = 21.
deferring deletion of insn with uid = 16.
modifying insn i2    22: r104:QI=flags:CCNO>0
      REG_DEAD flags:CC
deferring rescan insn with uid = 22.
modifying insn i3    23: r110:QI=flags:CCNO<=0
      REG_DEAD flags:CC
deferring rescan insn with uid = 23.

Combined instruction is OK, but when insn is split into two, it
propagates REG_UNUSED from insn 22 (and converting them to REG_DEAD on
the fly in the referred code) to insn i2. This is clearly wrong when
flags reg is used in insn i3. I don't see anything wrong besides this.

Uros.

Reply via email to