Hi,
After investigation, I believe PR78559 is a combine issue revealed by tree
level change. Root causes is after replacing CC register use in
undobuf.other_insn, its REG_EQUAL/REG_EQUIV notes are no longer valid because
meaning of CC register has changed in i2/i3 instructions by combine. For
following combine sequence, GCC would try to use the note and result in wrong
code. This is a proposed patch discarding all REG_EQUAL/REG_EQUIV notes for
other_insn. It might be a over-kill, but it's difficult to analyze whether
registers have been changed or not? Bootstrap and test on x86_64 and AArch64,
any suggestion on how to fix this?
Thanks,
bin
2016-12-01 Bin Cheng <bin.ch...@arm.com>
PR rtl-optimization/78559
* combine.c (try_combine): Discard REG_EQUAL and REG_EQUIV for
other_insn in combine.
gcc/testsuite/ChangeLog
2016-12-01 Bin Cheng <bin.ch...@arm.com>
PR rtl-optimization/78559
* gcc.c-torture/execute/pr78559.c: New test.
diff --git a/gcc/combine.c b/gcc/combine.c
index 22fb7a9..93b0901 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4138,7 +4138,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1,
rtx_insn *i0,
PATTERN (undobuf.other_insn)))
||(REG_NOTE_KIND (note) == REG_UNUSED
&& !reg_set_p (XEXP (note, 0),
- PATTERN (undobuf.other_insn))))
+ PATTERN (undobuf.other_insn)))
+ || REG_NOTE_KIND (note) == REG_EQUAL
+ || REG_NOTE_KIND (note) == REG_EQUIV)
remove_note (undobuf.other_insn, note);
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78559.c
b/gcc/testsuite/gcc.c-torture/execute/pr78559.c
new file mode 100644
index 0000000..1db1519
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr78559.c
@@ -0,0 +1,34 @@
+/* PR rtl-optimization/78559 */
+
+int g = 20;
+int d = 0;
+
+short
+fn2 (int p1, int p2)
+{
+ return p2 >= 2 || 5 >> p2 ? p1 : p1 << p2;
+}
+
+int
+main ()
+{
+ int result = 0;
+lbl_2582:
+ if (g)
+ {
+ for (int c = -3; c; c++)
+ result = fn2 (1, g);
+ }
+ else
+ {
+ for (int i = 0; i < 2; i += 2)
+ if (d)
+ goto lbl_2582;
+ }
+ if (result != 1)
+ __builtin_abort ();
+ return 0;
+}
+
+
+