re PR middle-end/80422 (ICE on valid code at -O3 in 32-bit mode on x86_64-linux-gnu...
authorJeff Law <law@redhat.com>
Tue, 18 Apr 2017 17:31:30 +0000 (11:31 -0600)
committerJeff Law <law@gcc.gnu.org>
Tue, 18 Apr 2017 17:31:30 +0000 (11:31 -0600)
PR middle-end/80422
* cfgcleanup.c (try_crossjump_to_edge): Verify SRC1 and SRC2 have
predecessors after walking up the insn chain.

PR middle-end/80422
* gcc.c-torture/compile/pr80422.c: New test.

From-SVN: r246975

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr80422.c [new file with mode: 0644]

index 38c0d301765751ab6f0bee469e443f1442140788..67751810e4a8af555dac701c91bdfe89f3a0ffe4 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-18  Jeff Law  <law@redhat.com>
+
+       PR middle-end/80422
+       * cfgcleanup.c (try_crossjump_to_edge): Verify SRC1 and SRC2 have
+       predecessors after walking up the insn chain.
+
 2017-04-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/80263
index d55b0ceb832edc87467d3db0dd8ab2ffda1282f6..f68a964e31e9389944ef9587d99edeb19965b70f 100644 (file)
@@ -2017,6 +2017,11 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
   if (newpos2 != NULL_RTX)
     src2 = BLOCK_FOR_INSN (newpos2);
 
+  /* Check that SRC1 and SRC2 have preds again.  They may have changed
+     above due to the call to flow_find_cross_jump.  */
+  if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
+    return false;
+
   if (dir == dir_backward)
     {
 #define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
index 4157094c399095f32d58a0e12a5528970b7ff1cb..cf5d0be6da340b87a9625fe4dd70fc2967a25c12 100644 (file)
@@ -1,3 +1,8 @@
+2017-04-18  Jeff Law  <law@redhat.com>
+
+       PR middle-end/80422
+       * gcc.c-torture/compile/pr80422.c: New test.
+
 2017-04-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/80263
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr80422.c b/gcc/testsuite/gcc.c-torture/compile/pr80422.c
new file mode 100644 (file)
index 0000000..2cece67
--- /dev/null
@@ -0,0 +1,26 @@
+
+int a, c, f;
+short b, d, e;
+
+int fn1 (int h)
+{ 
+  return a > 2 || h > a ? h : h << a;
+}
+
+void fn2 ()
+{ 
+  int j, k;
+  while (1)
+    { 
+      k = c && b;
+      f &= e > (fn1 (k) && j);
+      if (!d)
+        break;
+    }
+}
+
+int main ()
+{ 
+  fn2 ();
+  return 0;
+}