The following fixes a bug in vop-live get_live_in which was using
NULL to indicate the first processed edge but at the same time
using it for the case the live-in virtual operand cannot be computed.
The following fixes this, avoiding sinking a load to a place where
we'd have to insert virtual PHIs to make the virtual operand SSA
web OK.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/115149
        * tree-ssa-live.cc (virtual_operand_live::get_live_in):
        Explicitly track the first processed edge.

        * gcc.dg/pr115149.c: New testcase.
---
 gcc/testsuite/gcc.dg/pr115149.c | 16 ++++++++++++++++
 gcc/tree-ssa-live.cc            |  8 ++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr115149.c

diff --git a/gcc/testsuite/gcc.dg/pr115149.c b/gcc/testsuite/gcc.dg/pr115149.c
new file mode 100644
index 00000000000..9f6bc97dbe6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr115149.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-inline -fno-tree-vrp -fno-ipa-sra -fno-tree-dce 
-fno-tree-ch" } */
+
+int a, c, e, f, g, h[1], i;
+static int j(int b) { return 0; }
+static void k(int d) {}
+int main()
+{
+  if (h[0])
+    while (1) {
+       k(f && j(i && (h[g] = e)));
+       while (a)
+         c ^= 1;
+    }
+  return 0;
+}
diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc
index e6ae551a457..60dfc05dcd9 100644
--- a/gcc/tree-ssa-live.cc
+++ b/gcc/tree-ssa-live.cc
@@ -1675,14 +1675,18 @@ virtual_operand_live::get_live_in (basic_block bb)
   edge_iterator ei;
   edge e;
   tree livein = NULL_TREE;
+  bool first = true;
   FOR_EACH_EDGE (e, ei, bb->preds)
     if (e->flags & EDGE_DFS_BACK)
       /* We can ignore backedges since if there's a def there it would
         have forced a PHI in the source because it also acts as use
         downstream.  */
       continue;
-    else if (!livein)
-      livein = get_live_out (e->src);
+    else if (first)
+      {
+       livein = get_live_out (e->src);
+       first = false;
+      }
     else if (get_live_out (e->src) != livein)
       /* When there's no virtual use downstream this indicates a point
         where we'd insert a PHI merging the different live virtual
-- 
2.35.3

Reply via email to