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;
+}
+
+
+

Reply via email to