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
This commit is contained in:
William Schmidt 2018-10-19 18:28:11 +00:00
parent 273f3d4bb4
commit 3146c60f16
2 changed files with 113 additions and 69 deletions

View File

@ -2779,17 +2779,23 @@ record_phi_increments_1 (slsr_cand_t basis, gimple *phi)
for (i = 0; i < gimple_phi_num_args (phi); i++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
tree arg = gimple_phi_arg_def (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) if (operand_equal_p (arg, phi_cand->base_expr, 0))
record_phi_increments_1 (basis, arg_def); {
diff = -basis->index;
record_increment (phi_cand, diff, PHI_ADJUST);
}
else else
{ {
slsr_cand_t arg_cand = base_cand_from_table (arg); 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); 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++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
tree arg = gimple_phi_arg_def (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); int feeding_savings = 0;
tree feeding_var = gimple_phi_result (arg_def);
if (gimple_code (arg_def) == GIMPLE_PHI) 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; arg_cand = (slsr_cand_t)NULL;
tree feeding_var = gimple_phi_result (arg_def); diff = -basis->index;
cost += phi_incr_cost_1 (c, incr, arg_def, &feeding_savings);
if (uses_consumed_by_stmt (feeding_var, phi))
*savings += feeding_savings;
} }
else else
{ {
slsr_cand_t arg_cand = base_cand_from_table (arg); arg_cand = base_cand_from_table (arg);
widest_int diff = arg_cand->index - basis->index; diff = arg_cand->index - basis->index;
}
if (incr == diff)
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); 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)) if (uses_consumed_by_stmt (lhs, phi))
*savings += stmt_cost (arg_cand->cand_stmt, true); *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++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
tree arg = gimple_phi_arg_def (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) if (operand_equal_p (arg, phi_cand->base_expr, 0))
ncd = ncd_with_phi (c, incr, as_a <gphi *> (arg_def), ncd, diff = -basis->index;
where); else
else
{ {
slsr_cand_t arg_cand = base_cand_from_table (arg); slsr_cand_t arg_cand = base_cand_from_table (arg);
widest_int diff = arg_cand->index - basis->index; 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);
} }
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; return false;
tree arg = gimple_phi_arg_def (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 (!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 (operand_equal_p (arg, phi_cand->base_expr, 0))
{ increment = -basis->index;
if (!all_phi_incrs_profitable_1 (c, as_a <gphi *> (arg_def),
spread)
|| *spread > MAX_SPREAD)
return false;
}
else else
{ {
int j;
slsr_cand_t arg_cand = base_cand_from_table (arg); 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;
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 (!address_arithmetic_p && wi::neg_p (increment))
increment = -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;
} }
} }

View File

@ -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;
}