Hi, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82337 reports a problem with SLSR performing an invalid optimization across an abnormal PHI. This is easy to avoid by ensuring that SSA names used in an abnormal PHI never appear as a basis or as a PHI basis in the candidate table. We won't optimize what we can't see...
I've cleaned up the test case in the bug report so that it compiles without warnings and added it to the torture tests. Bootstrapped and tested on powerpc64le-linux-gnu with no regressions. Is this ok for trunk? I would also like to backport it to all open releases after a short wait. Thanks, Bill 2017-09-26 Bill Schmidt <wschm...@linux.vnet.ibm.com> PR tree-optimization/82337 * gimple-ssa-strength-reduction.c (find_phi_def): Don't record a phi definition if the PHI result appears in an abnormal PHI. (find_basis_for_base_expr): Don't record a basis if the LHS of the basis appears in an abnormal PHI. Index: gcc/gimple-ssa-strength-reduction.c =================================================================== --- gcc/gimple-ssa-strength-reduction.c (revision 253232) +++ gcc/gimple-ssa-strength-reduction.c (working copy) @@ -488,7 +488,8 @@ find_phi_def (tree base) c = base_cand_from_table (base); - if (!c || c->kind != CAND_PHI) + if (!c || c->kind != CAND_PHI + || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (c->cand_stmt))) return 0; return c->cand_num; @@ -557,6 +558,11 @@ find_basis_for_base_expr (slsr_cand_t c, tree base gimple_bb (one_basis->cand_stmt))) continue; + tree lhs = gimple_assign_lhs (one_basis->cand_stmt); + if (lhs && TREE_CODE (lhs) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) + continue; + if (!basis || basis->cand_num < one_basis->cand_num) basis = one_basis; } Index: gcc/testsuite/gcc.c-torture/compile/pr82337.c =================================================================== --- gcc/testsuite/gcc.c-torture/compile/pr82337.c (nonexistent) +++ gcc/testsuite/gcc.c-torture/compile/pr82337.c (working copy) @@ -0,0 +1,25 @@ +/* PR82337: SLSR needs to prevent abnormal SSA names from + serving as a basis. */ +char *a, *b, *c; + +struct d { + short e; + char f[]; +}; + +extern void j (void); + +void +g() { + struct d *h; + char *i; + int d; + do { + i = h->f + d; + 20 ? j() : 0; + i = c; + if (__builtin_setjmp (h)) + b = h->f + d; + d = (int)(*i); + } while (a); +}