On Sun, May 20, 2012 at 11:37 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Sun, May 20, 2012 at 11:15 AM, Jakub Jelinek <ja...@redhat.com> wrote: >> On Sun, May 20, 2012 at 10:37:13AM -0700, H.J. Lu wrote: >>> On Sun, May 20, 2012 at 10:19 AM, Jakub Jelinek <ja...@redhat.com> wrote: >>> > On Sun, May 20, 2012 at 10:04:26AM -0700, H.J. Lu wrote: >>> >> rdrand<mode>_1 must be marked with unspec_volatile since it returns >>> >> a different value every time. OK for trunk, 4.7 and 4.6? >>> > >>> > A testcase for this would be nice (runtime is not possible, since the >>> > RNG in theory could return the same value twice, but scanning assembly >>> > for a particular number of the rdrand insns would be nice). >>> > >>> >>> For >>> >>> unsigned int number = 0; >>> volatile int result = 0; >>> >>> for (register int i = 0; i < 4; ++i) { >>> result = _rdrand32_step(&number); >>> printf("%d: %d\n", result, number); >>> } >> >> Try it without the loop, unroll it by hand, see if without the patch >> the rdrand insns are still CSEd together? >> > > It doesn't: > > [hjl@gnu-ivb-1 tmp]$ cat x.c > #include <stdio.h> > > int > main(int argc, char **argv) > { > unsigned int number = 0; > volatile int result = 0; > > result = __builtin_ia32_rdrand32_step (&number); > printf("%d: %d\n", result, number); > result = __builtin_ia32_rdrand32_step (&number); > printf("%d: %d\n", result, number); > result = __builtin_ia32_rdrand32_step (&number); > printf("%d: %d\n", result, number); > result = __builtin_ia32_rdrand32_step (&number); > printf("%d: %d\n", result, number); > return 0; > } > [hjl@gnu-ivb-1 tmp]$ > /export/gnu/import/git/gcc-regression/master/187369/usr/bin/gcc > -mrdrnd -O3 -S x.c > [hjl@gnu-ivb-1 tmp]$ grep rdrand x.s > rdrand %ebx > rdrand %eax > rdrand %eax > rdrand %eax > [hjl@gnu-ivb-1 tmp]$
Try: #include <stdio.h> int main(int argc, char **argv) { unsigned int number = 0; int result0, result1, result2, result3; result0 = __builtin_ia32_rdrand32_step (&number); result1 = __builtin_ia32_rdrand32_step (&number); result2 = __builtin_ia32_rdrand32_step (&number); result3 = __builtin_ia32_rdrand32_step (&number); printf("%d: %d\n", result0, number); printf("%d: %d\n", result1, number); printf("%d: %d\n", result2, number); printf("%d: %d\n", result3, number); return 0; } Which I Know for a fact fails before the patch: pinskia@server:~$ grep rdrand t.s rdrand %edx pinskia@server:~$ Thanks, Andrew Pinski > > > -- > H.J.