diff --git a/gcc/testsuite/gcc.dg/torture/pr118717.c b/gcc/testsuite/gcc.dg/torture/pr118717.c new file mode 100644 index 0000000000000000000000000000000000000000..42dc5ec84f28ae350d47825032f2e52c19b16d0f --- /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 64d3ba9e1607a4e46d5f3c8746109ee749047902..f67f52d2d69abf01b1c5ca1e0c55658c820d54ca 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 e79762b9848b2c418013d750257194a7971e6557..959e0d5c6bea18ff6ef1eea74bb579dda66f000b 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