https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82328
Bug ID: 82328 Summary: x86 rdrand: flags not used directly when branching on success/failure Product: gcc Version: 8.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: peter at cordes dot ca Target Milestone: --- Target: x86_64-*-*, i?86-*-* #include <immintrin.h> unsigned long long use_intrinsic(void) { unsigned long long rand; while(!_rdrand64_step(&rand)); // FIXME: limited retry in case RNG is broken return rand; } // https://godbolt.org/g/x7mUvj gcc 8.0.0 20170926 -O3 -mrdrnd movl $1, %edx .L4: rdrand %rax movq %rax, -8(%rsp) # spill to memory, really? cmovc %edx, %eax testl %eax, %eax je .L4 movq -8(%rsp), %rax ret Note that RDRAND (http://felixcloutier.com/x86/RDRAND.html) indicates failure by clearing CF *and* putting 0 in the destination register. So this code is correct (returning a valid RDRAND result even if it was zero), just much worse than clang's: .LBB1_1: rdrandq %rax jae .LBB1_1 retq