diff mbox

[PR,tree-optimization/79621] Avoid path isolation on block with edge to itself

Message ID 914638e4-b41e-0623-83b1-fa3f1e853a64@redhat.com
State New
Headers show

Commit Message

Jeff Law Feb. 21, 2017, 5:58 p.m. UTC
Erroneous path isolation inherently duplicates blocks with erroneous 
behavior when reached via certain paths.  This allows us to modify one 
copy without affecting the other.

Block duplication can cause re-allocation of a PHI nodes in successor 
blocks and thus referencing the old PHI references stale data.

This is what's happening in this BZ.  We duplicate the block with an 
edge to itself.  This causes PHIs to be reallocated which 
gimple-ssa-isolate-paths can't handle.

This can only occur in a block which itself as a direct successor and 
which also has some other path that triggers erroneous behavior.

Fixed by avoiding isolation if the block with erroneous behaviour can 
reach itself.  This avoids the ICE, but does leave a missed optimization 
in the IL.  So I'll update the BZ rather than closing.

Bootstrapped and regression tested on x86_64.  Installing on the trunk.

Jeff
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a58a516..a7b0b49 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2017-02-21 Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/79621
+	* gimple-ssa-isolate-paths.c (find_implicit_erroneous_behavior): Ignore
+	blocks with edges to themselves.
+
 2017-02-21  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/79570
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index 25e8c8a..7babe09 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -35,6 +35,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "cfgloop.h"
 #include "tree-cfg.h"
+#include "cfganal.h"
 #include "intl.h"
 
 
@@ -352,6 +353,16 @@  find_implicit_erroneous_behavior (void)
       if (has_abnormal_or_eh_outgoing_edge_p (bb))
 	continue;
 
+
+      /* If BB has an edge to itself, then duplication of BB below
+	 could result in reallocation of BB's PHI nodes.   If that happens
+	 then the loop below over the PHIs would use the old PHI and
+	 thus invalid information.  We don't have a good way to know
+	 if a PHI has been reallocated, so just avoid isolation in
+	 this case.  */
+      if (find_edge (bb, bb))
+	continue;
+
       /* First look for a PHI which sets a pointer to NULL and which
  	 is then dereferenced within BB.  This is somewhat overly
 	 conservative, but probably catches most of the interesting
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f6f2e37..b164483 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2017-02-21  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/79621
+	* gcc.c-torture/compile/pr79621.c: New test.
+
 2017-02-21  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/79570
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr79621.c b/gcc/testsuite/gcc.c-torture/compile/pr79621.c
new file mode 100644
index 0000000..f115c07
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr79621.c
@@ -0,0 +1,18 @@ 
+int b5;
+
+void
+h6 (int zb, int e7)
+{
+  while (b5 > 0)
+    {
+      int gv;
+
+      for (gv = 1; gv < 4; ++gv)
+        {
+          ((zb != 0) ? b5 : gv) && (b5 /= e7);
+          zb = 0;
+        }
+      e7 = 0;
+    }
+}
+