This is a regression present on the mainline and 4.8 branch. As diagnosed by
Jakub, there is a danling REG_DEAD note on an insn after a first combination
which confuses the distribution of notes during a second combination. In the
first combination, the insn is the other_insn and this insn is handled in a
special way: it doesn't undergo the usual distribution of notes but instead
is patched up separately. The code checks that the REG_UNUSED notes are still
valid for it, it ought to do the same for the REG_DEAD notes.
Tested on x86_64-suse-linux, applied on the mainline and 4.8 branch.
2014-02-12 Eric Botcazou <ebotca...@adacore.com>
PR rtl-optimization/60116
* combine.c (try_combine): Also remove dangling REG_DEAD notes on the
other_insn once the combination has been validated.
2014-02-12 Eric Botcazou <ebotca...@adacore.com>
* gcc.c-torture/execute/20140212-1.c: New test.
--
Eric Botcazou
Index: combine.c
===================================================================
--- combine.c (revision 207685)
+++ combine.c (working copy)
@@ -3894,14 +3894,15 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx
PATTERN (undobuf.other_insn) = other_pat;
- /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
- are still valid. Then add any non-duplicate notes added by
- recog_for_combine. */
+ /* If any of the notes in OTHER_INSN were REG_DEAD or REG_UNUSED,
+ ensure that they are still valid. Then add any non-duplicate
+ notes added by recog_for_combine. */
for (note = REG_NOTES (undobuf.other_insn); note; note = next)
{
next = XEXP (note, 1);
- if (REG_NOTE_KIND (note) == REG_UNUSED
+ if ((REG_NOTE_KIND (note) == REG_DEAD
+ || REG_NOTE_KIND (note) == REG_UNUSED)
&& ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
remove_note (undobuf.other_insn, note);
}
/* PR rtl-optimization/60116 */
/* Reported by Zhendong Su <s...@cs.ucdavis.edu> */
extern void abort (void);
int a, b, c, d = 1, e, f = 1, h, i, k;
char g, j;
void
fn1 (void)
{
int l;
e = 0;
c = 0;
for (;;)
{
k = a && b;
j = k * 54;
g = j * 147;
l = ~g + (long long) e && 1;
if (d)
c = l;
else
h = i = l * 9UL;
if (f)
return;
}
}
int
main (void)
{
fn1 ();
if (c != 1)
abort ();
return 0;
}