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.

Reply via email to