Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mcpu=core-avx-i -mattr=+rdrnd | FileCheck %s --check-prefix=X86
      3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=core-avx-i -mattr=+rdrnd | FileCheck %s --check-prefix=X64
      4 
      5 declare {i16, i32} @llvm.x86.rdrand.16()
      6 declare {i32, i32} @llvm.x86.rdrand.32()
      7 
      8 define i32 @_rdrand16_step(i16* %random_val) {
      9 ; X86-LABEL: _rdrand16_step:
     10 ; X86:       # %bb.0:
     11 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     12 ; X86-NEXT:    rdrandw %ax
     13 ; X86-NEXT:    movzwl %ax, %edx
     14 ; X86-NEXT:    movl $1, %eax
     15 ; X86-NEXT:    cmovael %edx, %eax
     16 ; X86-NEXT:    movw %dx, (%ecx)
     17 ; X86-NEXT:    retl
     18 ;
     19 ; X64-LABEL: _rdrand16_step:
     20 ; X64:       # %bb.0:
     21 ; X64-NEXT:    rdrandw %ax
     22 ; X64-NEXT:    movzwl %ax, %ecx
     23 ; X64-NEXT:    movl $1, %eax
     24 ; X64-NEXT:    cmovael %ecx, %eax
     25 ; X64-NEXT:    movw %cx, (%rdi)
     26 ; X64-NEXT:    retq
     27   %call = call {i16, i32} @llvm.x86.rdrand.16()
     28   %randval = extractvalue {i16, i32} %call, 0
     29   store i16 %randval, i16* %random_val
     30   %isvalid = extractvalue {i16, i32} %call, 1
     31   ret i32 %isvalid
     32 }
     33 
     34 define i32 @_rdrand32_step(i32* %random_val) {
     35 ; X86-LABEL: _rdrand32_step:
     36 ; X86:       # %bb.0:
     37 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     38 ; X86-NEXT:    rdrandl %edx
     39 ; X86-NEXT:    movl $1, %eax
     40 ; X86-NEXT:    cmovael %edx, %eax
     41 ; X86-NEXT:    movl %edx, (%ecx)
     42 ; X86-NEXT:    retl
     43 ;
     44 ; X64-LABEL: _rdrand32_step:
     45 ; X64:       # %bb.0:
     46 ; X64-NEXT:    rdrandl %ecx
     47 ; X64-NEXT:    movl $1, %eax
     48 ; X64-NEXT:    cmovael %ecx, %eax
     49 ; X64-NEXT:    movl %ecx, (%rdi)
     50 ; X64-NEXT:    retq
     51   %call = call {i32, i32} @llvm.x86.rdrand.32()
     52   %randval = extractvalue {i32, i32} %call, 0
     53   store i32 %randval, i32* %random_val
     54   %isvalid = extractvalue {i32, i32} %call, 1
     55   ret i32 %isvalid
     56 }
     57 
     58 ; Check that MachineCSE doesn't eliminate duplicate rdrand instructions.
     59 define i32 @CSE() nounwind {
     60 ; X86-LABEL: CSE:
     61 ; X86:       # %bb.0:
     62 ; X86-NEXT:    rdrandl %ecx
     63 ; X86-NEXT:    rdrandl %eax
     64 ; X86-NEXT:    addl %ecx, %eax
     65 ; X86-NEXT:    retl
     66 ;
     67 ; X64-LABEL: CSE:
     68 ; X64:       # %bb.0:
     69 ; X64-NEXT:    rdrandl %ecx
     70 ; X64-NEXT:    rdrandl %eax
     71 ; X64-NEXT:    addl %ecx, %eax
     72 ; X64-NEXT:    retq
     73  %rand1 = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
     74  %v1 = extractvalue { i32, i32 } %rand1, 0
     75  %rand2 = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
     76  %v2 = extractvalue { i32, i32 } %rand2, 0
     77  %add = add i32 %v2, %v1
     78  ret i32 %add
     79 }
     80 
     81 ; Check that MachineLICM doesn't hoist rdrand instructions.
     82 define void @loop(i32* %p, i32 %n) nounwind {
     83 ; X86-LABEL: loop:
     84 ; X86:       # %bb.0: # %entry
     85 ; X86-NEXT:    pushl %esi
     86 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
     87 ; X86-NEXT:    testl %eax, %eax
     88 ; X86-NEXT:    je .LBB3_3
     89 ; X86-NEXT:  # %bb.1: # %while.body.preheader
     90 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
     91 ; X86-NEXT:    xorl %edx, %edx
     92 ; X86-NEXT:    .p2align 4, 0x90
     93 ; X86-NEXT:  .LBB3_2: # %while.body
     94 ; X86-NEXT:    # =>This Inner Loop Header: Depth=1
     95 ; X86-NEXT:    rdrandl %esi
     96 ; X86-NEXT:    movl %esi, (%ecx,%edx,4)
     97 ; X86-NEXT:    addl $1, %edx
     98 ; X86-NEXT:    cmpl %edx, %eax
     99 ; X86-NEXT:    jne .LBB3_2
    100 ; X86-NEXT:  .LBB3_3: # %while.end
    101 ; X86-NEXT:    popl %esi
    102 ; X86-NEXT:    retl
    103 ;
    104 ; X64-LABEL: loop:
    105 ; X64:       # %bb.0: # %entry
    106 ; X64-NEXT:    testl %esi, %esi
    107 ; X64-NEXT:    je .LBB3_3
    108 ; X64-NEXT:  # %bb.1: # %while.body.preheader
    109 ; X64-NEXT:    movl %esi, %eax
    110 ; X64-NEXT:    xorl %ecx, %ecx
    111 ; X64-NEXT:    .p2align 4, 0x90
    112 ; X64-NEXT:  .LBB3_2: # %while.body
    113 ; X64-NEXT:    # =>This Inner Loop Header: Depth=1
    114 ; X64-NEXT:    rdrandl %edx
    115 ; X64-NEXT:    movl %edx, (%rdi,%rcx,4)
    116 ; X64-NEXT:    addq $1, %rcx
    117 ; X64-NEXT:    cmpl %ecx, %eax
    118 ; X64-NEXT:    jne .LBB3_2
    119 ; X64-NEXT:  .LBB3_3: # %while.end
    120 ; X64-NEXT:    retq
    121 entry:
    122   %tobool1 = icmp eq i32 %n, 0
    123   br i1 %tobool1, label %while.end, label %while.body
    124 
    125 while.body:                                       ; preds = %entry, %while.body
    126   %p.addr.03 = phi i32* [ %incdec.ptr, %while.body ], [ %p, %entry ]
    127   %n.addr.02 = phi i32 [ %dec, %while.body ], [ %n, %entry ]
    128   %dec = add nsw i32 %n.addr.02, -1
    129   %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.03, i64 1
    130   %rand = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
    131   %v1 = extractvalue { i32, i32 } %rand, 0
    132   store i32 %v1, i32* %p.addr.03, align 4
    133   %tobool = icmp eq i32 %dec, 0
    134   br i1 %tobool, label %while.end, label %while.body
    135 
    136 while.end:                                        ; preds = %while.body, %entry
    137   ret void
    138 }
    139