https://gcc.gnu.org/g:b7b2b199b1a77eb28c0496633af7eed0a508a14c
commit r16-4595-gb7b2b199b1a77eb28c0496633af7eed0a508a14c Author: Richard Biener <[email protected]> Date: Fri Oct 24 10:13:14 2025 +0200 Fix reduction validation for associated reduction chains The code checking whether we have a single cycle and tracking the reduction chain was not transitioned to full SLP which now shows when having a SLP reduction chain built after associating the reduction operation. * tree-vect-loop.cc (vectorizable_reduction): SLP-ify reduction operation processing a bit more. * gcc.dg/vect/vect-pr122406-1.c: Adjust to expect reduction chain vectorization. * gcc.dg/vect/vect-pr122406-2.c: Likewise. Diff: --- gcc/testsuite/gcc.dg/vect/vect-pr122406-1.c | 4 ++++ gcc/testsuite/gcc.dg/vect/vect-pr122406-2.c | 4 ++++ gcc/tree-vect-loop.cc | 14 ++++++-------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr122406-1.c b/gcc/testsuite/gcc.dg/vect/vect-pr122406-1.c index a67a01c2cca2..c756ff34c52a 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-pr122406-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-pr122406-1.c @@ -7,3 +7,7 @@ int f(long l, short *sp) { us += sp[1] + sp[3]; return us; } + +/* ??? Both SVE and RVV refuse to do the { 1, 3 } permutation as two ld2 + or ld1 with odd extract plus lo/hi concat. Instead they prefer ld4. */ +/* { dg-final { scan-tree-dump "vectorizing a reduction chain" "vect" { target { { vect_extract_even_odd && vect_int } && { ! vect_variable_length } } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-pr122406-2.c b/gcc/testsuite/gcc.dg/vect/vect-pr122406-2.c index 0bce77d3f316..8b69625bb538 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-pr122406-2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-pr122406-2.c @@ -6,3 +6,7 @@ int f(long l, short *sp) { us += sp[1] + sp[3]; return us; } + +/* ??? Both SVE and RVV refuse to do the { 1, 3 } permutation as two ld2 + or ld1 with odd extract plus lo/hi concat. Instead they prefer ld4. */ +/* { dg-final { scan-tree-dump "vectorizing a reduction chain" "vect" { target { { vect_extract_even_odd && vect_int } && { ! vect_variable_length } } } } } */ diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index a98c06dd0664..50cdc2a90fa2 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7147,11 +7147,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, reduction variable. */ slp_tree *slp_op = XALLOCAVEC (slp_tree, op.num_ops); tree *vectype_op = XALLOCAVEC (tree, op.num_ops); - /* We need to skip an extra operand for COND_EXPRs with embedded - comparison. */ - unsigned opno_adjust = 0; - if (op.code == COND_EXPR && COMPARISON_CLASS_P (op.ops[0])) - opno_adjust = 1; + gcc_assert (op.code != COND_EXPR || !COMPARISON_CLASS_P (op.ops[0])); for (i = 0; i < (int) op.num_ops; i++) { /* The condition of COND_EXPR is checked in vectorizable_condition(). */ @@ -7161,7 +7157,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, stmt_vec_info def_stmt_info; enum vect_def_type dt; if (!vect_is_simple_use (loop_vinfo, slp_for_stmt_info, - i + opno_adjust, &op.ops[i], &slp_op[i], &dt, + i, &op.ops[i], &slp_op[i], &dt, &vectype_op[i], &def_stmt_info)) { if (dump_enabled_p ()) @@ -7172,12 +7168,14 @@ vectorizable_reduction (loop_vec_info loop_vinfo, /* Skip reduction operands, and for an IFN_COND_OP we might hit the reduction operand twice (once as definition, once as else). */ - if (op.ops[i] == op.ops[STMT_VINFO_REDUC_IDX (stmt_info)]) + if (SLP_TREE_CHILDREN (slp_for_stmt_info)[i] + == SLP_TREE_CHILDREN + (slp_for_stmt_info)[SLP_TREE_REDUC_IDX (slp_for_stmt_info)]) continue; /* There should be only one cycle def in the stmt, the one leading to reduc_def. */ - if (VECTORIZABLE_CYCLE_DEF (dt)) + if (SLP_TREE_CHILDREN (slp_for_stmt_info)[i]->cycle_info.id != -1) return false; if (!vectype_op[i])
