Commit 963aeaad by Richard Sandiford Committed by Richard Sandiford

PR81815: Invalid conditional reduction

We weren't checking whether the phi in a conditional reduction was
used by the condition itself (which isn't a case we handle).

2017-08-11  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	PR tree-optimization/81835
	* tree-vect-loop.c (vect_is_simple_reduction): Simply checks for
	the phi SSA_NAME.  Check that the condition in a COND_EXPR does
	not depend on the phi.

gcc/testsuite/
	PR tree-optimization/81835
	* gcc.dg/vect/pr81815.c: New test.

From-SVN: r251117
parent 60e095de
2017-08-16 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/81835
* tree-vect-loop.c (vect_is_simple_reduction): Simply checks for
the phi SSA_NAME. Check that the condition in a COND_EXPR does
not depend on the phi.
2017-08-16 Alan Modra <amodra@gmail.com> 2017-08-16 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Delete * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Delete
......
2017-08-16 Richard Sandiford <richard.sandiford@linaro.org>
PR tree-optimization/81835
* gcc.dg/vect/pr81815.c: New test.
2017-08-15 Joseph Myers <joseph@codesourcery.com> 2017-08-15 Joseph Myers <joseph@codesourcery.com>
PR target/78460 PR target/78460
......
/* { dg-do run } */
int __attribute__ ((noinline, noclone))
f (int *x, int n)
{
int b = 13;
for (int i = 0; i < n; ++i)
{
int next = x[i];
b = b < 100 ? next : 200;
}
return b;
}
static int res[32];
int
main (void)
{
for (int i = 0; i < 32; ++i)
res[i] = i;
res[15] = 100;
if (f (res, 32) != 200)
__builtin_abort ();
return 0;
}
...@@ -2690,15 +2690,15 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi, ...@@ -2690,15 +2690,15 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
*double_reduc = false; *double_reduc = false;
*v_reduc_type = TREE_CODE_REDUCTION; *v_reduc_type = TREE_CODE_REDUCTION;
name = PHI_RESULT (phi); tree phi_name = PHI_RESULT (phi);
/* ??? If there are no uses of the PHI result the inner loop reduction /* ??? If there are no uses of the PHI result the inner loop reduction
won't be detected as possibly double-reduction by vectorizable_reduction won't be detected as possibly double-reduction by vectorizable_reduction
because that tries to walk the PHI arg from the preheader edge which because that tries to walk the PHI arg from the preheader edge which
can be constant. See PR60382. */ can be constant. See PR60382. */
if (has_zero_uses (name)) if (has_zero_uses (phi_name))
return NULL; return NULL;
nloop_uses = 0; nloop_uses = 0;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name) FOR_EACH_IMM_USE_FAST (use_p, imm_iter, phi_name)
{ {
gimple *use_stmt = USE_STMT (use_p); gimple *use_stmt = USE_STMT (use_p);
if (is_gimple_debug (use_stmt)) if (is_gimple_debug (use_stmt))
...@@ -2847,10 +2847,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi, ...@@ -2847,10 +2847,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
simply rewriting this into "res += -x[i]". Avoid changing simply rewriting this into "res += -x[i]". Avoid changing
gimple instruction for the first simple tests and only do this gimple instruction for the first simple tests and only do this
if we're allowed to change code at all. */ if we're allowed to change code at all. */
if (code == MINUS_EXPR if (code == MINUS_EXPR && gimple_assign_rhs2 (def_stmt) != phi_name)
&& ! ((op1 = gimple_assign_rhs2 (def_stmt))
&& TREE_CODE (op1) == SSA_NAME
&& SSA_NAME_DEF_STMT (op1) == phi))
code = PLUS_EXPR; code = PLUS_EXPR;
if (code == COND_EXPR) if (code == COND_EXPR)
...@@ -2864,6 +2861,14 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi, ...@@ -2864,6 +2861,14 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
op4 = TREE_OPERAND (op3, 1); op4 = TREE_OPERAND (op3, 1);
op3 = TREE_OPERAND (op3, 0); op3 = TREE_OPERAND (op3, 0);
} }
if (op3 == phi_name || op4 == phi_name)
{
if (dump_enabled_p ())
report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
"reduction: condition depends on previous"
" iteration: ");
return NULL;
}
op1 = gimple_assign_rhs2 (def_stmt); op1 = gimple_assign_rhs2 (def_stmt);
op2 = gimple_assign_rhs3 (def_stmt); op2 = gimple_assign_rhs3 (def_stmt);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment