tree-optimization/115149 - VOP live and missing PHIs

Message ID 20240521085136.17F1E13A1E@imap1.dmz-prg2.suse.org
State Committed
Commit ec9b8bafe20755d13ab9a1b834b5da79ae972c0e
Headers
Series tree-optimization/115149 - VOP live and missing PHIs |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

Richard Biener May 21, 2024, 8:51 a.m. UTC
  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
  

Patch

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