https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92437
Bug ID: 92437 Summary: Unnecessary register duplication of vector constant in x86 Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: zingaburga+gcc at hotmail dot com Target Milestone: --- Consider the following code example: #include <x86intrin.h> void fn(__m128i* in, __m128i* out) { int i=0; const __m128i num = _mm_set1_epi8(99); while(i<100) { __m128i a = in[i]; __m128i b = _mm_add_epi8(a, num); if(_mm_movemask_epi8(b)) a = _mm_or_si128(a, num); if(_mm_movemask_epi8(a)) a = _mm_or_si128(a, num); out[i] = a; i++; } } The vector `num` is referenced 3 times in the loop, and GCC seems to load it into 3 separate registers, when 1 would suffice: https://godbolt.org/z/mP22ez (in this link, the `99` vector is held in xmm2, xmm3 and xmm4). This seems to be the case regardless of AVX being enabled or not. I don't really get what a possible cause for this is, but it seems that the `if` conditions are necessary to trigger this effect.