diff mbox

[PR,tree-optimization/71272] Don't crash on zero length jump thread path

Message ID 963a4401-4bb1-0c83-eb77-ddb44c711d9c@redhat.com
State New
Headers show

Commit Message

Jeff Law May 25, 2016, 10:30 p.m. UTC
I'm expecting to revamp a bit of this code shortly in a way that will 
eliminate the undesirable path stack manipulations.  In the mean time, 
this fixes the regression on the trunk.

Essentially we create a path that looks like

BB X
BB X

in the vector representation.  Which turns into an empty path in the 
jump_thread_path representation and ultimately an OOB array index.

Obviously the revamp alluded to above is supposed to eliminate the 
duplicate BB in the jump thread vector representation.  This patch is a 
short-term workaround.

Bootstrapped and regression tested on x86_64 linux.  Also verified an 
aarch64-elf cross no longer fails on the test by hand.

Installed on the trunk.

Jeff
commit 4a3aab9e315ea1b1c66d8116ef2a263cd5f8bb89
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed May 25 22:25:35 2016 +0000

    	PR tree-optimization/71272
    	* tree-ssa-threadbackward.c (convert_and_register_jump_thread_path):
    	Update comments.  Add test for empty path.
    
    	PR tree-optimization/71272
    	* gcc.c-torture/compile/pr71272.c: new test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@236755 138bc75d-0d04-0410-961f-82ee72b054a4
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 27eeee4..a3c4d90 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2016-05-25  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/71272
+	* tree-ssa-threadbackward.c (convert_and_register_jump_thread_path):
+	Update comments.  Add test for empty path.
+
 2016-05-25  Bill Seurer  <seurer@linux.vnet.ibm.com>
 
 	* config/rs6000/altivec.h (vec_cmpne): Add #define for vec_cmpne.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 30b5d25..61c064f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2016-05-25  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/71272
+	* gcc.c-torture/compile/pr71272.c: new test.
+
 2016-05-25  Bill Seurer  <seurer@linux.vnet.ibm.com>
 
 	* gcc.target/powerpc/vec-cmpne.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71272.c b/gcc/testsuite/gcc.c-torture/compile/pr71272.c
new file mode 100644
index 0000000..22f1498
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr71272.c
@@ -0,0 +1,33 @@ 
+int a, b, c, d;
+
+int
+f1 (int p1, int p2)
+{
+  return p1 - p2;
+}
+
+void
+f2 (short p1, short p2)
+{
+  for (;;)
+    {
+      if (5 < (1 ^ p2))
+        for (; a;)
+          for (;;)
+            {
+              b = 0xE7BC92A3EDA01CD8 < (d = p2) || (0, 0);
+              break;
+            }
+      if (p1)
+        break;
+      p2 = 5;
+    }
+}
+
+void
+f3 (int x)
+{
+  int tmp = -2L;
+  c = f1 (90, x != 10);
+  f2 (c, tmp);
+}
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 4d0fd9c..636b67d 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -373,6 +373,10 @@  convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path,
     {
       basic_block bb1 = (*path)[path->length () - j - 1];
       basic_block bb2 = (*path)[path->length () - j - 2];
+
+      /* This can happen when we have an SSA_NAME as a PHI argument and
+	 its initialization block is the head of the PHI argument's
+	 edge.  */
       if (bb1 == bb2)
 	continue;
 
@@ -382,6 +386,22 @@  convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path,
       jump_thread_path->safe_push (x);
     }
 
+  /* As a consequence of the test for duplicate blocks in the path
+     above, we can get a path with no blocks.  This happens if a
+     conditional can be fully evaluated at compile time using just
+     defining statements in the same block as the test.
+
+     When we no longer push the block associated with a PHI argument
+     onto the stack, then this as well as the test in the loop above
+     can be removed.  */
+  if (jump_thread_path->length () == 0)
+    {
+      jump_thread_path->release ();
+      delete jump_thread_path;
+      path->pop ();
+      return;
+    }
+
   /* Add the edge taken when the control variable has value ARG.  */
   jump_thread_edge *x
     = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);