[Bug rtl-optimization/118739] [15 Regression] wrong code at -O{s,3} with "-fno-tree-forwprop -fno-tree-vrp" on x86_64-linux-gnu since r15-268-g9dbff9c05520a7
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Mar 3 15:57:59 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118739
--- Comment #18 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Uros Bizjak <uros@gcc.gnu.org>:
https://gcc.gnu.org/g:a92dc3fe31c95d56019b2fb95a58414bca06241f
commit r15-7793-ga92dc3fe31c95d56019b2fb95a58414bca06241f
Author: Uros Bizjak <ubizjak@gmail.com>
Date: Wed Feb 12 11:19:57 2025 +0100
combine: Discard REG_UNUSED note in i2 when register is also referenced in
i3 [PR118739]
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.
More information about the Gcc-bugs
mailing list