aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2021-02-25 09:36:33 +0100
committerRichard Biener <rguenther@suse.de>2021-02-25 10:28:49 +0100
commit1193d05465acd39b6e3c7095274d8351a1e2cd44 (patch)
tree0f422ff8bf1153956f0617bed7b072e384aa3dab /gcc/tree-vect-loop.c
parent880682e7b2348d66f4089fa4af102b69eaaefbc2 (diff)
downloadgcc-1193d05465acd39b6e3c7095274d8351a1e2cd44.zip
gcc-1193d05465acd39b6e3c7095274d8351a1e2cd44.tar.gz
gcc-1193d05465acd39b6e3c7095274d8351a1e2cd44.tar.bz2
tree-optimization/99253 - fix reduction path check
This fixes an ordering problem with verifying that no intermediate computations in a reduction path are used outside of the chain. The check was disabled for value-preserving conversions at the tail but whether a stmt was a conversion or not was only computed after the first use. The following fixes this by re-ordering things accordingly. 2021-02-25 Richard Biener <rguenther@suse.de> PR tree-optimization/99253 * tree-vect-loop.c (check_reduction_path): First compute code, then verify out-of-loop uses. * gcc.dg/vect/pr99253.c: New testcase.
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r--gcc/tree-vect-loop.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 27845c0..3e973e7 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -3432,34 +3432,6 @@ pop:
fail = true;
break;
}
- /* Check there's only a single stmt the op is used on. For the
- not value-changing tail and the last stmt allow out-of-loop uses.
- ??? We could relax this and handle arbitrary live stmts by
- forcing a scalar epilogue for example. */
- imm_use_iterator imm_iter;
- gimple *op_use_stmt;
- unsigned cnt = 0;
- FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op)
- if (!is_gimple_debug (op_use_stmt)
- && (*code != ERROR_MARK
- || flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt))))
- {
- /* We want to allow x + x but not x < 1 ? x : 2. */
- if (is_gimple_assign (op_use_stmt)
- && gimple_assign_rhs_code (op_use_stmt) == COND_EXPR)
- {
- use_operand_p use_p;
- FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
- cnt++;
- }
- else
- cnt++;
- }
- if (cnt != 1)
- {
- fail = true;
- break;
- }
tree_code use_code = gimple_assign_rhs_code (use_stmt);
if (use_code == MINUS_EXPR)
{
@@ -3489,6 +3461,34 @@ pop:
fail = true;
break;
}
+ /* Check there's only a single stmt the op is used on. For the
+ not value-changing tail and the last stmt allow out-of-loop uses.
+ ??? We could relax this and handle arbitrary live stmts by
+ forcing a scalar epilogue for example. */
+ imm_use_iterator imm_iter;
+ gimple *op_use_stmt;
+ unsigned cnt = 0;
+ FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op)
+ if (!is_gimple_debug (op_use_stmt)
+ && (*code != ERROR_MARK
+ || flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt))))
+ {
+ /* We want to allow x + x but not x < 1 ? x : 2. */
+ if (is_gimple_assign (op_use_stmt)
+ && gimple_assign_rhs_code (op_use_stmt) == COND_EXPR)
+ {
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+ cnt++;
+ }
+ else
+ cnt++;
+ }
+ if (cnt != 1)
+ {
+ fail = true;
+ break;
+ }
}
return ! fail && ! neg && *code != ERROR_MARK;
}