diff options
author | Richard Biener <rguenther@suse.de> | 2021-02-25 09:36:33 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-02-25 10:28:49 +0100 |
commit | 1193d05465acd39b6e3c7095274d8351a1e2cd44 (patch) | |
tree | 0f422ff8bf1153956f0617bed7b072e384aa3dab /gcc/tree-vect-loop.c | |
parent | 880682e7b2348d66f4089fa4af102b69eaaefbc2 (diff) | |
download | gcc-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.c | 56 |
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; } |