aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Schmidt <wschmidt@gcc.gnu.org>2018-10-19 18:28:11 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2018-10-19 18:28:11 +0000
commit3146c60f16558e7eae1039ba6c937f75413ce4f9 (patch)
tree1095403462d7da08f6d6f4b0e38a5135c80d380c
parent273f3d4bb4734845ce527bf92b4781e288e4aae2 (diff)
downloadgcc-3146c60f16558e7eae1039ba6c937f75413ce4f9.zip
gcc-3146c60f16558e7eae1039ba6c937f75413ce4f9.tar.gz
gcc-3146c60f16558e7eae1039ba6c937f75413ce4f9.tar.bz2
re PR tree-optimization/87473 (ICE in create_add_on_incoming_edge, at gimple-ssa-strength-reduction.c:2344)
[gcc] 2018-10-19 Bill Schmidt <wschmidt@linux.ibm.com> PR tree-optimization/87473 * gimple-ssa-strength-reduction.c (record_phi_increments_1): For phi arguments identical to the base expression of the phi candidate, record a phi-adjust increment of zero minus the index expression of the hidden basis. (phi_incr_cost_1): For phi arguments identical to the base expression of the phi candidate, the difference to compare against the increment is zero minus the index expression of the hidden basis, and there is no potential savings from replacing the (phi) statement. (ncd_with_phi): For phi arguments identical to the base expression of the phi candidate, the difference to compare against the increment is zero minus the index expression of the hidden basis. (all_phi_incrs_profitable_1): For phi arguments identical to the base expression of the phi candidate, the increment to be checked for profitability is zero minus the index expression of the hidden basis. [gcc/testsuite] 2018-10-19 Bill Schmidt <wschmidt@linux.ibm.com> PR tree-optimization/87473 * gcc.c-torture/compile/pr87473.c: New file. From-SVN: r265319
-rw-r--r--gcc/gimple-ssa-strength-reduction.c157
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr87473.c19
2 files changed, 110 insertions, 66 deletions
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index ea81adc..e8a657e 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -2779,17 +2779,23 @@ record_phi_increments_1 (slsr_cand_t basis, gimple *phi)
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = gimple_phi_arg_def (phi, i);
+ gimple *arg_def = SSA_NAME_DEF_STMT (arg);
- if (!operand_equal_p (arg, phi_cand->base_expr, 0))
+ if (gimple_code (arg_def) == GIMPLE_PHI)
+ record_phi_increments_1 (basis, arg_def);
+ else
{
- gimple *arg_def = SSA_NAME_DEF_STMT (arg);
+ widest_int diff;
- if (gimple_code (arg_def) == GIMPLE_PHI)
- record_phi_increments_1 (basis, arg_def);
+ if (operand_equal_p (arg, phi_cand->base_expr, 0))
+ {
+ diff = -basis->index;
+ record_increment (phi_cand, diff, PHI_ADJUST);
+ }
else
{
slsr_cand_t arg_cand = base_cand_from_table (arg);
- widest_int diff = arg_cand->index - basis->index;
+ diff = arg_cand->index - basis->index;
record_increment (arg_cand, diff, PHI_ADJUST);
}
}
@@ -2864,29 +2870,43 @@ phi_incr_cost_1 (slsr_cand_t c, const widest_int &incr, gimple *phi,
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = gimple_phi_arg_def (phi, i);
+ gimple *arg_def = SSA_NAME_DEF_STMT (arg);
- if (!operand_equal_p (arg, phi_cand->base_expr, 0))
+ if (gimple_code (arg_def) == GIMPLE_PHI)
{
- gimple *arg_def = SSA_NAME_DEF_STMT (arg);
-
- if (gimple_code (arg_def) == GIMPLE_PHI)
+ int feeding_savings = 0;
+ tree feeding_var = gimple_phi_result (arg_def);
+ cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings);
+ if (uses_consumed_by_stmt (feeding_var, phi))
+ *savings += feeding_savings;
+ }
+ else
+ {
+ widest_int diff;
+ slsr_cand_t arg_cand;
+
+ /* When the PHI argument is just a pass-through to the base
+ expression of the hidden basis, the difference is zero minus
+ the index of the basis. There is no potential savings by
+ eliminating a statement in this case. */
+ if (operand_equal_p (arg, phi_cand->base_expr, 0))
{
- int feeding_savings = 0;
- tree feeding_var = gimple_phi_result (arg_def);
- cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings);
- if (uses_consumed_by_stmt (feeding_var, phi))
- *savings += feeding_savings;
+ arg_cand = (slsr_cand_t)NULL;
+ diff = -basis->index;
}
else
{
- slsr_cand_t arg_cand = base_cand_from_table (arg);
- widest_int diff = arg_cand->index - basis->index;
-
- if (incr == diff)
+ arg_cand = base_cand_from_table (arg);
+ diff = arg_cand->index - basis->index;
+ }
+
+ if (incr == diff)
+ {
+ tree basis_lhs = gimple_assign_lhs (basis->cand_stmt);
+ cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs)));
+ if (arg_cand)
{
- tree basis_lhs = gimple_assign_lhs (basis->cand_stmt);
tree lhs = gimple_assign_lhs (arg_cand->cand_stmt);
- cost += add_cost (true, TYPE_MODE (TREE_TYPE (basis_lhs)));
if (uses_consumed_by_stmt (lhs, phi))
*savings += stmt_cost (arg_cand->cand_stmt, true);
}
@@ -3228,23 +3248,26 @@ ncd_with_phi (slsr_cand_t c, const widest_int &incr, gphi *phi,
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = gimple_phi_arg_def (phi, i);
+ gimple *arg_def = SSA_NAME_DEF_STMT (arg);
- if (!operand_equal_p (arg, phi_cand->base_expr, 0))
+ if (gimple_code (arg_def) == GIMPLE_PHI)
+ ncd = ncd_with_phi (c, incr, as_a <gphi *> (arg_def), ncd, where);
+ else
{
- gimple *arg_def = SSA_NAME_DEF_STMT (arg);
+ widest_int diff;
- if (gimple_code (arg_def) == GIMPLE_PHI)
- ncd = ncd_with_phi (c, incr, as_a <gphi *> (arg_def), ncd,
- where);
- else
+ if (operand_equal_p (arg, phi_cand->base_expr, 0))
+ diff = -basis->index;
+ else
{
slsr_cand_t arg_cand = base_cand_from_table (arg);
- widest_int diff = arg_cand->index - basis->index;
- basic_block pred = gimple_phi_arg_edge (phi, i)->src;
-
- if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
- ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where);
+ diff = arg_cand->index - basis->index;
}
+
+ basic_block pred = gimple_phi_arg_edge (phi, i)->src;
+
+ if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
+ ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where);
}
}
@@ -3515,51 +3538,53 @@ all_phi_incrs_profitable_1 (slsr_cand_t c, gphi *phi, int *spread)
return false;
tree arg = gimple_phi_arg_def (phi, i);
+ gimple *arg_def = SSA_NAME_DEF_STMT (arg);
- if (!operand_equal_p (arg, phi_cand->base_expr, 0))
+ if (gimple_code (arg_def) == GIMPLE_PHI)
{
- gimple *arg_def = SSA_NAME_DEF_STMT (arg);
+ if (!all_phi_incrs_profitable_1 (c, as_a <gphi *> (arg_def), spread)
+ || *spread > MAX_SPREAD)
+ return false;
+ }
+ else
+ {
+ int j;
+ widest_int increment;
- if (gimple_code (arg_def) == GIMPLE_PHI)
- {
- if (!all_phi_incrs_profitable_1 (c, as_a <gphi *> (arg_def),
- spread)
- || *spread > MAX_SPREAD)
- return false;
- }
+ if (operand_equal_p (arg, phi_cand->base_expr, 0))
+ increment = -basis->index;
else
{
- int j;
slsr_cand_t arg_cand = base_cand_from_table (arg);
- widest_int increment = arg_cand->index - basis->index;
+ increment = arg_cand->index - basis->index;
+ }
- if (!address_arithmetic_p && wi::neg_p (increment))
- increment = -increment;
+ if (!address_arithmetic_p && wi::neg_p (increment))
+ increment = -increment;
- j = incr_vec_index (increment);
+ j = incr_vec_index (increment);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, " Conditional candidate %d, phi: ",
- c->cand_num);
- print_gimple_stmt (dump_file, phi, 0);
- fputs (" increment: ", dump_file);
- print_decs (increment, dump_file);
- if (j < 0)
- fprintf (dump_file,
- "\n Not replaced; incr_vec overflow.\n");
- else {
- fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost);
- if (profitable_increment_p (j))
- fputs (" Replacing...\n", dump_file);
- else
- fputs (" Not replaced.\n", dump_file);
- }
- }
-
- if (j < 0 || !profitable_increment_p (j))
- return false;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " Conditional candidate %d, phi: ",
+ c->cand_num);
+ print_gimple_stmt (dump_file, phi, 0);
+ fputs (" increment: ", dump_file);
+ print_decs (increment, dump_file);
+ if (j < 0)
+ fprintf (dump_file,
+ "\n Not replaced; incr_vec overflow.\n");
+ else {
+ fprintf (dump_file, "\n cost: %d\n", incr_vec[j].cost);
+ if (profitable_increment_p (j))
+ fputs (" Replacing...\n", dump_file);
+ else
+ fputs (" Not replaced.\n", dump_file);
+ }
}
+
+ if (j < 0 || !profitable_increment_p (j))
+ return false;
}
}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr87473.c b/gcc/testsuite/gcc.c-torture/compile/pr87473.c
new file mode 100644
index 0000000..0ca5e30
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr87473.c
@@ -0,0 +1,19 @@
+/* PR87473: SLSR ICE on hidden basis with |increment| > 1. */
+/* { dg-additional-options "-fno-tree-ch" } */
+
+void
+t6 (int qz, int wh)
+{
+ int jl = wh;
+
+ while (1.0 / 0 < 1)
+ {
+ qz = wh * (wh + 2);
+
+ while (wh < 1)
+ jl = 0;
+ }
+
+ while (qz < 1)
+ qz = jl * wh;
+}