aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-02-03 09:55:50 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-02-03 11:23:22 +0100
commitfbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5 (patch)
tree08b78236ed838b6e8c379f2b382edb30b198bb81
parent75ab30f77f6d8a555aa78472b45a75a508544c68 (diff)
downloadgcc-fbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5.zip
gcc-fbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5.tar.gz
gcc-fbcbbfe2bf83eb8b1347144eeca37b06be5a8bb5.tar.bz2
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.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr118717.c41
-rw-r--r--gcc/tree-ssa-phiopt.cc4
-rw-r--r--gcc/tree-ssa-sink.cc4
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 0000000..42dc5ec
--- /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 64d3ba9..f67f52d 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 e79762b..959e0d5 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