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

            Bug ID: 119322
           Summary: Different results between -O1 and -O3
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: egor.pugin at gmail dot com
  Target Milestone: ---

gmult2() is a function from Galois/Counter Mode (GCM) for AES and other
ciphers.
This code is not minimized. You can try to make it shorter.

===

using u64 = unsigned long long;

void gmult2(u64 *X, u64 *Y) {
    u64 Z[2] = {0, 0};
    u64 V[2];
    int i, j;
    V[0] = X[0];
    V[1] = X[1];
    for (i = 0; i < 2; i++) {
        auto y = Y[i];
        for (j = 0; j < 64; j++) {
            u64 mask = 0 - (y >> 63);
            Z[0] ^= V[0] & mask;
            Z[1] ^= V[1] & mask;
            auto v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
            V[1] >>= 1;
            V[1] |= V[0] << 63;
            V[0] >>= 1;
            V[0] ^= v1;
            y <<= 1;
        }
    }
    X[0] = Z[0];
    X[1] = Z[1];
}

int main() {
    __int128 a{3}, b{4};
    gmult2((u64*)&a, (u64*)&b);
    return a;
}

===

gcc gives 0 at -O1 and 3 at -O3 since 11 release. So, 11/12/13/14/15 are
affected.
gcc gives 0 at both -O1 and -O3 in version 10.
clang gives 0 at both -O1 and -O3 in version 20 (others were not tested).

godbolt for reference https://godbolt.org/z/5r1Ednf1Y

Reply via email to