aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2017-03-20 20:04:25 +0000
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>2017-03-20 20:04:25 +0000
commitc3856045ee8a20e77ce5d9dcaee21949887e447b (patch)
treeccbcf5648b7808b2c65e066ad61a0d0c2d5c120c
parentd43cd87e50ed8188e32ff3445e40d86d64999495 (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/ChangeLog10
-rw-r--r--gcc/gimple-ssa-strength-reduction.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr80054.C40
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);
+}