1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -fast-isel-sink-local-values < %s -fast-isel -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X32
3 ; RUN: llc -fast-isel-sink-local-values < %s -fast-isel -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64
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 ; X32-LABEL: test__tzcnt_u16:
14 ; X32-NEXT: tzcntw {{[0-9]+}}(%esp), %ax
17 ; X64-LABEL: test__tzcnt_u16:
19 ; X64-NEXT: tzcntw %di, %ax
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)
27 define i32 @test__andn_u32(i32 %a0, i32 %a1) {
28 ; X32-LABEL: test__andn_u32:
30 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
31 ; X32-NEXT: xorl $-1, %eax
32 ; X32-NEXT: andl {{[0-9]+}}(%esp), %eax
35 ; X64-LABEL: test__andn_u32:
37 ; X64-NEXT: movl %edi, %eax
38 ; X64-NEXT: xorl $-1, %eax
39 ; X64-NEXT: andl %esi, %eax
41 %xor = xor i32 %a0, -1
42 %res = and i32 %xor, %a1
46 define i32 @test__bextr_u32(i32 %a0, i32 %a1) {
47 ; X32-LABEL: test__bextr_u32:
49 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
50 ; X32-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
53 ; X64-LABEL: test__bextr_u32:
55 ; X64-NEXT: bextrl %esi, %edi, %eax
57 %res = call i32 @llvm.x86.bmi.bextr.32(i32 %a0, i32 %a1)
61 define i32 @test__blsi_u32(i32 %a0) {
62 ; X32-LABEL: test__blsi_u32:
64 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
65 ; X32-NEXT: xorl %eax, %eax
66 ; X32-NEXT: subl %ecx, %eax
67 ; X32-NEXT: andl %ecx, %eax
70 ; X64-LABEL: test__blsi_u32:
72 ; X64-NEXT: xorl %eax, %eax
73 ; X64-NEXT: subl %edi, %eax
74 ; X64-NEXT: andl %edi, %eax
77 %res = and i32 %a0, %neg
81 define i32 @test__blsmsk_u32(i32 %a0) {
82 ; X32-LABEL: test__blsmsk_u32:
84 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
85 ; X32-NEXT: leal -1(%ecx), %eax
86 ; X32-NEXT: xorl %ecx, %eax
89 ; X64-LABEL: test__blsmsk_u32:
91 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
92 ; X64-NEXT: leal -1(%rdi), %eax
93 ; X64-NEXT: xorl %edi, %eax
96 %res = xor i32 %a0, %dec
100 define i32 @test__blsr_u32(i32 %a0) {
101 ; X32-LABEL: test__blsr_u32:
103 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
104 ; X32-NEXT: leal -1(%ecx), %eax
105 ; X32-NEXT: andl %ecx, %eax
108 ; X64-LABEL: test__blsr_u32:
110 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
111 ; X64-NEXT: leal -1(%rdi), %eax
112 ; X64-NEXT: andl %edi, %eax
114 %dec = sub i32 %a0, 1
115 %res = and i32 %a0, %dec
119 define i32 @test__tzcnt_u32(i32 %a0) {
120 ; X32-LABEL: test__tzcnt_u32:
122 ; X32-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
125 ; X64-LABEL: test__tzcnt_u32:
127 ; X64-NEXT: tzcntl %edi, %eax
129 %cmp = icmp ne i32 %a0, 0
130 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
138 define i16 @test_tzcnt_u16(i16 %a0) {
139 ; X32-LABEL: test_tzcnt_u16:
141 ; X32-NEXT: tzcntw {{[0-9]+}}(%esp), %ax
144 ; X64-LABEL: test_tzcnt_u16:
146 ; X64-NEXT: tzcntw %di, %ax
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)
154 define i32 @test_andn_u32(i32 %a0, i32 %a1) {
155 ; X32-LABEL: test_andn_u32:
157 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
158 ; X32-NEXT: xorl $-1, %eax
159 ; X32-NEXT: andl {{[0-9]+}}(%esp), %eax
162 ; X64-LABEL: test_andn_u32:
164 ; X64-NEXT: movl %edi, %eax
165 ; X64-NEXT: xorl $-1, %eax
166 ; X64-NEXT: andl %esi, %eax
168 %xor = xor i32 %a0, -1
169 %res = and i32 %xor, %a1
173 define i32 @test_bextr_u32(i32 %a0, i32 %a1, i32 %a2) {
174 ; X32-LABEL: test_bextr_u32:
176 ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
177 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
178 ; X32-NEXT: andl $255, %ecx
179 ; X32-NEXT: andl $255, %eax
180 ; X32-NEXT: shll $8, %eax
181 ; X32-NEXT: orl %ecx, %eax
182 ; X32-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
185 ; X64-LABEL: test_bextr_u32:
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
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)
201 define i32 @test_blsi_u32(i32 %a0) {
202 ; X32-LABEL: test_blsi_u32:
204 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
205 ; X32-NEXT: xorl %eax, %eax
206 ; X32-NEXT: subl %ecx, %eax
207 ; X32-NEXT: andl %ecx, %eax
210 ; X64-LABEL: test_blsi_u32:
212 ; X64-NEXT: xorl %eax, %eax
213 ; X64-NEXT: subl %edi, %eax
214 ; X64-NEXT: andl %edi, %eax
216 %neg = sub i32 0, %a0
217 %res = and i32 %a0, %neg
221 define i32 @test_blsmsk_u32(i32 %a0) {
222 ; X32-LABEL: test_blsmsk_u32:
224 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
225 ; X32-NEXT: leal -1(%ecx), %eax
226 ; X32-NEXT: xorl %ecx, %eax
229 ; X64-LABEL: test_blsmsk_u32:
231 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
232 ; X64-NEXT: leal -1(%rdi), %eax
233 ; X64-NEXT: xorl %edi, %eax
235 %dec = sub i32 %a0, 1
236 %res = xor i32 %a0, %dec
240 define i32 @test_blsr_u32(i32 %a0) {
241 ; X32-LABEL: test_blsr_u32:
243 ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
244 ; X32-NEXT: leal -1(%ecx), %eax
245 ; X32-NEXT: andl %ecx, %eax
248 ; X64-LABEL: test_blsr_u32:
250 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
251 ; X64-NEXT: leal -1(%rdi), %eax
252 ; X64-NEXT: andl %edi, %eax
254 %dec = sub i32 %a0, 1
255 %res = and i32 %a0, %dec
259 define i32 @test_tzcnt_u32(i32 %a0) {
260 ; X32-LABEL: test_tzcnt_u32:
262 ; X32-NEXT: tzcntl {{[0-9]+}}(%esp), %eax
265 ; X64-LABEL: test_tzcnt_u32:
267 ; X64-NEXT: tzcntl %edi, %eax
269 %cmp = icmp ne i32 %a0, 0
270 %cttz = call i32 @llvm.cttz.i32(i32 %a0, i1 false)
274 declare i16 @llvm.cttz.i16(i16, i1)
275 declare i32 @llvm.cttz.i32(i32, i1)
276 declare i32 @llvm.x86.bmi.bextr.32(i32, i32)