On Wed, 26 Feb 2025, Uros Bizjak wrote: > 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 > 23: {r110:QI=r119:QI|r120:QI;clobber flags:CC;} > REG_DEAD r120:QI > REG_DEAD r119:QI > REG_UNUSED flags:CC > > and creates the following two insn sequence: > > 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. > > where the REG_DEAD note in i2 is not correct, because the flags > register is still referenced in i3. In try_combine() megafunction, > we have this part: > > --cut here-- > /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ > if (i3notes) > distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL, > elim_i2, elim_i1, elim_i0); > if (i2notes) > distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL, > elim_i2, elim_i1, elim_i0); > if (i1notes) > distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL, > elim_i2, local_elim_i1, local_elim_i0); > if (i0notes) > distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULL, > elim_i2, elim_i1, local_elim_i0); > if (midnotes) > distribute_notes (midnotes, NULL, i3, newi2pat ? i2 : NULL, > elim_i2, elim_i1, elim_i0); > --cut here-- > > where the compiler distributes REG_UNUSED note from i2: > > 22: {r120:QI=r104:QI^0x1;clobber flags:CC;} > REG_UNUSED flags:CC > > via distribute_notes() using the following: > > --cut here-- > /* Otherwise, if this register is used by I3, then this register > now dies here, so we must put a REG_DEAD note here unless there > is one already. */ > else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)) > && ! (REG_P (XEXP (note, 0)) > ? find_regno_note (i3, REG_DEAD, > REGNO (XEXP (note, 0))) > : find_reg_note (i3, REG_DEAD, XEXP (note, 0)))) > { > PUT_REG_NOTE_KIND (note, REG_DEAD); > place = i3; > } > --cut here-- > > Flags register is used in I3, but there already is a REG_DEAD note in I3. > The above condition doesn't trigger and continues in the "else" part where > REG_DEAD note is put to I2. The proposed solution corrects the above > logic to trigger every time the register is referenced in I3, avoiding the > "else" part. > > PR rtl-optimization/118739 > > gcc/ChangeLog: > > * combine.cc (distribute_notes) <case REG_UNUSED>: Correct the > logic when the register is used by I3. > > gcc/testsuite/ChangeLog: > > * gcc.target/i386/pr118739.c: New test. > > Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. > > OK for master and eventual backports?
OK if there's no other comments on this until Monday. Thanks, Richard.