Message ID | 14297c29-261e-23fb-a9fe-7a1f539fe8d8@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
Series | Fix PR82337 (SLSR and abnormal PHIs) | expand |
On Wed, Sep 27, 2017 at 9:15 PM, Bill Schmidt <wschmidt@linux.vnet.ibm.com> wrote: > 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. Ok for trunk and branches. Thanks, Richard. > Thanks, > Bill > > > 2017-09-26 Bill Schmidt <wschmidt@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); > +} >
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); +}