Hi! I just ran across a bug in the nvc and nvc++ compilers. I’ve seen in some older C code an idiom where the old gcc intrinsic __sync_val_compare_and_swap is used to perform an atomic store and the result is discarded. It’s an odd idiom, but technically valid. Unfortunately if optimizations are on with the latest nvc and nvc++ (25.3), the compiler optimizes out the call entirely. The optimizer seems to think that __sync_val_compare_and_swap is a pure function or something similar. With C11 this is easily rewritten using atomic_store_explicit, and that is a viable workaround for me in this case, but I wanted to forward the error report because it may not be easy to track down the cause in other cases where this may show up.
Here’s a minimal example to reproduce the issue:
static volatile int val;
int main() {
(void)__sync_val_compare_and_swap(&val, 0, 1);
}
Looking at the generated assembly, with -O1 set, the intrinsic is optimized out, but without optimization the correct code is generated. If you don’t want to look at the assembly directly you can also just read the value after the intrinsic and confirm whether the store actually happened.
Here are examples showing this behavior on the godbolt compiler explorer:
unoptimized (correct): Compiler Explorer
optimized (incorrect): Compiler Explorer
This bug is not present in earlier versions of nvc and nvc++, just 25.3.