https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105053
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Err, no - the reduction epilogue is simply incomplete:
<bb 46> [local count: 202926872]:
# prephitmp_27 = PHI <prephitmp_97(12)>
# vect__26.72_63 = PHI <vect__26.72_62(12)>
_64 = .REDUC_MAX (vect__26.72_63);
if (prephitmp_27 != prephitmp_35)
goto <bb 18>; [0.00%]
else
goto <bb 19>; [100.00%]
<bb 18> [count: 0]:
abort ();
and the reason is that live_out_stmts has the wrong entry and we fail to
adjust the PHI nodes. Now that's a missed optimization and should still
keep the scalar code live of course.
In fact
/* The last statement in the reduction chain produces the live-out
value. */
single_live_out_stmt[0] = SLP_TREE_SCALAR_STMTS (slp_node)[group_size - 1];
is wrong. Or rather the way to get at it is.
The following fixes this and the testcase.
@@ -5271,9 +5275,17 @@ vect_create_epilog_for_reduction (loop_vec_info
loop_vinfo,
/* All statements produce live-out values. */
live_out_stmts = SLP_TREE_SCALAR_STMTS (slp_node);
else if (slp_node)
- /* The last statement in the reduction chain produces the live-out
- value. */
- single_live_out_stmt[0] = SLP_TREE_SCALAR_STMTS (slp_node)[group_size -
1];
+ {
+ /* The last statement in the reduction chain produces the live-out
+ value. Note SLP optimization can shuffle scalar stmts to
+ optimize permutations so we have to search for the last stmt. */
+ for (k = 0; k < group_size; ++k)
+ if (!REDUC_GROUP_NEXT_ELEMENT (SLP_TREE_SCALAR_STMTS (slp_node)[k]))
+ {
+ single_live_out_stmt[0] = SLP_TREE_SCALAR_STMTS (slp_node)[k];
+ break;
+ }
+ }
unsigned vec_num;
int ncopies;