tree-optimization/118717 - store commoning vs. abnormals

Message ID 20250203102412.7D43B385842D@sourceware.org
State New
Headers
Series tree-optimization/118717 - store commoning vs. abnormals |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Richard Biener Feb. 3, 2025, 10:23 a.m. UTC
  When we sink common stores in cselim or the sink pass we have to
make sure to not introduce overlapping lifetimes for abnormals
used in the ref.  The easiest is to avoid sinking stmts which
reference abnormals at all which is what the following does.

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

	PR tree-optimization/118717
	* tree-ssa-phiopt.cc (cond_if_else_store_replacement_1):
	Do not common stores referencing abnormal SSA names.
	* tree-ssa-sink.cc (sink_common_stores_to_bb): Likewise.

	* gcc.dg/torture/pr118717.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr118717.c | 41 +++++++++++++++++++++++++
 gcc/tree-ssa-phiopt.cc                  |  4 ++-
 gcc/tree-ssa-sink.cc                    |  4 ++-
 3 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr118717.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr118717.c b/gcc/testsuite/gcc.dg/torture/pr118717.c
new file mode 100644
index 00000000000..42dc5ec84f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118717.c
@@ -0,0 +1,41 @@ 
+/* { dg-do compile } */
+
+void jj(void);
+int ff1(void) __attribute__((__returns_twice__));
+struct s2 {
+  int prev;
+};
+typedef struct s1 {
+  unsigned interrupt_flag;
+  unsigned interrupt_mask;
+  int tag;
+  int state;
+}s1;
+int ff(void);
+static inline
+int mm(s1 *ec) {
+  if (ff())
+    if (ec->interrupt_flag & ~(ec)->interrupt_mask)
+      return 0;
+}
+void ll(s1 *ec) {
+  int t = 1;
+  int state;
+  if (t)
+  {
+    {
+      s1 *const _ec = ec;
+      struct s2 _tag = {0};
+      if (ff1())
+	state = ec->state;
+      else
+	state = 0;
+      if (!state)
+	mm (ec);
+      _ec->tag = _tag.prev;
+    }
+    if (state)
+      __builtin_exit(0);
+  }
+  jj();
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 64d3ba9e160..f67f52d2d69 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3646,7 +3646,9 @@  cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
       || else_assign == NULL
       || !gimple_assign_single_p (else_assign)
       || gimple_clobber_p (else_assign)
-      || gimple_has_volatile_ops (else_assign))
+      || gimple_has_volatile_ops (else_assign)
+      || stmt_references_abnormal_ssa_name (then_assign)
+      || stmt_references_abnormal_ssa_name (else_assign))
     return false;
 
   lhs = gimple_assign_lhs (then_assign);
diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc
index e79762b9848..959e0d5c6be 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -36,6 +36,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-eh.h"
 #include "tree-ssa-live.h"
+#include "tree-dfa.h"
 
 /* TODO:
    1. Sinking store only using scalar promotion (IE without moving the RHS):
@@ -516,7 +517,8 @@  sink_common_stores_to_bb (basic_block bb)
 	      gimple *def = SSA_NAME_DEF_STMT (arg);
 	      if (! is_gimple_assign (def)
 		  || stmt_can_throw_internal (cfun, def)
-		  || (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL))
+		  || (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
+		  || stmt_references_abnormal_ssa_name (def))
 		{
 		  /* ???  We could handle some cascading with the def being
 		     another PHI.  We'd have to insert multiple PHIs for