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;