diff --git a/gcc/testsuite/gcc.dg/torture/pr96349.c b/gcc/testsuite/gcc.dg/torture/pr96349.c new file mode 100644 index 00000000000..4ce39498213 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr96349.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +void __attribute__ ((returns_twice)) +gr (void); + +void +ib (void); + +void +zg (void); + +void +yw (int uz) +{ + gr (); + + for (;;) + if (uz != 0) + { + uz = 0; + ib (); + } + else + zg (); +} diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c index 7de95b58884..1eb6be5ddb2 100644 --- a/gcc/tree-ssa-loop-split.c +++ b/gcc/tree-ssa-loop-split.c @@ -1145,6 +1145,16 @@ stmt_semi_invariant_p_1 (struct loop *loop, gimple *stmt, if (gimple_bb (stmt) == loop->header) { + /* If the entry value is subject to abnormal coalescing + avoid the transform since we're going to duplicate the + loop header and thus likely introduce overlapping life-ranges + between the PHI def and the entry on the path when the + first loop is skipped. */ + tree entry_def + = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); + if (TREE_CODE (entry_def) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (entry_def)) + return false; invar = loop_iter_phi_semi_invariant_p (loop, phi, skip_head); return invar; }