https://gcc.gnu.org/g:7ea81ee5e57e4a5d6a6975c4bffde59751aa87f2
commit r16-4730-g7ea81ee5e57e4a5d6a6975c4bffde59751aa87f2 Author: Richard Biener <[email protected]> Date: Thu Oct 30 10:38:13 2025 +0100 Swap operands during SLP discovery for mismatching STMT_VINFO_REDUC_IDX When we are unlucky operand canonicalization can end up presenting us with different order, making a possible SLP reduction group not match up. The following allows swapping operands in this case. * tree-vect-slp.cc (vect_get_operand_map): Handle commutative operands when swapping is requested. (vect_build_slp_tree_1): Allow STMT_VINFO_REDUC_IDX differences when operand swapping makes them match and request swapping. (vect_build_slp_instance): Indicate we have successfully discovered a SLP reduction group. * gcc.dg/vect/slp-reduc-13.c: New testcase. Co-authored-by: Eric Botcazou <[email protected]> Diff: --- gcc/testsuite/gcc.dg/vect/slp-reduc-13.c | 66 ++++++++++++++++++++++++++++++++ gcc/tree-vect-slp.cc | 23 ++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c new file mode 100644 index 000000000000..00e91fc6251b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c @@ -0,0 +1,66 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-fgimple" } */ + +int q[2]; + +void __GIMPLE (ssa,guessed_local(16535624),startwith("loop")) +foo (int * r) +{ + int i; + int sum2; + int sum1; + int _1; + long unsigned int _2; + long unsigned int _3; + int * _4; + int _24; + __SIZETYPE__ _6; + __SIZETYPE__ _7; + int * _8; + int _9; + int _13; + unsigned int _30; + unsigned int _31; + + __BB(2,guessed_local(16535624)): + goto __BB3(precise(134217728)); + + __BB(3,loop_header(1),guessed_local(1057206200)): + sum1_5 = __PHI (__BB5: sum1_18, __BB2: 0); + sum2_26 = __PHI (__BB5: sum2_19, __BB2: 0); + i_28 = __PHI (__BB5: i_20, __BB2: 0); + _31 = __PHI (__BB5: _30, __BB2: 64u); + _1 = i_28 * 2; + _2 = (long unsigned int) _1; + _3 = _2 * 4ul; + _4 = r_17(D) + _3; + _24 = __MEM <int> (_4); + /* Deliberately have swapped operands here */ + sum1_18 = sum1_5 + _24; + _13 = _1 + 1; + _6 = (__SIZETYPE__) _13; + _7 = _6 * 4ul; + _8 = r_17(D) + _7; + _9 = __MEM <int> (_8); + /* versus here. */ + sum2_19 = _9 + sum2_26; + i_20 = i_28 + 1; + _30 = _31 - 1u; + if (_30 != 0u) + goto __BB5(guessed(132118446)); + else + goto __BB4(guessed(2099282)); + + __BB(5,guessed_local(1040670576)): + goto __BB3(precise(134217728)); + + __BB(4,guessed_local(16535624)): + sum1_33 = __PHI (__BB3: sum1_18); + sum2_32 = __PHI (__BB3: sum2_19); + q[0] = sum1_33; + q[1] = sum2_32; + return; +} + +/* { dg-final { scan-tree-dump "SLP discovery of size 2 reduction group succeeded" "vect" } } */ diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index f64f874abfff..aa6c3e2e041d 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -558,7 +558,8 @@ vect_get_operand_map (const gimple *stmt, bool gather_scatter_p = false, if (gimple_assign_rhs_code (assign) == COND_EXPR && COMPARISON_CLASS_P (gimple_assign_rhs1 (assign))) gcc_unreachable (); - if (TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison + if ((TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison + || commutative_tree_code (gimple_assign_rhs_code (assign))) && swap) return op1_op0_map; if (gather_scatter_p) @@ -1352,7 +1353,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, uniform but only that of the first stmt matters. */ && !(first_reduc_idx != -1 && STMT_VINFO_REDUC_IDX (stmt_info) != -1 - && REDUC_GROUP_FIRST_ELEMENT (stmt_info))) + && REDUC_GROUP_FIRST_ELEMENT (stmt_info)) + && !(first_reduc_idx != -1 + && STMT_VINFO_REDUC_IDX (stmt_info) != -1 + && rhs_code.is_tree_code () + && commutative_tree_code (tree_code (rhs_code)) + && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info))) { if (dump_enabled_p ()) { @@ -1617,6 +1623,15 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap, && (swap_tree_comparison ((tree_code)first_stmt_code) == (tree_code)rhs_code)) swap[i] = 1; + + if (i != 0 + && first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info) + && first_reduc_idx != -1 + && STMT_VINFO_REDUC_IDX (stmt_info) != -1 + && rhs_code.is_tree_code () + && commutative_tree_code (tree_code (rhs_code)) + && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info)) + swap[i] = 1; } matches[i] = true; @@ -4164,6 +4179,10 @@ vect_build_slp_instance (vec_info *vinfo, if (dump_enabled_p ()) { + if (kind == slp_inst_kind_reduc_group) + dump_printf_loc (MSG_NOTE, vect_location, + "SLP discovery of size %d reduction group " + "succeeded\n", group_size); dump_printf_loc (MSG_NOTE, vect_location, "Final SLP tree for instance %p:\n", (void *) new_instance);
