1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64
4
5; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/bmi-builtins.c
6
7;
8; AMD Intrinsics
9;
10
11define i16 @test__tzcnt_u16(i16 %a0) {
12; X86-LABEL: test__tzcnt_u16:
13; X86:       # %bb.0:
14; X86-NEXT:    tzcntw {{[0-9]+}}(%esp), %ax
15; X86-NEXT:    retl
16;
17; X64-LABEL: test__tzcnt_u16:
18; X64:       # %bb.0:
19; X64-NEXT:    tzcntw %di, %ax
20; X64-NEXT:    retq
21  %zext = zext i16 %a0 to i32
22  %cmp = icmp ne i32 %zext, 0
23  %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
24  ret i16 %cttz
25}
26
27define i32 @test__andn_u32(i32 %a0, i32 %a1) {
28; X86-LABEL: test__andn_u32:
29; X86:       # %bb.0:
30; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
31; X86-NEXT:    xorl $-1, %eax
32; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
33; X86-NEXT:    retl
34;
35; X64-LABEL: test__andn_u32:
36; X64:       # %bb.0:
37; X64-NEXT:    movl %edi, %eax
38; X64-NEXT:    xorl $-1, %eax
39; X64-NEXT:    andl %esi, %eax
40; X64-NEXT:    retq
41  %xor = xor i32 %a0, -1
42  %res = and i32 %xor, %a1
43  ret i32 %res
44}
45
46define i32 @test__bextr_u32(i32 %a0, i32 %a1) {
47; X86-LABEL: test__bextr_u32:
48; X86:       # %bb.0:
49; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
50; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
51; X86-NEXT:    retl
52;
53; X64-LABEL: test__bextr_u32:
54; X64:       # %bb.0:
55; X64-NEXT:    bextrl %esi, %edi, %eax
56; X64-NEXT:    retq
57  %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1)
58  ret i32 %res
59}
60
61define i32 @test__blsi_u32(i32 %a0) {
62; X86-LABEL: test__blsi_u32:
63; X86:       # %bb.0:
64; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
65; X86-NEXT:    xorl %eax, %eax
66; X86-NEXT:    subl %ecx, %eax
67; X86-NEXT:    andl %ecx, %eax
68; X86-NEXT:    retl
69;
70; X64-LABEL: test__blsi_u32:
71; X64:       # %bb.0:
72; X64-NEXT:    xorl %eax, %eax
73; X64-NEXT:    subl %edi, %eax
74; X64-NEXT:    andl %edi, %eax
75; X64-NEXT:    retq
76  %neg = sub i32 0, %a0
77  %res = and i32 %a0, %neg
78  ret i32 %res
79}
80
81define i32 @test__blsmsk_u32(i32 %a0) {
82; X86-LABEL: test__blsmsk_u32:
83; X86:       # %bb.0:
84; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
85; X86-NEXT:    leal -1(%ecx), %eax
86; X86-NEXT:    xorl %ecx, %eax
87; X86-NEXT:    retl
88;
89; X64-LABEL: test__blsmsk_u32:
90; X64:       # %bb.0:
91; X64-NEXT:    # kill: def $edi killed $edi def $rdi
92; X64-NEXT:    leal -1(%rdi), %eax
93; X64-NEXT:    xorl %edi, %eax
94; X64-NEXT:    retq
95  %dec = sub i32 %a0, 1
96  %res = xor i32 %a0, %dec
97  ret i32 %res
98}
99
100define i32 @test__blsr_u32(i32 %a0) {
101; X86-LABEL: test__blsr_u32:
102; X86:       # %bb.0:
103; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
104; X86-NEXT:    leal -1(%ecx), %eax
105; X86-NEXT:    andl %ecx, %eax
106; X86-NEXT:    retl
107;
108; X64-LABEL: test__blsr_u32:
109; X64:       # %bb.0:
110; X64-NEXT:    # kill: def $edi killed $edi def $rdi
111; X64-NEXT:    leal -1(%rdi), %eax
112; X64-NEXT:    andl %edi, %eax
113; X64-NEXT:    retq
114  %dec = sub i32 %a0, 1
115  %res = and i32 %a0, %dec
116  ret i32 %res
117}
118
119define i32 @test__tzcnt_u32(i32 %a0) {
120; X86-LABEL: test__tzcnt_u32:
121; X86:       # %bb.0:
122; X86-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax
123; X86-NEXT:    retl
124;
125; X64-LABEL: test__tzcnt_u32:
126; X64:       # %bb.0:
127; X64-NEXT:    tzcntl %edi, %eax
128; X64-NEXT:    retq
129  %cmp = icmp ne i32 %a0, 0
130  %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
131  ret i32 %cttz
132}
133
134;
135; Intel intrinsics
136;
137
138define i16 @test_tzcnt_u16(i16 %a0) {
139; X86-LABEL: test_tzcnt_u16:
140; X86:       # %bb.0:
141; X86-NEXT:    tzcntw {{[0-9]+}}(%esp), %ax
142; X86-NEXT:    retl
143;
144; X64-LABEL: test_tzcnt_u16:
145; X64:       # %bb.0:
146; X64-NEXT:    tzcntw %di, %ax
147; X64-NEXT:    retq
148  %zext = zext i16 %a0 to i32
149  %cmp = icmp ne i32 %zext, 0
150  %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
151  ret i16 %cttz
152}
153
154define i32 @test_andn_u32(i32 %a0, i32 %a1) {
155; X86-LABEL: test_andn_u32:
156; X86:       # %bb.0:
157; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
158; X86-NEXT:    xorl $-1, %eax
159; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
160; X86-NEXT:    retl
161;
162; X64-LABEL: test_andn_u32:
163; X64:       # %bb.0:
164; X64-NEXT:    movl %edi, %eax
165; X64-NEXT:    xorl $-1, %eax
166; X64-NEXT:    andl %esi, %eax
167; X64-NEXT:    retq
168  %xor = xor i32 %a0, -1
169  %res = and i32 %xor, %a1
170  ret i32 %res
171}
172
173define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) {
174; X86-LABEL: test_bextr_u32:
175; X86:       # %bb.0:
176; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
177; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
178; X86-NEXT:    andl $255, %ecx
179; X86-NEXT:    andl $255, %eax
180; X86-NEXT:    shll $8, %eax
181; X86-NEXT:    orl %ecx, %eax
182; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
183; X86-NEXT:    retl
184;
185; X64-LABEL: test_bextr_u32:
186; X64:       # %bb.0:
187; X64-NEXT:    andl $255, %esi
188; X64-NEXT:    andl $255, %edx
189; X64-NEXT:    shll $8, %edx
190; X64-NEXT:    orl %esi, %edx
191; X64-NEXT:    bextrl %edx, %edi, %eax
192; X64-NEXT:    retq
193  %and1 = and i32 %a1, 255
194  %and2 = and i32 %a2, 255
195  %shl = shl i32 %and2, 8
196  %or = or i32 %and1, %shl
197  %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or)
198  ret i32 %res
199}
200
201define i32 @test_blsi_u32(i32 %a0) {
202; X86-LABEL: test_blsi_u32:
203; X86:       # %bb.0:
204; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
205; X86-NEXT:    xorl %eax, %eax
206; X86-NEXT:    subl %ecx, %eax
207; X86-NEXT:    andl %ecx, %eax
208; X86-NEXT:    retl
209;
210; X64-LABEL: test_blsi_u32:
211; X64:       # %bb.0:
212; X64-NEXT:    xorl %eax, %eax
213; X64-NEXT:    subl %edi, %eax
214; X64-NEXT:    andl %edi, %eax
215; X64-NEXT:    retq
216  %neg = sub i32 0, %a0
217  %res = and i32 %a0, %neg
218  ret i32 %res
219}
220
221define i32 @test_blsmsk_u32(i32 %a0) {
222; X86-LABEL: test_blsmsk_u32:
223; X86:       # %bb.0:
224; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
225; X86-NEXT:    leal -1(%ecx), %eax
226; X86-NEXT:    xorl %ecx, %eax
227; X86-NEXT:    retl
228;
229; X64-LABEL: test_blsmsk_u32:
230; X64:       # %bb.0:
231; X64-NEXT:    # kill: def $edi killed $edi def $rdi
232; X64-NEXT:    leal -1(%rdi), %eax
233; X64-NEXT:    xorl %edi, %eax
234; X64-NEXT:    retq
235  %dec = sub i32 %a0, 1
236  %res = xor i32 %a0, %dec
237  ret i32 %res
238}
239
240define i32 @test_blsr_u32(i32 %a0) {
241; X86-LABEL: test_blsr_u32:
242; X86:       # %bb.0:
243; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
244; X86-NEXT:    leal -1(%ecx), %eax
245; X86-NEXT:    andl %ecx, %eax
246; X86-NEXT:    retl
247;
248; X64-LABEL: test_blsr_u32:
249; X64:       # %bb.0:
250; X64-NEXT:    # kill: def $edi killed $edi def $rdi
251; X64-NEXT:    leal -1(%rdi), %eax
252; X64-NEXT:    andl %edi, %eax
253; X64-NEXT:    retq
254  %dec = sub i32 %a0, 1
255  %res = and i32 %a0, %dec
256  ret i32 %res
257}
258
259define i32 @test_tzcnt_u32(i32 %a0) {
260; X86-LABEL: test_tzcnt_u32:
261; X86:       # %bb.0:
262; X86-NEXT:    tzcntl {{[0-9]+}}(%esp), %eax
263; X86-NEXT:    retl
264;
265; X64-LABEL: test_tzcnt_u32:
266; X64:       # %bb.0:
267; X64-NEXT:    tzcntl %edi, %eax
268; X64-NEXT:    retq
269  %cmp = icmp ne i32 %a0, 0
270  %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
271  ret i32 %cttz
272}
273
274declare i16 @llvm.cttz.i16(i16, i1)
275declare i32 @llvm.cttz.i32(i32, i1)
276declare i32 @llvm.x86.bmi.bextr.32(i32, i32)
277