[llvm-dev] [IR] [CodeGen] Volatile causes i128 load/store to tear?

Itay Bookstein via llvm-dev llvm-dev at lists.llvm.org
Thu May 6 01:46:13 PDT 2021


Hey all,

I've encountered a codegen peculiarity on both X86-64 and PPC64LE on
top of trunk:

void foo(__uint128_t *p, __uint128_t *q) { *p = *q; }
void bar(volatile __uint128_t *p, __uint128_t *q) { *p = *q; }

On gcc trunk x86-64 -O3, both of these compile to movdqa, movaps, ret
(https://clang.godbolt.org/z/xvs8x646T).
On clang trunk x86-64 -O3, the first compiles to movaps, movaps, ret,
and the second tears into 4 mov-s
(https://clang.godbolt.org/z/zfM9MMrbM).
On clang trunk power64le, the first compiles to lxvd2x, stxvd2x, blr,
and the second tears into 2x ld, 2x std, blr
(https://clang.godbolt.org/z/7E7zG4Yfz).

I'm a bit surprised by this, since I'd expect volatile to at least
"nudge the compiler along" in the direction of not tearing, rather
than the other way around (e.g. how Linux uses volatile to implement
READ_ONCE/WRITE_ONCE).

I realize that the semantics of volatile might be a bit fuzzier when
applied to non-standard types such as __uint128_t (at the level of
clang), but as far as I can tell at the IR level these two just
compile to load/store (volatile) i128. Would this be considered a
CodeGen issue?

Thanks,
~Itay


More information about the llvm-dev mailing list