[gcc r13-9681] tree-optimization/119057 - bogus double reduction detection
Richard Biener
rguenth@gcc.gnu.org
Mon May 26 10:37:10 GMT 2025
https://gcc.gnu.org/g:876083c5e7a8863ce87d8da9e3a43927aee7e02b
commit r13-9681-g876083c5e7a8863ce87d8da9e3a43927aee7e02b
Author: Richard Biener <rguenther@suse.de>
Date: Mon Mar 3 13:21:53 2025 +0100
tree-optimization/119057 - bogus double reduction detection
We are detecting a cycle as double reduction where the inner loop
cycle has extra out-of-loop uses. This clashes at least with
assumptions from the SLP discovery code which says the cycle
isn't reachable from another SLP instance. It also was not intended
to support this case, in fact with GCC 14 we seem to generate wrong
code here.
PR tree-optimization/119057
* tree-vect-loop.cc (check_reduction_path): Add argument
specifying whether we're analyzing the inner loop of a
double reduction. Do not allow extra uses outside of the
double reduction cycle in this case.
(vect_is_simple_reduction): Adjust.
* gcc.dg/vect/pr119057.c: New testcase.
(cherry picked from commit 758de6263dfc7ba8701965fa468691ac23cb7eb5)
Diff:
---
gcc/testsuite/gcc.dg/vect/pr119057.c | 19 +++++++++++++++++++
gcc/tree-vect-loop.cc | 12 +++++++-----
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/gcc/testsuite/gcc.dg/vect/pr119057.c b/gcc/testsuite/gcc.dg/vect/pr119057.c
new file mode 100644
index 000000000000..582bb8ff86c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119057.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-vrp -fno-tree-forwprop" } */
+
+int a, b, c, d;
+unsigned e;
+static void f(void)
+{
+ unsigned h;
+ for (d = 0; d < 2; d++)
+ b |= e;
+ h = b;
+ c |= h;
+}
+int main()
+{
+ for (; a; a++)
+ f();
+ return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 7a319e7f98ef..9672dc7f8a35 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -3552,7 +3552,8 @@ needs_fold_left_reduction_p (tree type, code_helper code)
static bool
check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi,
tree loop_arg, code_helper *code,
- vec<std::pair<ssa_op_iter, use_operand_p> > &path)
+ vec<std::pair<ssa_op_iter, use_operand_p> > &path,
+ bool inner_loop_of_double_reduc)
{
auto_bitmap visited;
tree lookfor = PHI_RESULT (phi);
@@ -3682,7 +3683,8 @@ pop:
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.
+ not value-changing tail and the last stmt allow out-of-loop uses,
+ but not when this is the inner loop of a double reduction.
??? We could relax this and handle arbitrary live stmts by
forcing a scalar epilogue for example. */
imm_use_iterator imm_iter;
@@ -3691,7 +3693,7 @@ pop:
unsigned cnt = 0;
FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op.ops[opi])
if (!is_gimple_debug (op_use_stmt)
- && (*code != ERROR_MARK
+ && ((*code != ERROR_MARK || inner_loop_of_double_reduc)
|| flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt))))
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
cnt++;
@@ -3710,7 +3712,7 @@ check_reduction_path (dump_user_location_t loc, loop_p loop, gphi *phi,
{
auto_vec<std::pair<ssa_op_iter, use_operand_p> > path;
code_helper code_;
- return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path)
+ return (check_reduction_path (loc, loop, phi, loop_arg, &code_, path, false)
&& code_ == code);
}
@@ -3914,7 +3916,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
auto_vec<std::pair<ssa_op_iter, use_operand_p> > path;
code_helper code;
if (check_reduction_path (vect_location, loop, phi, latch_def, &code,
- path))
+ path, inner_loop_of_double_reduc))
{
STMT_VINFO_REDUC_CODE (phi_info) = code;
if (code == COND_EXPR && !nested_in_vect_loop)
More information about the Gcc-cvs
mailing list