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 ; RUN: llc < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi,+egpr --show-mc-encoding | FileCheck %s --check-prefix=EGPR
5 ; NOTE: This should use IR equivalent to what is generated by clang/test/CodeGen/bmi-builtins.c
11 define i16 @test__tzcnt_u16(i16 %a0) {
12 ; X86-LABEL: test__tzcnt_u16:
14 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
15 ; X86-NEXT: orl $65536, %eax # imm = 0x10000
16 ; X86-NEXT: tzcntl %eax, %eax
17 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
20 ; X64-LABEL: test__tzcnt_u16:
22 ; X64-NEXT: orl $65536, %edi # imm = 0x10000
23 ; X64-NEXT: tzcntl %edi, %eax
24 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
27 ; EGPR-LABEL: test__tzcnt_u16:
29 ; EGPR-NEXT: orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00]
30 ; EGPR-NEXT: # imm = 0x10000
31 ; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
32 ; EGPR-NEXT: # kill: def $ax killed $ax killed $eax
33 ; EGPR-NEXT: retq # encoding: [0xc3]
34 %zext = zext i16 %a0 to i32
35 %cmp = icmp ne i32 %zext, 0
36 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
40 define i32 @test__andn_u32(i32 %a0, i32 %a1) {
41 ; X86-LABEL: test__andn_u32:
43 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
44 ; X86-NEXT: xorl $-1, %eax
45 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
48 ; X64-LABEL: test__andn_u32:
50 ; X64-NEXT: movl %edi, %eax
51 ; X64-NEXT: xorl $-1, %eax
52 ; X64-NEXT: andl %esi, %eax
55 ; EGPR-LABEL: test__andn_u32:
57 ; EGPR-NEXT: movl %edi, %eax # encoding: [0x89,0xf8]
58 ; EGPR-NEXT: xorl $-1, %eax # encoding: [0x83,0xf0,0xff]
59 ; EGPR-NEXT: andl %esi, %eax # encoding: [0x21,0xf0]
60 ; EGPR-NEXT: retq # encoding: [0xc3]
61 %xor = xor i32 %a0, -1
62 %res = and i32 %xor, %a1
66 define i32 @test__bextr_u32(i32 %a0, i32 %a1) {
67 ; X86-LABEL: test__bextr_u32:
69 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
70 ; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
73 ; X64-LABEL: test__bextr_u32:
75 ; X64-NEXT: bextrl %esi, %edi, %eax
78 ; EGPR-LABEL: test__bextr_u32:
80 ; EGPR-NEXT: bextrl %esi, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x48,0xf7,0xc7]
81 ; EGPR-NEXT: retq # encoding: [0xc3]
82 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1)
86 define i32 @test__blsi_u32(i32 %a0) {
87 ; X86-LABEL: test__blsi_u32:
89 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
90 ; X86-NEXT: xorl %eax, %eax
91 ; X86-NEXT: subl %ecx, %eax
92 ; X86-NEXT: andl %ecx, %eax
95 ; X64-LABEL: test__blsi_u32:
97 ; X64-NEXT: xorl %eax, %eax
98 ; X64-NEXT: subl %edi, %eax
99 ; X64-NEXT: andl %edi, %eax
102 ; EGPR-LABEL: test__blsi_u32:
104 ; EGPR-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
105 ; EGPR-NEXT: subl %edi, %eax # encoding: [0x29,0xf8]
106 ; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8]
107 ; EGPR-NEXT: retq # encoding: [0xc3]
108 %neg = sub i32 0, %a0
109 %res = and i32 %a0, %neg
113 define i32 @test__blsmsk_u32(i32 %a0) {
114 ; X86-LABEL: test__blsmsk_u32:
116 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
117 ; X86-NEXT: leal -1(%ecx), %eax
118 ; X86-NEXT: xorl %ecx, %eax
121 ; X64-LABEL: test__blsmsk_u32:
123 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
124 ; X64-NEXT: leal -1(%rdi), %eax
125 ; X64-NEXT: xorl %edi, %eax
128 ; EGPR-LABEL: test__blsmsk_u32:
130 ; EGPR-NEXT: # kill: def $edi killed $edi def $rdi
131 ; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
132 ; EGPR-NEXT: xorl %edi, %eax # encoding: [0x31,0xf8]
133 ; EGPR-NEXT: retq # encoding: [0xc3]
134 %dec = sub i32 %a0, 1
135 %res = xor i32 %a0, %dec
139 define i32 @test__blsr_u32(i32 %a0) {
140 ; X86-LABEL: test__blsr_u32:
142 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
143 ; X86-NEXT: leal -1(%ecx), %eax
144 ; X86-NEXT: andl %ecx, %eax
147 ; X64-LABEL: test__blsr_u32:
149 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
150 ; X64-NEXT: leal -1(%rdi), %eax
151 ; X64-NEXT: andl %edi, %eax
154 ; EGPR-LABEL: test__blsr_u32:
156 ; EGPR-NEXT: # kill: def $edi killed $edi def $rdi
157 ; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
158 ; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8]
159 ; EGPR-NEXT: retq # encoding: [0xc3]
160 %dec = sub i32 %a0, 1
161 %res = and i32 %a0, %dec
165 define i32 @test__tzcnt_u32(i32 %a0) {
166 ; X86-LABEL: test__tzcnt_u32:
168 ; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
171 ; X64-LABEL: test__tzcnt_u32:
173 ; X64-NEXT: tzcntl %edi, %eax
176 ; EGPR-LABEL: test__tzcnt_u32:
178 ; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
179 ; EGPR-NEXT: retq # encoding: [0xc3]
180 %cmp = icmp ne i32 %a0, 0
181 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
189 define i16 @test_tzcnt_u16(i16 %a0) {
190 ; X86-LABEL: test_tzcnt_u16:
192 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
193 ; X86-NEXT: orl $65536, %eax # imm = 0x10000
194 ; X86-NEXT: tzcntl %eax, %eax
195 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
198 ; X64-LABEL: test_tzcnt_u16:
200 ; X64-NEXT: orl $65536, %edi # imm = 0x10000
201 ; X64-NEXT: tzcntl %edi, %eax
202 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
205 ; EGPR-LABEL: test_tzcnt_u16:
207 ; EGPR-NEXT: orl $65536, %edi # encoding: [0x81,0xcf,0x00,0x00,0x01,0x00]
208 ; EGPR-NEXT: # imm = 0x10000
209 ; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
210 ; EGPR-NEXT: # kill: def $ax killed $ax killed $eax
211 ; EGPR-NEXT: retq # encoding: [0xc3]
212 %zext = zext i16 %a0 to i32
213 %cmp = icmp ne i32 %zext, 0
214 %cttz = call i16 @llvm.cttz.i16(i16 %a0, i1 false)
218 define i32 @test_andn_u32(i32 %a0, i32 %a1) {
219 ; X86-LABEL: test_andn_u32:
221 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
222 ; X86-NEXT: xorl $-1, %eax
223 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
226 ; X64-LABEL: test_andn_u32:
228 ; X64-NEXT: movl %edi, %eax
229 ; X64-NEXT: xorl $-1, %eax
230 ; X64-NEXT: andl %esi, %eax
233 ; EGPR-LABEL: test_andn_u32:
235 ; EGPR-NEXT: movl %edi, %eax # encoding: [0x89,0xf8]
236 ; EGPR-NEXT: xorl $-1, %eax # encoding: [0x83,0xf0,0xff]
237 ; EGPR-NEXT: andl %esi, %eax # encoding: [0x21,0xf0]
238 ; EGPR-NEXT: retq # encoding: [0xc3]
239 %xor = xor i32 %a0, -1
240 %res = and i32 %xor, %a1
244 define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) {
245 ; X86-LABEL: test_bextr_u32:
247 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
248 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
249 ; X86-NEXT: andl $255, %ecx
250 ; X86-NEXT: andl $255, %eax
251 ; X86-NEXT: shll $8, %eax
252 ; X86-NEXT: orl %ecx, %eax
253 ; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
256 ; X64-LABEL: test_bextr_u32:
258 ; X64-NEXT: andl $255, %esi
259 ; X64-NEXT: andl $255, %edx
260 ; X64-NEXT: shll $8, %edx
261 ; X64-NEXT: orl %esi, %edx
262 ; X64-NEXT: bextrl %edx, %edi, %eax
265 ; EGPR-LABEL: test_bextr_u32:
267 ; EGPR-NEXT: andl $255, %esi # encoding: [0x81,0xe6,0xff,0x00,0x00,0x00]
268 ; EGPR-NEXT: andl $255, %edx # encoding: [0x81,0xe2,0xff,0x00,0x00,0x00]
269 ; EGPR-NEXT: shll $8, %edx # encoding: [0xc1,0xe2,0x08]
270 ; EGPR-NEXT: orl %esi, %edx # encoding: [0x09,0xf2]
271 ; EGPR-NEXT: bextrl %edx, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x68,0xf7,0xc7]
272 ; EGPR-NEXT: retq # encoding: [0xc3]
273 %and1 = and i32 %a1, 255
274 %and2 = and i32 %a2, 255
275 %shl = shl i32 %and2, 8
276 %or = or i32 %and1, %shl
277 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %or)
281 define i32 @test_blsi_u32(i32 %a0) {
282 ; X86-LABEL: test_blsi_u32:
284 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
285 ; X86-NEXT: xorl %eax, %eax
286 ; X86-NEXT: subl %ecx, %eax
287 ; X86-NEXT: andl %ecx, %eax
290 ; X64-LABEL: test_blsi_u32:
292 ; X64-NEXT: xorl %eax, %eax
293 ; X64-NEXT: subl %edi, %eax
294 ; X64-NEXT: andl %edi, %eax
297 ; EGPR-LABEL: test_blsi_u32:
299 ; EGPR-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
300 ; EGPR-NEXT: subl %edi, %eax # encoding: [0x29,0xf8]
301 ; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8]
302 ; EGPR-NEXT: retq # encoding: [0xc3]
303 %neg = sub i32 0, %a0
304 %res = and i32 %a0, %neg
308 define i32 @test_blsmsk_u32(i32 %a0) {
309 ; X86-LABEL: test_blsmsk_u32:
311 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
312 ; X86-NEXT: leal -1(%ecx), %eax
313 ; X86-NEXT: xorl %ecx, %eax
316 ; X64-LABEL: test_blsmsk_u32:
318 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
319 ; X64-NEXT: leal -1(%rdi), %eax
320 ; X64-NEXT: xorl %edi, %eax
323 ; EGPR-LABEL: test_blsmsk_u32:
325 ; EGPR-NEXT: # kill: def $edi killed $edi def $rdi
326 ; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
327 ; EGPR-NEXT: xorl %edi, %eax # encoding: [0x31,0xf8]
328 ; EGPR-NEXT: retq # encoding: [0xc3]
329 %dec = sub i32 %a0, 1
330 %res = xor i32 %a0, %dec
334 define i32 @test_blsr_u32(i32 %a0) {
335 ; X86-LABEL: test_blsr_u32:
337 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
338 ; X86-NEXT: leal -1(%ecx), %eax
339 ; X86-NEXT: andl %ecx, %eax
342 ; X64-LABEL: test_blsr_u32:
344 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
345 ; X64-NEXT: leal -1(%rdi), %eax
346 ; X64-NEXT: andl %edi, %eax
349 ; EGPR-LABEL: test_blsr_u32:
351 ; EGPR-NEXT: # kill: def $edi killed $edi def $rdi
352 ; EGPR-NEXT: leal -1(%rdi), %eax # encoding: [0x8d,0x47,0xff]
353 ; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8]
354 ; EGPR-NEXT: retq # encoding: [0xc3]
355 %dec = sub i32 %a0, 1
356 %res = and i32 %a0, %dec
360 define i32 @test_tzcnt_u32(i32 %a0) {
361 ; X86-LABEL: test_tzcnt_u32:
363 ; X86-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
366 ; X64-LABEL: test_tzcnt_u32:
368 ; X64-NEXT: tzcntl %edi, %eax
371 ; EGPR-LABEL: test_tzcnt_u32:
373 ; EGPR-NEXT: tzcntl %edi, %eax # encoding: [0xf3,0x0f,0xbc,0xc7]
374 ; EGPR-NEXT: retq # encoding: [0xc3]
375 %cmp = icmp ne i32 %a0, 0
376 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
380 declare i16 @llvm.cttz.i16(i16, i1)
381 declare i32 @llvm.cttz.i32(i32, i1)
382 declare i32 @llvm.x86.bmi.bextr.32(i32, i32)