pmeerw's blog
Below code should output 00000000fc52127e31b9685a7fc3bdda302494879630be65bffa2dc38b680ac9 with -O2; clang-20, clang-21, clang-22 produce different output on x64 (see Issue 215690).
// x.cpp
#include <cstdint>
#include <cstdio>
#include <cstdlib>
__attribute__((noinline)) void bar(uint8_t *b, size_t size)
{
const uint32_t k = 0xc93e5407;
for (uint32_t i = 0; i < size; i++)
{
b[i] ^= ((uint8_t*)&k)[i % sizeof(uint32_t)];
}
}
int main() {
uint8_t y[] = "\x07\x54\x3e\xc9\xfb\x06\x2c\xb7\x36\xed\x56\x93\x78\x97\x83\x13\x37\x70\xaa\x4e\x91\x64\x80\xac\xb8\xae\x13\x0a\x8c\x3c\x34";
const size_t n = sizeof(y);
bar(y, n);
for (size_t i = 0; i < n; i++) printf("%02x", y[i]); puts("");
}
Just compile with clang++-22 -O2 x.cpp on x64; clang 19.1.7 (20ubuntu4) is OK, clang 22.1.2 (1ubuntu1) is NG.
-opt-bisect-limit indicates that loop-vectorize breaks things (see Using -opt-bisect-limit): compile with
clang++-22 -O2 -mllvm -opt-bisect-limit=87 -c x.cpp to see/bisect which optimization step breaks the output.
The __attribute__((noinline)) is helpful to actually reproduce the issue in a single file; otherwise different compilation units do the thing.
posted at: 01:03 | path: /programming | permanent link