https://gcc.gnu.org/g:90a447677a2abb934b683a012b477e6c52088e35

commit r14-10257-g90a447677a2abb934b683a012b477e6c52088e35
Author: Richard Biener <rguent...@suse.de>
Date:   Tue May 21 09:48:04 2024 +0200

    tree-optimization/115149 - VOP live and missing PHIs
    
    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.
    
            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.
    
    (cherry picked from commit ec9b8bafe20755d13ab9a1b834b5da79ae972c0e)

Diff:
---
 gcc/testsuite/gcc.dg/pr115149.c | 16 ++++++++++++++++
 gcc/tree-ssa-live.cc            |  8 ++++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

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 d94e94eb3bc..122d8e245dd 100644
--- a/gcc/tree-ssa-live.cc
+++ b/gcc/tree-ssa-live.cc
@@ -1684,14 +1684,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

Reply via email to