[Bug target/82328] New: x86 rdrand: flags not used directly when branching on success/failure

peter at cordes dot ca gcc-bugzilla@gcc.gnu.org
Tue Sep 26 14:56:00 GMT 2017


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


More information about the Gcc-bugs mailing list