• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5declare {i16, i32} @llvm.x86.rdrand.16()
6declare {i32, i32} @llvm.x86.rdrand.32()
7
8define 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
34define 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.
59define 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.
82define 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
121entry:
122  %tobool1 = icmp eq i32 %n, 0
123  br i1 %tobool1, label %while.end, label %while.body
124
125while.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
136while.end:                                        ; preds = %while.body, %entry
137  ret void
138}
139