diff options
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr118717.c | 41 | ||||
-rw-r--r-- | gcc/tree-ssa-phiopt.cc | 4 | ||||
-rw-r--r-- | 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 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 |