https://gcc.gnu.org/g:8eca273335750e100efff8f45aee285290be3c46

commit r12-11017-g8eca273335750e100efff8f45aee285290be3c46
Author: Richard Biener <rguent...@suse.de>
Date:   Mon Feb 3 09:55:50 2025 +0100

    tree-optimization/118717 - store commoning vs. abnormals
    
    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.
    
            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.
    
    (cherry picked from commit fbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5)

Diff:
---
 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(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr118717.c 
b/gcc/testsuite/gcc.dg/torture/pr118717.c
new file mode 100644
index 000000000000..42dc5ec84f28
--- /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 558d5b4b57db..3ef7d6b28fcd 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3293,7 +3293,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 8ce4403ddc8f..f747f8adc34f 100644
--- a/gcc/tree-ssa-sink.cc
+++ b/gcc/tree-ssa-sink.cc
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "cfgloop.h"
 #include "tree-eh.h"
+#include "tree-dfa.h"
 
 /* TODO:
    1. Sinking store only using scalar promotion (IE without moving the RHS):
@@ -523,7 +524,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

Reply via email to