diff mbox series

tree-optimization/115220 - fix store sinking virtual operand constraints

Message ID 20240527104540.9EB313858CDA@sourceware.org
State New
Headers show
Series tree-optimization/115220 - fix store sinking virtual operand constraints | expand

Commit Message

Richard Biener May 27, 2024, 10:45 a.m. UTC
The following makes sure the virtual operand updating when sinking
stores works for the case we ignore paths to kills.  The final
sink location might not post-dominate the original stmt location
which would require inserting of a virtual PHI which we do not support.

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

	PR tree-optimization/115220
	PR tree-optimization/115226
	* tree-ssa-sink.cc (statement_sink_location): When ignoring
	paths to kills when sinking stores make sure the final
	sink location is still post-dominated by the original one.
	Otherwise we'd need to insert a PHI node to merge virtual operands.

	* gcc.dg/torture/pr115220.c: New testcase.
	* gcc.dg/torture/pr115226.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr115220.c | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/torture/pr115226.c | 15 +++++++++++++++
 gcc/tree-ssa-sink.cc                    | 12 +++++++++---
 3 files changed, 38 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr115220.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr115226.c
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr115220.c b/gcc/testsuite/gcc.dg/torture/pr115220.c
new file mode 100644
index 00000000000..e7b5da6ba42
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115220.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "--param logical-op-non-short-circuit=0" } */
+
+extern char **environ;
+static char ***p_environ = &environ;
+int
+_setenv_r (const char *name, const char *value)
+{
+  register char *C;
+  int offset;
+  for (C = (*p_environ)[offset]; (*C = *name++) && *C != '='; ++C);
+  for (*C++ = '='; (*C++ = *value++) != 0;);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr115226.c b/gcc/testsuite/gcc.dg/torture/pr115226.c
new file mode 100644
index 00000000000..9a0bc7c9b6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr115226.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+
+extern void c();
+int a, b;
+int main() {
+  while (b) {
+    int d, e = 0, *f = &a;
+    *f = 1;
+    e = 1 >> d ? : 1 << d;
+    if (e)
+      a = 0;
+    c();
+  }
+  return 0;
+}
diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc
index b0fe871cf1e..8c551e42a4d 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -467,11 +467,17 @@  statement_sink_location (gimple *stmt, basic_block frombb,
   if (!sinkbb)
     return false;
   
-  sinkbb = select_best_block (frombb, sinkbb, stmt);
-  if (sinkbb == frombb)
+  basic_block bestbb = select_best_block (frombb, sinkbb, stmt);
+  if (bestbb == frombb
+      /* When we sink a store make sure there's not a path to any of
+	 the possibly skipped killing defs as that wrecks the virtual
+	 operand update, requiring inserting of a PHI node.  */
+      || (gimple_vdef (stmt)
+	  && bestbb != sinkbb
+	  && !dominated_by_p (CDI_POST_DOMINATORS, bestbb, sinkbb)))
     return false;
 
-  *togsi = gsi_after_labels (sinkbb);
+  *togsi = gsi_after_labels (bestbb);
 
   return true;
 }