https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116463
--- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> --- Yeah, This is because they generate different gimple sequences and thus different SLP trees. The core of the problem is there's no canonical form here, and a missing gimple simplification rule: _33 = IMAGPART_EXPR <*_3> + ((REALPART_EXPR <*_5> * IMAGPART_EXPR <*_7>) + (IMAGPART_EXPR <*_5> * REALPART_EXPR <*_7>)); vs _37 = IMAGPART_EXPR <*_3> - ((REALPART_EXPR <*_5> * -IMAGPART_EXPR <*_7>) + (IMAGPART_EXPR <*_5> * -REALPART_EXPR <*_7>)); i.e. a - ((b * -c) + (d * -e)) == a + (b * c) + (d * e) So probably in match.pd we should fold _37 into _33 which is a simpler form of the same thing and it's better on scalar as well. It would be better to finally introduce a vectorizer canonical form, for instance the real part generates: _36 = (_31 - _30) + REALPART_EXPR <*_3>; vs _32 = REALPART_EXPR <*_3> + (_26 - _27); and this already is an additional thing to check, so it would be better if slp build always puts complex parts consistently on one side of commutative operations so we don't have to swap operands to check. In any case, I have some patches in this area and can take a look when I'm back, but think the new expression should be simplified back into the old one.