https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91481
Bug ID: 91481 Summary: POWER9 "DARN" RNG intrinsic produces repeated output Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: lloyd at randombit dot net Target Milestone: --- The POWER9 ISA includes a hardware random number generator "DARN" which is similar to x86 RDRAND/RDSEED. Using the GCC intrinsics and *any optimization level* then `__builtin_darn()` and `__builtin_darn_raw()` produce repeated output: $ cat darn.c #include <stdio.h> #include <stdint.h> int main() { uint64_t darn[32]; for(size_t i = 0; i != 32; ++i) darn[i] = __builtin_darn(); // or __builtin_darn_raw() for(size_t i = 0; i != 32; ++i) printf("%016lX\n", darn[i]); } $ $HOME/opt/bin/powerpc64le-unknown-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=/home/lloyd/opt/bin/powerpc64le-unknown-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/lloyd/opt/libexec/gcc/powerpc64le-unknown-linux-gnu/9.2.0/lto-wrapper Target: powerpc64le-unknown-linux-gnu Configured with: ../gcc-9.2.0/configure --prefix=/home/lloyd/opt --enable-languages=c,c++ Thread model: posix gcc version 9.2.0 (GCC) $ $HOME/opt/bin/powerpc64le-unknown-linux-gnu-gcc -mcpu=power9 -O -m64 darn.c -o darn $ ./darn 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 32A7727F89101CF3 ... The binary produces a unique value each time it is executed, but the same value repeats. If no optimization is used, then different values are produced. Since these instructions are supposed to be used to seed cryptographic random number generators, this is quite bad. I don't know PPC asm but my read of the generated code when optimizations are enabled is that `darn` is invoked just once and then the value is placed repeatedly into the array - maybe GCC has not been taught that this instruction is volatile and produces a different output each time it is used? Originally observed with "gcc version 8.3.1 20190304 (Advance-Toolchain-at12.0) [revision 269374] (GCC)" on gcc135, same behavior with stock GCC 9.2.0. I don't think there is an issue with the hardware; if using inline asm instead of the intrinsics, everything seems to work as expected.