> ... here we probably get PLUS_EXPR for MINUS_EXPR above but IIRC > for MINUS_EXPR the !as_initial case should return positive zero. > > Can you double-check?
You're referring to the canonicalization from a - CST to a + -CST so that the neutral op would need to change with it? Argh, good point. >From what I can tell the only difference for MINUS_EXPR is that we negate the reduction operand and then just continue as if it were a PLUS_EXPR (which is the right thing to do also for +-0.0?). At least I didn't observe a canonicalization and we don't call neutral_op_for_reduction in between. What we do have, though, is for the fully-masked case (you added that recently): if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) { vector_identity = build_zero_cst (vectype_out); if (!HONOR_SIGNED_ZEROS (vectype_out)) ; else { gcc_assert (!HONOR_SIGN_DEPENDENT_ROUNDING (vectype_out)); vector_identity = const_unop (NEGATE_EXPR, vectype_out, vector_identity); } } So for /* Handle MINUS by adding the negative. */ if (reduc_fn != IFN_LAST && code == MINUS_EXPR) { tree negated = make_ssa_name (vectype_out); We might need a similar assert gcc_assert (HONOR_SIGNED_ZEROS (vectype_out) && !HONOR_SIGN_DEPENDENT_ROUNDING (vectype_out));? Apart from that the only call with !as_inital is in vect_create_epilog_for_reduction. I just instrumented it with an assert (false) but i386.exp doesn't trigger it at all. Regards Robin