diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2017-03-20 20:04:25 +0000 |
---|---|---|
committer | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2017-03-20 20:04:25 +0000 |
commit | c3856045ee8a20e77ce5d9dcaee21949887e447b (patch) | |
tree | ccbcf5648b7808b2c65e066ad61a0d0c2d5c120c | |
parent | d43cd87e50ed8188e32ff3445e40d86d64999495 (diff) |
[gcc]
2017-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/80054
* gimple-ssa-strength-reduction.c (all_phi_incrs_profitable): Fail
the optimization if a PHI or any of its arguments is not dominated
by the candidate's basis. Use gphi* rather than gimple* as
appropriate.
(replace_profitable_candidates): Clean up a gimple* variable that
should be a gphi* variable.
[gcc/testsuite]
2017-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/80054
* g++.dg/torture/pr80054.C: New file.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@246290 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/gimple-ssa-strength-reduction.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr80054.C | 40 |
4 files changed, 76 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 188a561963b..07fc63898d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR tree-optimization/80054 + * gimple-ssa-strength-reduction.c (all_phi_incrs_profitable): Fail + the optimization if a PHI or any of its arguments is not dominated + by the candidate's basis. Use gphi* rather than gimple* as + appropriate. + (replace_profitable_candidates): Clean up a gimple* variable that + should be a gphi* variable. + 2017-03-20 Martin Sebor <msebor@redhat.com> PR c++/52477 diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 9ebe1989bd2..ca154c51bfc 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -3279,17 +3279,34 @@ insert_initializers (slsr_cand_t c) } /* Return TRUE iff all required increments for candidates feeding PHI - are profitable to replace on behalf of candidate C. */ + are profitable (and legal!) to replace on behalf of candidate C. */ static bool -all_phi_incrs_profitable (slsr_cand_t c, gimple *phi) +all_phi_incrs_profitable (slsr_cand_t c, gphi *phi) { unsigned i; slsr_cand_t basis = lookup_cand (c->basis); slsr_cand_t phi_cand = *stmt_cand_map->get (phi); + /* If the basis doesn't dominate the PHI (including when the PHI is + in the same block as the basis), we won't be able to create a PHI + using the basis here. */ + basic_block basis_bb = gimple_bb (basis->cand_stmt); + basic_block phi_bb = gimple_bb (phi); + + if (phi_bb == basis_bb + || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb)) + return false; + for (i = 0; i < gimple_phi_num_args (phi); i++) { + /* If the PHI arg resides in a block not dominated by the basis, + we won't be able to create a PHI using the basis here. */ + basic_block pred_bb = gimple_phi_arg_edge (phi, i)->src; + + if (!dominated_by_p (CDI_DOMINATORS, pred_bb, basis_bb)) + return false; + tree arg = gimple_phi_arg_def (phi, i); if (!operand_equal_p (arg, phi_cand->base_expr, 0)) @@ -3298,7 +3315,7 @@ all_phi_incrs_profitable (slsr_cand_t c, gimple *phi) if (gimple_code (arg_def) == GIMPLE_PHI) { - if (!all_phi_incrs_profitable (c, arg_def)) + if (!all_phi_incrs_profitable (c, as_a <gphi *> (arg_def))) return false; } else @@ -3565,7 +3582,7 @@ replace_profitable_candidates (slsr_cand_t c) { if (phi_dependent_cand_p (c)) { - gimple *phi = lookup_cand (c->def_phi)->cand_stmt; + gphi *phi = as_a <gphi *> (lookup_cand (c->def_phi)->cand_stmt); if (all_phi_incrs_profitable (c, phi)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b6d7c6286c..121c3dc7c31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR tree-optimization/80054 + * g++.dg/torture/pr80054.C: New file. + 2017-03-20 Kelvin Nilsen <kelvin@gcc.gnu.org> PR target/79963 diff --git a/gcc/testsuite/g++.dg/torture/pr80054.C b/gcc/testsuite/g++.dg/torture/pr80054.C new file mode 100644 index 00000000000..50de24ae821 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr80054.C @@ -0,0 +1,40 @@ +/* { dg-do compile } */ + +/* Used to fail in SLSR because of a dominance violation. PR80054. */ + +extern short var_2; +extern short var_4; +extern const bool var_32; +extern short var_36; +extern const bool var_37; +extern bool var_46; +extern unsigned int var_47; +extern short var_49; +extern unsigned int var_56; +extern unsigned int var_62; +extern unsigned int var_65; +extern bool var_831; +extern unsigned int var_843; +extern short var_846; +extern short var_889; + +void foo() { + if (var_36 * var_37) + var_831 = var_56 = 0; + else + var_65 = 0; + + if (var_46) + var_843 = 0; + + var_846 = 0; + + if ((var_4 == 0) >> (var_32 | -(var_37 < var_46 || var_36)) + 8) + var_49 = 2032651381 * bool(var_2 * var_37); + else { + var_62 = 0; + var_47 = (var_46 || var_36) * (var_2 * var_37); + } + + var_889 = bool(var_2 * var_37); +} |