https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94823

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Despite the code being correct, I think it would be better to hoist this branch
out of the loop:

          if (__k == 0)
            __r2 += __s;
          else if (__k <= __s)
            __r2 += __kn + _M_v[__k - 1];
          else
            __r2 += __kn;

We can do the k=0 case first, where we know that (k+p)%n==p and (k+q)%n==q,
and we also know that for that first iteration begin[0]^begin[q]^begin[n-1] is
simply 0x8b8b8b8bu because every element has that value:

    // k == 0, every element in [begin,end) equals 0x8b8b8b8bu
      {
        uint_least32_t __r1 = 1371501266u;
        uint_least32_t __r2 = __r1 + __s;
        __begin[__p] += __r1;
        __begin[__q] += __r2;
        __begin[0] = __r2;
      }

The we can loop up to __s+1

    for (size_t __k = 1; __k <= __s; ++__k)
      ...

And then up to m

    for (size_t __k = __s + 1; __k < __m; ++__k)
      ...

This unasks the question of whether begin[-1ul % n] is the right element or has
the right value.

Reply via email to