https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92618
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That optimization seems to ignore completely the involved types. Consider following testcase instead, where in foo the addition is performed originally in unsigned long long type and in baz in double type, that reassoc change happily performs the addition in long long type in both cases. #if __SIZEOF_LONG_LONG__ == __SIZEOF_DOUBLE__ typedef long long __m128i __attribute__((__may_alias__, __vector_size__(2 * sizeof (long long)))); unsigned long long b[4]; __m128i bar (void); double e[4]; void foo (unsigned long long *x) { __m128i c = bar (); __m128i d = bar (); *(__m128i *) &b[0] = c; *(__m128i *) &b[2] = d; *x = b[0] + b[1] + b[2] + b[3]; } void baz (double *x) { __m128i c = bar (); __m128i d = bar (); *(__m128i *) &e[0] = c; *(__m128i *) &e[2] = d; *x = e[0] + e[1] + e[2] + e[3]; } #endif