[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / X86 / bmi.ll
blobd5603431e756cc4cc958c46003f2a791353e4bc2
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov,+bmi | FileCheck %s --check-prefixes=CHECK,X86,X86-SLOW-BEXTR
3 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov,+bmi,+bmi2 | FileCheck %s --check-prefixes=CHECK,X86,X86-SLOW-BEXTR
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,X64,X64-SLOW-BEXTR
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+bmi2 | FileCheck %s --check-prefixes=CHECK,X64,X64-SLOW-BEXTR
6 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov,+bmi,+fast-bextr | FileCheck %s --check-prefixes=CHECK,X86,X86-FAST-BEXTR
7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+fast-bextr | FileCheck %s --check-prefixes=CHECK,X64,X64-FAST-BEXTR
9 define i32 @andn32(i32 %x, i32 %y)   {
10 ; X86-LABEL: andn32:
11 ; X86:       # %bb.0:
12 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
13 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
14 ; X86-NEXT:    retl
16 ; X64-LABEL: andn32:
17 ; X64:       # %bb.0:
18 ; X64-NEXT:    andnl %esi, %edi, %eax
19 ; X64-NEXT:    retq
20   %tmp1 = xor i32 %x, -1
21   %tmp2 = and i32 %y, %tmp1
22   ret i32 %tmp2
25 define i32 @andn32_load(i32 %x, i32* %y)   {
26 ; X86-LABEL: andn32_load:
27 ; X86:       # %bb.0:
28 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
29 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
30 ; X86-NEXT:    andnl (%eax), %ecx, %eax
31 ; X86-NEXT:    retl
33 ; X64-LABEL: andn32_load:
34 ; X64:       # %bb.0:
35 ; X64-NEXT:    andnl (%rsi), %edi, %eax
36 ; X64-NEXT:    retq
37   %y1 = load i32, i32* %y
38   %tmp1 = xor i32 %x, -1
39   %tmp2 = and i32 %y1, %tmp1
40   ret i32 %tmp2
43 define i64 @andn64(i64 %x, i64 %y)   {
44 ; X86-LABEL: andn64:
45 ; X86:       # %bb.0:
46 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
47 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
48 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
49 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %ecx, %edx
50 ; X86-NEXT:    retl
52 ; X64-LABEL: andn64:
53 ; X64:       # %bb.0:
54 ; X64-NEXT:    andnq %rsi, %rdi, %rax
55 ; X64-NEXT:    retq
56   %tmp1 = xor i64 %x, -1
57   %tmp2 = and i64 %tmp1, %y
58   ret i64 %tmp2
61 ; Don't choose a 'test' if an 'andn' can be used.
62 define i1 @andn_cmp(i32 %x, i32 %y) {
63 ; X86-LABEL: andn_cmp:
64 ; X86:       # %bb.0:
65 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
66 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
67 ; X86-NEXT:    sete %al
68 ; X86-NEXT:    retl
70 ; X64-LABEL: andn_cmp:
71 ; X64:       # %bb.0:
72 ; X64-NEXT:    andnl %esi, %edi, %eax
73 ; X64-NEXT:    sete %al
74 ; X64-NEXT:    retq
75   %notx = xor i32 %x, -1
76   %and = and i32 %notx, %y
77   %cmp = icmp eq i32 %and, 0
78   ret i1 %cmp
81 ; Recognize a disguised andn in the following 4 tests.
82 define i1 @and_cmp1(i32 %x, i32 %y) {
83 ; X86-LABEL: and_cmp1:
84 ; X86:       # %bb.0:
85 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
86 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
87 ; X86-NEXT:    sete %al
88 ; X86-NEXT:    retl
90 ; X64-LABEL: and_cmp1:
91 ; X64:       # %bb.0:
92 ; X64-NEXT:    andnl %esi, %edi, %eax
93 ; X64-NEXT:    sete %al
94 ; X64-NEXT:    retq
95   %and = and i32 %x, %y
96   %cmp = icmp eq i32 %and, %y
97   ret i1 %cmp
100 define i1 @and_cmp2(i32 %x, i32 %y) {
101 ; X86-LABEL: and_cmp2:
102 ; X86:       # %bb.0:
103 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
104 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
105 ; X86-NEXT:    setne %al
106 ; X86-NEXT:    retl
108 ; X64-LABEL: and_cmp2:
109 ; X64:       # %bb.0:
110 ; X64-NEXT:    andnl %esi, %edi, %eax
111 ; X64-NEXT:    setne %al
112 ; X64-NEXT:    retq
113   %and = and i32 %y, %x
114   %cmp = icmp ne i32 %and, %y
115   ret i1 %cmp
118 define i1 @and_cmp3(i32 %x, i32 %y) {
119 ; X86-LABEL: and_cmp3:
120 ; X86:       # %bb.0:
121 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
122 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
123 ; X86-NEXT:    sete %al
124 ; X86-NEXT:    retl
126 ; X64-LABEL: and_cmp3:
127 ; X64:       # %bb.0:
128 ; X64-NEXT:    andnl %esi, %edi, %eax
129 ; X64-NEXT:    sete %al
130 ; X64-NEXT:    retq
131   %and = and i32 %x, %y
132   %cmp = icmp eq i32 %y, %and
133   ret i1 %cmp
136 define i1 @and_cmp4(i32 %x, i32 %y) {
137 ; X86-LABEL: and_cmp4:
138 ; X86:       # %bb.0:
139 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
140 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
141 ; X86-NEXT:    setne %al
142 ; X86-NEXT:    retl
144 ; X64-LABEL: and_cmp4:
145 ; X64:       # %bb.0:
146 ; X64-NEXT:    andnl %esi, %edi, %eax
147 ; X64-NEXT:    setne %al
148 ; X64-NEXT:    retq
149   %and = and i32 %y, %x
150   %cmp = icmp ne i32 %y, %and
151   ret i1 %cmp
154 ; A mask and compare against constant is ok for an 'andn' too
155 ; even though the BMI instruction doesn't have an immediate form.
156 define i1 @and_cmp_const(i32 %x) {
157 ; X86-LABEL: and_cmp_const:
158 ; X86:       # %bb.0:
159 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
160 ; X86-NEXT:    andl $43, %eax
161 ; X86-NEXT:    cmpl $43, %eax
162 ; X86-NEXT:    sete %al
163 ; X86-NEXT:    retl
165 ; X64-LABEL: and_cmp_const:
166 ; X64:       # %bb.0:
167 ; X64-NEXT:    andl $43, %edi
168 ; X64-NEXT:    cmpl $43, %edi
169 ; X64-NEXT:    sete %al
170 ; X64-NEXT:    retq
171   %and = and i32 %x, 43
172   %cmp = icmp eq i32 %and, 43
173   ret i1 %cmp
176 ; But don't use 'andn' if the mask is a power-of-two.
177 define i1 @and_cmp_const_power_of_two(i32 %x, i32 %y) {
178 ; X86-LABEL: and_cmp_const_power_of_two:
179 ; X86:       # %bb.0:
180 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
181 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
182 ; X86-NEXT:    btl %ecx, %eax
183 ; X86-NEXT:    setae %al
184 ; X86-NEXT:    retl
186 ; X64-LABEL: and_cmp_const_power_of_two:
187 ; X64:       # %bb.0:
188 ; X64-NEXT:    btl %esi, %edi
189 ; X64-NEXT:    setae %al
190 ; X64-NEXT:    retq
191   %shl = shl i32 1, %y
192   %and = and i32 %x, %shl
193   %cmp = icmp ne i32 %and, %shl
194   ret i1 %cmp
197 ; Don't transform to 'andn' if there's another use of the 'and'.
198 define i32 @and_cmp_not_one_use(i32 %x) {
199 ; X86-LABEL: and_cmp_not_one_use:
200 ; X86:       # %bb.0:
201 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
202 ; X86-NEXT:    andl $37, %ecx
203 ; X86-NEXT:    xorl %eax, %eax
204 ; X86-NEXT:    cmpl $37, %ecx
205 ; X86-NEXT:    sete %al
206 ; X86-NEXT:    addl %ecx, %eax
207 ; X86-NEXT:    retl
209 ; X64-LABEL: and_cmp_not_one_use:
210 ; X64:       # %bb.0:
211 ; X64-NEXT:    andl $37, %edi
212 ; X64-NEXT:    xorl %eax, %eax
213 ; X64-NEXT:    cmpl $37, %edi
214 ; X64-NEXT:    sete %al
215 ; X64-NEXT:    addl %edi, %eax
216 ; X64-NEXT:    retq
217   %and = and i32 %x, 37
218   %cmp = icmp eq i32 %and, 37
219   %ext = zext i1 %cmp to i32
220   %add = add i32 %and, %ext
221   ret i32 %add
224 ; Verify that we're not transforming invalid comparison predicates.
225 define i1 @not_an_andn1(i32 %x, i32 %y) {
226 ; X86-LABEL: not_an_andn1:
227 ; X86:       # %bb.0:
228 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
229 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
230 ; X86-NEXT:    andl %eax, %ecx
231 ; X86-NEXT:    cmpl %ecx, %eax
232 ; X86-NEXT:    setg %al
233 ; X86-NEXT:    retl
235 ; X64-LABEL: not_an_andn1:
236 ; X64:       # %bb.0:
237 ; X64-NEXT:    andl %esi, %edi
238 ; X64-NEXT:    cmpl %edi, %esi
239 ; X64-NEXT:    setg %al
240 ; X64-NEXT:    retq
241   %and = and i32 %x, %y
242   %cmp = icmp sgt i32 %y, %and
243   ret i1 %cmp
246 define i1 @not_an_andn2(i32 %x, i32 %y) {
247 ; X86-LABEL: not_an_andn2:
248 ; X86:       # %bb.0:
249 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
250 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
251 ; X86-NEXT:    andl %eax, %ecx
252 ; X86-NEXT:    cmpl %ecx, %eax
253 ; X86-NEXT:    setbe %al
254 ; X86-NEXT:    retl
256 ; X64-LABEL: not_an_andn2:
257 ; X64:       # %bb.0:
258 ; X64-NEXT:    andl %esi, %edi
259 ; X64-NEXT:    cmpl %edi, %esi
260 ; X64-NEXT:    setbe %al
261 ; X64-NEXT:    retq
262   %and = and i32 %y, %x
263   %cmp = icmp ule i32 %y, %and
264   ret i1 %cmp
267 ; Don't choose a 'test' if an 'andn' can be used.
268 define i1 @andn_cmp_swap_ops(i64 %x, i64 %y) {
269 ; X86-LABEL: andn_cmp_swap_ops:
270 ; X86:       # %bb.0:
271 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
272 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
273 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %ecx, %ecx
274 ; X86-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
275 ; X86-NEXT:    orl %ecx, %eax
276 ; X86-NEXT:    sete %al
277 ; X86-NEXT:    retl
279 ; X64-LABEL: andn_cmp_swap_ops:
280 ; X64:       # %bb.0:
281 ; X64-NEXT:    andnq %rsi, %rdi, %rax
282 ; X64-NEXT:    sete %al
283 ; X64-NEXT:    retq
284   %notx = xor i64 %x, -1
285   %and = and i64 %y, %notx
286   %cmp = icmp eq i64 %and, 0
287   ret i1 %cmp
290 ; Use a 'test' (not an 'and') because 'andn' only works for i32/i64.
291 define i1 @andn_cmp_i8(i8 %x, i8 %y) {
292 ; X86-LABEL: andn_cmp_i8:
293 ; X86:       # %bb.0:
294 ; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
295 ; X86-NEXT:    notb %al
296 ; X86-NEXT:    testb %al, {{[0-9]+}}(%esp)
297 ; X86-NEXT:    sete %al
298 ; X86-NEXT:    retl
300 ; X64-LABEL: andn_cmp_i8:
301 ; X64:       # %bb.0:
302 ; X64-NEXT:    notb %sil
303 ; X64-NEXT:    testb %sil, %dil
304 ; X64-NEXT:    sete %al
305 ; X64-NEXT:    retq
306   %noty = xor i8 %y, -1
307   %and = and i8 %x, %noty
308   %cmp = icmp eq i8 %and, 0
309   ret i1 %cmp
312 declare i32 @llvm.x86.bmi.bextr.32(i32, i32)
314 define i32 @bextr32(i32 %x, i32 %y)   {
315 ; X86-LABEL: bextr32:
316 ; X86:       # %bb.0:
317 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
318 ; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
319 ; X86-NEXT:    retl
321 ; X64-LABEL: bextr32:
322 ; X64:       # %bb.0:
323 ; X64-NEXT:    bextrl %esi, %edi, %eax
324 ; X64-NEXT:    retq
325   %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
326   ret i32 %tmp
329 define i32 @bextr32_load(i32* %x, i32 %y)   {
330 ; X86-LABEL: bextr32_load:
331 ; X86:       # %bb.0:
332 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
333 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
334 ; X86-NEXT:    bextrl %eax, (%ecx), %eax
335 ; X86-NEXT:    retl
337 ; X64-LABEL: bextr32_load:
338 ; X64:       # %bb.0:
339 ; X64-NEXT:    bextrl %esi, (%rdi), %eax
340 ; X64-NEXT:    retq
341   %x1 = load i32, i32* %x
342   %tmp = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x1, i32 %y)
343   ret i32 %tmp
346 define i32 @bextr32b(i32 %x)  uwtable  ssp {
347 ; X86-SLOW-BEXTR-LABEL: bextr32b:
348 ; X86-SLOW-BEXTR:       # %bb.0:
349 ; X86-SLOW-BEXTR-NEXT:    movl {{[0-9]+}}(%esp), %eax
350 ; X86-SLOW-BEXTR-NEXT:    shrl $4, %eax
351 ; X86-SLOW-BEXTR-NEXT:    andl $4095, %eax # imm = 0xFFF
352 ; X86-SLOW-BEXTR-NEXT:    retl
354 ; X64-SLOW-BEXTR-LABEL: bextr32b:
355 ; X64-SLOW-BEXTR:       # %bb.0:
356 ; X64-SLOW-BEXTR-NEXT:    movl %edi, %eax
357 ; X64-SLOW-BEXTR-NEXT:    shrl $4, %eax
358 ; X64-SLOW-BEXTR-NEXT:    andl $4095, %eax # imm = 0xFFF
359 ; X64-SLOW-BEXTR-NEXT:    retq
361 ; X86-FAST-BEXTR-LABEL: bextr32b:
362 ; X86-FAST-BEXTR:       # %bb.0:
363 ; X86-FAST-BEXTR-NEXT:    movl $3076, %eax # imm = 0xC04
364 ; X86-FAST-BEXTR-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
365 ; X86-FAST-BEXTR-NEXT:    retl
367 ; X64-FAST-BEXTR-LABEL: bextr32b:
368 ; X64-FAST-BEXTR:       # %bb.0:
369 ; X64-FAST-BEXTR-NEXT:    movl $3076, %eax # imm = 0xC04
370 ; X64-FAST-BEXTR-NEXT:    bextrl %eax, %edi, %eax
371 ; X64-FAST-BEXTR-NEXT:    retq
372   %1 = lshr i32 %x, 4
373   %2 = and i32 %1, 4095
374   ret i32 %2
377 ; Make sure we still use AH subreg trick to extract 15:8
378 define i32 @bextr32_subreg(i32 %x)  uwtable  ssp {
379 ; X86-LABEL: bextr32_subreg:
380 ; X86:       # %bb.0:
381 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
382 ; X86-NEXT:    retl
384 ; X64-LABEL: bextr32_subreg:
385 ; X64:       # %bb.0:
386 ; X64-NEXT:    movl %edi, %eax
387 ; X64-NEXT:    movzbl %ah, %eax
388 ; X64-NEXT:    retq
389   %1 = lshr i32 %x, 8
390   %2 = and i32 %1, 255
391   ret i32 %2
394 define i32 @bextr32b_load(i32* %x)  uwtable  ssp {
395 ; X86-SLOW-BEXTR-LABEL: bextr32b_load:
396 ; X86-SLOW-BEXTR:       # %bb.0:
397 ; X86-SLOW-BEXTR-NEXT:    movl {{[0-9]+}}(%esp), %eax
398 ; X86-SLOW-BEXTR-NEXT:    movl (%eax), %eax
399 ; X86-SLOW-BEXTR-NEXT:    shrl $4, %eax
400 ; X86-SLOW-BEXTR-NEXT:    andl $4095, %eax # imm = 0xFFF
401 ; X86-SLOW-BEXTR-NEXT:    retl
403 ; X64-SLOW-BEXTR-LABEL: bextr32b_load:
404 ; X64-SLOW-BEXTR:       # %bb.0:
405 ; X64-SLOW-BEXTR-NEXT:    movl (%rdi), %eax
406 ; X64-SLOW-BEXTR-NEXT:    shrl $4, %eax
407 ; X64-SLOW-BEXTR-NEXT:    andl $4095, %eax # imm = 0xFFF
408 ; X64-SLOW-BEXTR-NEXT:    retq
410 ; X86-FAST-BEXTR-LABEL: bextr32b_load:
411 ; X86-FAST-BEXTR:       # %bb.0:
412 ; X86-FAST-BEXTR-NEXT:    movl {{[0-9]+}}(%esp), %eax
413 ; X86-FAST-BEXTR-NEXT:    movl $3076, %ecx # imm = 0xC04
414 ; X86-FAST-BEXTR-NEXT:    bextrl %ecx, (%eax), %eax
415 ; X86-FAST-BEXTR-NEXT:    retl
417 ; X64-FAST-BEXTR-LABEL: bextr32b_load:
418 ; X64-FAST-BEXTR:       # %bb.0:
419 ; X64-FAST-BEXTR-NEXT:    movl $3076, %eax # imm = 0xC04
420 ; X64-FAST-BEXTR-NEXT:    bextrl %eax, (%rdi), %eax
421 ; X64-FAST-BEXTR-NEXT:    retq
422   %1 = load i32, i32* %x
423   %2 = lshr i32 %1, 4
424   %3 = and i32 %2, 4095
425   ret i32 %3
428 ; PR34042
429 define i32 @bextr32c(i32 %x, i16 zeroext %y) {
430 ; X86-LABEL: bextr32c:
431 ; X86:       # %bb.0:
432 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
433 ; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
434 ; X86-NEXT:    retl
436 ; X64-LABEL: bextr32c:
437 ; X64:       # %bb.0:
438 ; X64-NEXT:    bextrl %esi, %edi, %eax
439 ; X64-NEXT:    retq
440   %tmp0 = sext i16 %y to i32
441   %tmp1 = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %tmp0)
442   ret i32 %tmp1
445 define i32 @non_bextr32(i32 %x) {
446 ; X86-LABEL: non_bextr32:
447 ; X86:       # %bb.0: # %entry
448 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
449 ; X86-NEXT:    shrl $2, %eax
450 ; X86-NEXT:    andl $111, %eax
451 ; X86-NEXT:    retl
453 ; X64-LABEL: non_bextr32:
454 ; X64:       # %bb.0: # %entry
455 ; X64-NEXT:    movl %edi, %eax
456 ; X64-NEXT:    shrl $2, %eax
457 ; X64-NEXT:    andl $111, %eax
458 ; X64-NEXT:    retq
459 entry:
460   %shr = lshr i32 %x, 2
461   %and = and i32 %shr, 111
462   ret i32 %and
465 define i32 @blsi32(i32 %x)   {
466 ; X86-LABEL: blsi32:
467 ; X86:       # %bb.0:
468 ; X86-NEXT:    blsil {{[0-9]+}}(%esp), %eax
469 ; X86-NEXT:    retl
471 ; X64-LABEL: blsi32:
472 ; X64:       # %bb.0:
473 ; X64-NEXT:    blsil %edi, %eax
474 ; X64-NEXT:    retq
475   %tmp = sub i32 0, %x
476   %tmp2 = and i32 %x, %tmp
477   ret i32 %tmp2
480 define i32 @blsi32_load(i32* %x)   {
481 ; X86-LABEL: blsi32_load:
482 ; X86:       # %bb.0:
483 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
484 ; X86-NEXT:    blsil (%eax), %eax
485 ; X86-NEXT:    retl
487 ; X64-LABEL: blsi32_load:
488 ; X64:       # %bb.0:
489 ; X64-NEXT:    blsil (%rdi), %eax
490 ; X64-NEXT:    retq
491   %x1 = load i32, i32* %x
492   %tmp = sub i32 0, %x1
493   %tmp2 = and i32 %x1, %tmp
494   ret i32 %tmp2
497 define i32 @blsi32_z(i32 %a, i32 %b) nounwind {
498 ; X86-LABEL: blsi32_z:
499 ; X86:       # %bb.0:
500 ; X86-NEXT:    blsil {{[0-9]+}}(%esp), %eax
501 ; X86-NEXT:    jne .LBB24_2
502 ; X86-NEXT:  # %bb.1:
503 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
504 ; X86-NEXT:  .LBB24_2:
505 ; X86-NEXT:    retl
507 ; X64-LABEL: blsi32_z:
508 ; X64:       # %bb.0:
509 ; X64-NEXT:    blsil %edi, %eax
510 ; X64-NEXT:    cmovel %esi, %eax
511 ; X64-NEXT:    retq
512   %t0 = sub i32 0, %a
513   %t1 = and i32 %t0, %a
514   %t2 = icmp eq i32 %t1, 0
515   %t3 = select i1 %t2, i32 %b, i32 %t1
516   ret i32 %t3
519 define i32 @blsi32_z2(i32 %a, i32 %b, i32 %c) nounwind {
520 ; X86-LABEL: blsi32_z2:
521 ; X86:       # %bb.0:
522 ; X86-NEXT:    blsil {{[0-9]+}}(%esp), %eax
523 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
524 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
525 ; X86-NEXT:    cmovel %eax, %ecx
526 ; X86-NEXT:    movl (%ecx), %eax
527 ; X86-NEXT:    retl
529 ; X64-LABEL: blsi32_z2:
530 ; X64:       # %bb.0:
531 ; X64-NEXT:    movl %esi, %eax
532 ; X64-NEXT:    blsil %edi, %ecx
533 ; X64-NEXT:    cmovnel %edx, %eax
534 ; X64-NEXT:    retq
535   %t0 = sub i32 0, %a
536   %t1 = and i32 %t0, %a
537   %t2 = icmp eq i32 %t1, 0
538   %t3 = select i1 %t2, i32 %b, i32 %c
539   ret i32 %t3
542 define i64 @blsi64(i64 %x)   {
543 ; X86-LABEL: blsi64:
544 ; X86:       # %bb.0:
545 ; X86-NEXT:    pushl %esi
546 ; X86-NEXT:    .cfi_def_cfa_offset 8
547 ; X86-NEXT:    .cfi_offset %esi, -8
548 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
549 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
550 ; X86-NEXT:    xorl %edx, %edx
551 ; X86-NEXT:    movl %ecx, %eax
552 ; X86-NEXT:    negl %eax
553 ; X86-NEXT:    sbbl %esi, %edx
554 ; X86-NEXT:    andl %esi, %edx
555 ; X86-NEXT:    andl %ecx, %eax
556 ; X86-NEXT:    popl %esi
557 ; X86-NEXT:    .cfi_def_cfa_offset 4
558 ; X86-NEXT:    retl
560 ; X64-LABEL: blsi64:
561 ; X64:       # %bb.0:
562 ; X64-NEXT:    blsiq %rdi, %rax
563 ; X64-NEXT:    retq
564   %tmp = sub i64 0, %x
565   %tmp2 = and i64 %tmp, %x
566   ret i64 %tmp2
569 define i64 @blsi64_z(i64 %a, i64 %b) nounwind {
570 ; X86-LABEL: blsi64_z:
571 ; X86:       # %bb.0:
572 ; X86-NEXT:    pushl %esi
573 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
574 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
575 ; X86-NEXT:    xorl %edx, %edx
576 ; X86-NEXT:    movl %ecx, %eax
577 ; X86-NEXT:    negl %eax
578 ; X86-NEXT:    sbbl %esi, %edx
579 ; X86-NEXT:    andl %esi, %edx
580 ; X86-NEXT:    andl %ecx, %eax
581 ; X86-NEXT:    movl %eax, %ecx
582 ; X86-NEXT:    orl %edx, %ecx
583 ; X86-NEXT:    jne .LBB27_2
584 ; X86-NEXT:  # %bb.1:
585 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
586 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
587 ; X86-NEXT:  .LBB27_2:
588 ; X86-NEXT:    popl %esi
589 ; X86-NEXT:    retl
591 ; X64-LABEL: blsi64_z:
592 ; X64:       # %bb.0:
593 ; X64-NEXT:    blsiq %rdi, %rax
594 ; X64-NEXT:    cmoveq %rsi, %rax
595 ; X64-NEXT:    retq
596   %t0 = sub i64 0, %a
597   %t1 = and i64 %t0, %a
598   %t2 = icmp eq i64 %t1, 0
599   %t3 = select i1 %t2, i64 %b, i64 %t1
600   ret i64 %t3
603 define i64 @blsi64_z2(i64 %a, i64 %b, i64 %c) nounwind {
604 ; X86-LABEL: blsi64_z2:
605 ; X86:       # %bb.0:
606 ; X86-NEXT:    pushl %esi
607 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
608 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
609 ; X86-NEXT:    xorl %edx, %edx
610 ; X86-NEXT:    movl %eax, %esi
611 ; X86-NEXT:    negl %esi
612 ; X86-NEXT:    sbbl %ecx, %edx
613 ; X86-NEXT:    andl %ecx, %edx
614 ; X86-NEXT:    andl %eax, %esi
615 ; X86-NEXT:    orl %edx, %esi
616 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
617 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
618 ; X86-NEXT:    cmovel %eax, %ecx
619 ; X86-NEXT:    movl (%ecx), %eax
620 ; X86-NEXT:    movl 4(%ecx), %edx
621 ; X86-NEXT:    popl %esi
622 ; X86-NEXT:    retl
624 ; X64-LABEL: blsi64_z2:
625 ; X64:       # %bb.0:
626 ; X64-NEXT:    movq %rsi, %rax
627 ; X64-NEXT:    blsiq %rdi, %rcx
628 ; X64-NEXT:    cmovneq %rdx, %rax
629 ; X64-NEXT:    retq
630   %t0 = sub i64 0, %a
631   %t1 = and i64 %t0, %a
632   %t2 = icmp eq i64 %t1, 0
633   %t3 = select i1 %t2, i64 %b, i64 %c
634   ret i64 %t3
637 define i32 @blsmsk32(i32 %x)   {
638 ; X86-LABEL: blsmsk32:
639 ; X86:       # %bb.0:
640 ; X86-NEXT:    blsmskl {{[0-9]+}}(%esp), %eax
641 ; X86-NEXT:    retl
643 ; X64-LABEL: blsmsk32:
644 ; X64:       # %bb.0:
645 ; X64-NEXT:    blsmskl %edi, %eax
646 ; X64-NEXT:    retq
647   %tmp = sub i32 %x, 1
648   %tmp2 = xor i32 %x, %tmp
649   ret i32 %tmp2
652 define i32 @blsmsk32_load(i32* %x)   {
653 ; X86-LABEL: blsmsk32_load:
654 ; X86:       # %bb.0:
655 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
656 ; X86-NEXT:    blsmskl (%eax), %eax
657 ; X86-NEXT:    retl
659 ; X64-LABEL: blsmsk32_load:
660 ; X64:       # %bb.0:
661 ; X64-NEXT:    blsmskl (%rdi), %eax
662 ; X64-NEXT:    retq
663   %x1 = load i32, i32* %x
664   %tmp = sub i32 %x1, 1
665   %tmp2 = xor i32 %x1, %tmp
666   ret i32 %tmp2
669 define i32 @blsmsk32_z(i32 %a, i32 %b) nounwind {
670 ; X86-LABEL: blsmsk32_z:
671 ; X86:       # %bb.0:
672 ; X86-NEXT:    blsmskl {{[0-9]+}}(%esp), %eax
673 ; X86-NEXT:    jne .LBB31_2
674 ; X86-NEXT:  # %bb.1:
675 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
676 ; X86-NEXT:  .LBB31_2:
677 ; X86-NEXT:    retl
679 ; X64-LABEL: blsmsk32_z:
680 ; X64:       # %bb.0:
681 ; X64-NEXT:    blsmskl %edi, %eax
682 ; X64-NEXT:    cmovel %esi, %eax
683 ; X64-NEXT:    retq
684   %t0 = sub i32 %a, 1
685   %t1 = xor i32 %t0, %a
686   %t2 = icmp eq i32 %t1, 0
687   %t3 = select i1 %t2, i32 %b, i32 %t1
688   ret i32 %t3
691 define i32 @blsmsk32_z2(i32 %a, i32 %b, i32 %c) nounwind {
692 ; X86-LABEL: blsmsk32_z2:
693 ; X86:       # %bb.0:
694 ; X86-NEXT:    blsmskl {{[0-9]+}}(%esp), %eax
695 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
696 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
697 ; X86-NEXT:    cmovel %eax, %ecx
698 ; X86-NEXT:    movl (%ecx), %eax
699 ; X86-NEXT:    retl
701 ; X64-LABEL: blsmsk32_z2:
702 ; X64:       # %bb.0:
703 ; X64-NEXT:    movl %esi, %eax
704 ; X64-NEXT:    blsmskl %edi, %ecx
705 ; X64-NEXT:    cmovnel %edx, %eax
706 ; X64-NEXT:    retq
707   %t0 = sub i32 %a, 1
708   %t1 = xor i32 %t0, %a
709   %t2 = icmp eq i32 %t1, 0
710   %t3 = select i1 %t2, i32 %b, i32 %c
711   ret i32 %t3
714 define i64 @blsmsk64(i64 %x)   {
715 ; X86-LABEL: blsmsk64:
716 ; X86:       # %bb.0:
717 ; X86-NEXT:    pushl %esi
718 ; X86-NEXT:    .cfi_def_cfa_offset 8
719 ; X86-NEXT:    .cfi_offset %esi, -8
720 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
721 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
722 ; X86-NEXT:    movl %ecx, %eax
723 ; X86-NEXT:    addl $-1, %eax
724 ; X86-NEXT:    movl %esi, %edx
725 ; X86-NEXT:    adcl $-1, %edx
726 ; X86-NEXT:    xorl %ecx, %eax
727 ; X86-NEXT:    xorl %esi, %edx
728 ; X86-NEXT:    popl %esi
729 ; X86-NEXT:    .cfi_def_cfa_offset 4
730 ; X86-NEXT:    retl
732 ; X64-LABEL: blsmsk64:
733 ; X64:       # %bb.0:
734 ; X64-NEXT:    blsmskq %rdi, %rax
735 ; X64-NEXT:    retq
736   %tmp = sub i64 %x, 1
737   %tmp2 = xor i64 %tmp, %x
738   ret i64 %tmp2
741 define i64 @blsmsk64_z(i64 %a, i64 %b) nounwind {
742 ; X86-LABEL: blsmsk64_z:
743 ; X86:       # %bb.0:
744 ; X86-NEXT:    pushl %esi
745 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
746 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
747 ; X86-NEXT:    movl %ecx, %eax
748 ; X86-NEXT:    addl $-1, %eax
749 ; X86-NEXT:    movl %esi, %edx
750 ; X86-NEXT:    adcl $-1, %edx
751 ; X86-NEXT:    xorl %ecx, %eax
752 ; X86-NEXT:    xorl %esi, %edx
753 ; X86-NEXT:    movl %eax, %ecx
754 ; X86-NEXT:    orl %edx, %ecx
755 ; X86-NEXT:    jne .LBB34_2
756 ; X86-NEXT:  # %bb.1:
757 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
758 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
759 ; X86-NEXT:  .LBB34_2:
760 ; X86-NEXT:    popl %esi
761 ; X86-NEXT:    retl
763 ; X64-LABEL: blsmsk64_z:
764 ; X64:       # %bb.0:
765 ; X64-NEXT:    blsmskq %rdi, %rax
766 ; X64-NEXT:    cmoveq %rsi, %rax
767 ; X64-NEXT:    retq
768   %t0 = sub i64 %a, 1
769   %t1 = xor i64 %t0, %a
770   %t2 = icmp eq i64 %t1, 0
771   %t3 = select i1 %t2, i64 %b, i64 %t1
772   ret i64 %t3
775 define i64 @blsmsk64_z2(i64 %a, i64 %b, i64 %c) nounwind {
776 ; X86-LABEL: blsmsk64_z2:
777 ; X86:       # %bb.0:
778 ; X86-NEXT:    pushl %esi
779 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
780 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
781 ; X86-NEXT:    movl %eax, %edx
782 ; X86-NEXT:    addl $-1, %edx
783 ; X86-NEXT:    movl %ecx, %esi
784 ; X86-NEXT:    adcl $-1, %esi
785 ; X86-NEXT:    xorl %eax, %edx
786 ; X86-NEXT:    xorl %ecx, %esi
787 ; X86-NEXT:    orl %edx, %esi
788 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
789 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
790 ; X86-NEXT:    cmovel %eax, %ecx
791 ; X86-NEXT:    movl (%ecx), %eax
792 ; X86-NEXT:    movl 4(%ecx), %edx
793 ; X86-NEXT:    popl %esi
794 ; X86-NEXT:    retl
796 ; X64-LABEL: blsmsk64_z2:
797 ; X64:       # %bb.0:
798 ; X64-NEXT:    movq %rsi, %rax
799 ; X64-NEXT:    blsmskq %rdi, %rcx
800 ; X64-NEXT:    cmovneq %rdx, %rax
801 ; X64-NEXT:    retq
802   %t0 = sub i64 %a, 1
803   %t1 = xor i64 %t0, %a
804   %t2 = icmp eq i64 %t1, 0
805   %t3 = select i1 %t2, i64 %b, i64 %c
806   ret i64 %t3
809 define i32 @blsr32(i32 %x)   {
810 ; X86-LABEL: blsr32:
811 ; X86:       # %bb.0:
812 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %eax
813 ; X86-NEXT:    retl
815 ; X64-LABEL: blsr32:
816 ; X64:       # %bb.0:
817 ; X64-NEXT:    blsrl %edi, %eax
818 ; X64-NEXT:    retq
819   %tmp = sub i32 %x, 1
820   %tmp2 = and i32 %x, %tmp
821   ret i32 %tmp2
824 define i32 @blsr32_load(i32* %x)   {
825 ; X86-LABEL: blsr32_load:
826 ; X86:       # %bb.0:
827 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
828 ; X86-NEXT:    blsrl (%eax), %eax
829 ; X86-NEXT:    retl
831 ; X64-LABEL: blsr32_load:
832 ; X64:       # %bb.0:
833 ; X64-NEXT:    blsrl (%rdi), %eax
834 ; X64-NEXT:    retq
835   %x1 = load i32, i32* %x
836   %tmp = sub i32 %x1, 1
837   %tmp2 = and i32 %x1, %tmp
838   ret i32 %tmp2
841 define i32 @blsr32_z(i32 %a, i32 %b) nounwind {
842 ; X86-LABEL: blsr32_z:
843 ; X86:       # %bb.0:
844 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %eax
845 ; X86-NEXT:    jne .LBB38_2
846 ; X86-NEXT:  # %bb.1:
847 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
848 ; X86-NEXT:  .LBB38_2:
849 ; X86-NEXT:    retl
851 ; X64-LABEL: blsr32_z:
852 ; X64:       # %bb.0:
853 ; X64-NEXT:    blsrl %edi, %eax
854 ; X64-NEXT:    cmovel %esi, %eax
855 ; X64-NEXT:    retq
856   %t0 = sub i32 %a, 1
857   %t1 = and i32 %t0, %a
858   %t2 = icmp eq i32 %t1, 0
859   %t3 = select i1 %t2, i32 %b, i32 %t1
860   ret i32 %t3
863 define i32 @blsr32_z2(i32 %a, i32 %b, i32 %c) nounwind {
864 ; X86-LABEL: blsr32_z2:
865 ; X86:       # %bb.0:
866 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %eax
867 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
868 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
869 ; X86-NEXT:    cmovel %eax, %ecx
870 ; X86-NEXT:    movl (%ecx), %eax
871 ; X86-NEXT:    retl
873 ; X64-LABEL: blsr32_z2:
874 ; X64:       # %bb.0:
875 ; X64-NEXT:    movl %esi, %eax
876 ; X64-NEXT:    blsrl %edi, %ecx
877 ; X64-NEXT:    cmovnel %edx, %eax
878 ; X64-NEXT:    retq
879   %t0 = sub i32 %a, 1
880   %t1 = and i32 %t0, %a
881   %t2 = icmp eq i32 %t1, 0
882   %t3 = select i1 %t2, i32 %b, i32 %c
883   ret i32 %t3
886 define i64 @blsr64(i64 %x)   {
887 ; X86-LABEL: blsr64:
888 ; X86:       # %bb.0:
889 ; X86-NEXT:    pushl %esi
890 ; X86-NEXT:    .cfi_def_cfa_offset 8
891 ; X86-NEXT:    .cfi_offset %esi, -8
892 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
893 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
894 ; X86-NEXT:    movl %ecx, %eax
895 ; X86-NEXT:    addl $-1, %eax
896 ; X86-NEXT:    movl %esi, %edx
897 ; X86-NEXT:    adcl $-1, %edx
898 ; X86-NEXT:    andl %ecx, %eax
899 ; X86-NEXT:    andl %esi, %edx
900 ; X86-NEXT:    popl %esi
901 ; X86-NEXT:    .cfi_def_cfa_offset 4
902 ; X86-NEXT:    retl
904 ; X64-LABEL: blsr64:
905 ; X64:       # %bb.0:
906 ; X64-NEXT:    blsrq %rdi, %rax
907 ; X64-NEXT:    retq
908   %tmp = sub i64 %x, 1
909   %tmp2 = and i64 %tmp, %x
910   ret i64 %tmp2
913 define i64 @blsr64_z(i64 %a, i64 %b) nounwind {
914 ; X86-LABEL: blsr64_z:
915 ; X86:       # %bb.0:
916 ; X86-NEXT:    pushl %esi
917 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
918 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
919 ; X86-NEXT:    movl %ecx, %eax
920 ; X86-NEXT:    addl $-1, %eax
921 ; X86-NEXT:    movl %esi, %edx
922 ; X86-NEXT:    adcl $-1, %edx
923 ; X86-NEXT:    andl %ecx, %eax
924 ; X86-NEXT:    andl %esi, %edx
925 ; X86-NEXT:    movl %eax, %ecx
926 ; X86-NEXT:    orl %edx, %ecx
927 ; X86-NEXT:    jne .LBB41_2
928 ; X86-NEXT:  # %bb.1:
929 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
930 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
931 ; X86-NEXT:  .LBB41_2:
932 ; X86-NEXT:    popl %esi
933 ; X86-NEXT:    retl
935 ; X64-LABEL: blsr64_z:
936 ; X64:       # %bb.0:
937 ; X64-NEXT:    blsrq %rdi, %rax
938 ; X64-NEXT:    cmoveq %rsi, %rax
939 ; X64-NEXT:    retq
940   %t0 = sub i64 %a, 1
941   %t1 = and i64 %t0, %a
942   %t2 = icmp eq i64 %t1, 0
943   %t3 = select i1 %t2, i64 %b, i64 %t1
944   ret i64 %t3
947 define i64 @blsr64_z2(i64 %a, i64 %b, i64 %c) nounwind {
948 ; X86-LABEL: blsr64_z2:
949 ; X86:       # %bb.0:
950 ; X86-NEXT:    pushl %esi
951 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
952 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
953 ; X86-NEXT:    movl %eax, %edx
954 ; X86-NEXT:    addl $-1, %edx
955 ; X86-NEXT:    movl %ecx, %esi
956 ; X86-NEXT:    adcl $-1, %esi
957 ; X86-NEXT:    andl %eax, %edx
958 ; X86-NEXT:    andl %ecx, %esi
959 ; X86-NEXT:    orl %edx, %esi
960 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
961 ; X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
962 ; X86-NEXT:    cmovel %eax, %ecx
963 ; X86-NEXT:    movl (%ecx), %eax
964 ; X86-NEXT:    movl 4(%ecx), %edx
965 ; X86-NEXT:    popl %esi
966 ; X86-NEXT:    retl
968 ; X64-LABEL: blsr64_z2:
969 ; X64:       # %bb.0:
970 ; X64-NEXT:    movq %rsi, %rax
971 ; X64-NEXT:    blsrq %rdi, %rcx
972 ; X64-NEXT:    cmovneq %rdx, %rax
973 ; X64-NEXT:    retq
974   %t0 = sub i64 %a, 1
975   %t1 = and i64 %t0, %a
976   %t2 = icmp eq i64 %t1, 0
977   %t3 = select i1 %t2, i64 %b, i64 %c
978   ret i64 %t3
981 ; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792
983 define i64 @blsr_disguised_constant(i64 %x) {
984 ; X86-LABEL: blsr_disguised_constant:
985 ; X86:       # %bb.0:
986 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %eax
987 ; X86-NEXT:    movzwl %ax, %eax
988 ; X86-NEXT:    xorl %edx, %edx
989 ; X86-NEXT:    retl
991 ; X64-LABEL: blsr_disguised_constant:
992 ; X64:       # %bb.0:
993 ; X64-NEXT:    blsrl %edi, %eax
994 ; X64-NEXT:    movzwl %ax, %eax
995 ; X64-NEXT:    retq
996   %a1 = and i64 %x, 65535
997   %a2 = add i64 %x, 65535
998   %r = and i64 %a1, %a2
999   ret i64 %r
1002 ; The add here used to get shrunk, but the and did not thus hiding the blsr pattern.
1003 ; We now use the knowledge that upper bits of the shift guarantee the and result has 0s in the upper bits to reduce it too.
1004 define i64 @blsr_disguised_shrunk_add(i64 %x) {
1005 ; X86-LABEL: blsr_disguised_shrunk_add:
1006 ; X86:       # %bb.0:
1007 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1008 ; X86-NEXT:    shrl $16, %eax
1009 ; X86-NEXT:    blsrl %eax, %eax
1010 ; X86-NEXT:    xorl %edx, %edx
1011 ; X86-NEXT:    retl
1013 ; X64-LABEL: blsr_disguised_shrunk_add:
1014 ; X64:       # %bb.0:
1015 ; X64-NEXT:    shrq $48, %rdi
1016 ; X64-NEXT:    blsrl %edi, %eax
1017 ; X64-NEXT:    retq
1018   %a = lshr i64 %x, 48
1019   %b = add i64 %a, -1
1020   %c = and i64 %b, %a
1021   ret i64 %c
1024 ; FIXME: We should not be using the S flag from BEXTR.
1025 define void @pr40060(i32, i32) {
1026 ; X86-LABEL: pr40060:
1027 ; X86:       # %bb.0:
1028 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1029 ; X86-NEXT:    bextrl %eax, {{[0-9]+}}(%esp), %eax
1030 ; X86-NEXT:    testl %eax, %eax
1031 ; X86-NEXT:    js .LBB45_1
1032 ; X86-NEXT:  # %bb.2:
1033 ; X86-NEXT:    jmp bar # TAILCALL
1034 ; X86-NEXT:  .LBB45_1:
1035 ; X86-NEXT:    retl
1037 ; X64-LABEL: pr40060:
1038 ; X64:       # %bb.0:
1039 ; X64-NEXT:    bextrl %esi, %edi, %eax
1040 ; X64-NEXT:    testl %eax, %eax
1041 ; X64-NEXT:    js .LBB45_1
1042 ; X64-NEXT:  # %bb.2:
1043 ; X64-NEXT:    jmp bar # TAILCALL
1044 ; X64-NEXT:  .LBB45_1:
1045 ; X64-NEXT:    retq
1046   %3 = tail call i32 @llvm.x86.bmi.bextr.32(i32 %0, i32 %1)
1047   %4 = icmp sgt i32 %3, -1
1048   br i1 %4, label %5, label %6
1050   tail call void @bar()
1051   br label %6
1053   ret void
1056 define i32 @blsr32_branch(i32 %x) {
1057 ; X86-LABEL: blsr32_branch:
1058 ; X86:       # %bb.0:
1059 ; X86-NEXT:    pushl %esi
1060 ; X86-NEXT:    .cfi_def_cfa_offset 8
1061 ; X86-NEXT:    .cfi_offset %esi, -8
1062 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %esi
1063 ; X86-NEXT:    jne .LBB46_2
1064 ; X86-NEXT:  # %bb.1:
1065 ; X86-NEXT:    calll bar
1066 ; X86-NEXT:  .LBB46_2:
1067 ; X86-NEXT:    movl %esi, %eax
1068 ; X86-NEXT:    popl %esi
1069 ; X86-NEXT:    .cfi_def_cfa_offset 4
1070 ; X86-NEXT:    retl
1072 ; X64-LABEL: blsr32_branch:
1073 ; X64:       # %bb.0:
1074 ; X64-NEXT:    pushq %rbx
1075 ; X64-NEXT:    .cfi_def_cfa_offset 16
1076 ; X64-NEXT:    .cfi_offset %rbx, -16
1077 ; X64-NEXT:    blsrl %edi, %ebx
1078 ; X64-NEXT:    jne .LBB46_2
1079 ; X64-NEXT:  # %bb.1:
1080 ; X64-NEXT:    callq bar
1081 ; X64-NEXT:  .LBB46_2:
1082 ; X64-NEXT:    movl %ebx, %eax
1083 ; X64-NEXT:    popq %rbx
1084 ; X64-NEXT:    .cfi_def_cfa_offset 8
1085 ; X64-NEXT:    retq
1086   %tmp = sub i32 %x, 1
1087   %tmp2 = and i32 %x, %tmp
1088   %cmp = icmp eq i32 %tmp2, 0
1089   br i1 %cmp, label %1, label %2
1091   tail call void @bar()
1092   br label %2
1093   ret i32 %tmp2
1096 define i64 @blsr64_branch(i64 %x) {
1097 ; X86-LABEL: blsr64_branch:
1098 ; X86:       # %bb.0:
1099 ; X86-NEXT:    pushl %edi
1100 ; X86-NEXT:    .cfi_def_cfa_offset 8
1101 ; X86-NEXT:    pushl %esi
1102 ; X86-NEXT:    .cfi_def_cfa_offset 12
1103 ; X86-NEXT:    .cfi_offset %esi, -12
1104 ; X86-NEXT:    .cfi_offset %edi, -8
1105 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1106 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1107 ; X86-NEXT:    movl %eax, %esi
1108 ; X86-NEXT:    addl $-1, %esi
1109 ; X86-NEXT:    movl %ecx, %edi
1110 ; X86-NEXT:    adcl $-1, %edi
1111 ; X86-NEXT:    andl %eax, %esi
1112 ; X86-NEXT:    andl %ecx, %edi
1113 ; X86-NEXT:    movl %esi, %eax
1114 ; X86-NEXT:    orl %edi, %eax
1115 ; X86-NEXT:    jne .LBB47_2
1116 ; X86-NEXT:  # %bb.1:
1117 ; X86-NEXT:    calll bar
1118 ; X86-NEXT:  .LBB47_2:
1119 ; X86-NEXT:    movl %esi, %eax
1120 ; X86-NEXT:    movl %edi, %edx
1121 ; X86-NEXT:    popl %esi
1122 ; X86-NEXT:    .cfi_def_cfa_offset 8
1123 ; X86-NEXT:    popl %edi
1124 ; X86-NEXT:    .cfi_def_cfa_offset 4
1125 ; X86-NEXT:    retl
1127 ; X64-LABEL: blsr64_branch:
1128 ; X64:       # %bb.0:
1129 ; X64-NEXT:    pushq %rbx
1130 ; X64-NEXT:    .cfi_def_cfa_offset 16
1131 ; X64-NEXT:    .cfi_offset %rbx, -16
1132 ; X64-NEXT:    blsrq %rdi, %rbx
1133 ; X64-NEXT:    jne .LBB47_2
1134 ; X64-NEXT:  # %bb.1:
1135 ; X64-NEXT:    callq bar
1136 ; X64-NEXT:  .LBB47_2:
1137 ; X64-NEXT:    movq %rbx, %rax
1138 ; X64-NEXT:    popq %rbx
1139 ; X64-NEXT:    .cfi_def_cfa_offset 8
1140 ; X64-NEXT:    retq
1141   %tmp = sub i64 %x, 1
1142   %tmp2 = and i64 %x, %tmp
1143   %cmp = icmp eq i64 %tmp2, 0
1144   br i1 %cmp, label %1, label %2
1146   tail call void @bar()
1147   br label %2
1148   ret i64 %tmp2
1151 define i32 @blsi32_branch(i32 %x) {
1152 ; X86-LABEL: blsi32_branch:
1153 ; X86:       # %bb.0:
1154 ; X86-NEXT:    pushl %esi
1155 ; X86-NEXT:    .cfi_def_cfa_offset 8
1156 ; X86-NEXT:    .cfi_offset %esi, -8
1157 ; X86-NEXT:    blsil {{[0-9]+}}(%esp), %esi
1158 ; X86-NEXT:    jne .LBB48_2
1159 ; X86-NEXT:  # %bb.1:
1160 ; X86-NEXT:    calll bar
1161 ; X86-NEXT:  .LBB48_2:
1162 ; X86-NEXT:    movl %esi, %eax
1163 ; X86-NEXT:    popl %esi
1164 ; X86-NEXT:    .cfi_def_cfa_offset 4
1165 ; X86-NEXT:    retl
1167 ; X64-LABEL: blsi32_branch:
1168 ; X64:       # %bb.0:
1169 ; X64-NEXT:    pushq %rbx
1170 ; X64-NEXT:    .cfi_def_cfa_offset 16
1171 ; X64-NEXT:    .cfi_offset %rbx, -16
1172 ; X64-NEXT:    blsil %edi, %ebx
1173 ; X64-NEXT:    jne .LBB48_2
1174 ; X64-NEXT:  # %bb.1:
1175 ; X64-NEXT:    callq bar
1176 ; X64-NEXT:  .LBB48_2:
1177 ; X64-NEXT:    movl %ebx, %eax
1178 ; X64-NEXT:    popq %rbx
1179 ; X64-NEXT:    .cfi_def_cfa_offset 8
1180 ; X64-NEXT:    retq
1181   %tmp = sub i32 0, %x
1182   %tmp2 = and i32 %x, %tmp
1183   %cmp = icmp eq i32 %tmp2, 0
1184   br i1 %cmp, label %1, label %2
1186   tail call void @bar()
1187   br label %2
1188   ret i32 %tmp2
1191 define i64 @blsi64_branch(i64 %x) {
1192 ; X86-LABEL: blsi64_branch:
1193 ; X86:       # %bb.0:
1194 ; X86-NEXT:    pushl %edi
1195 ; X86-NEXT:    .cfi_def_cfa_offset 8
1196 ; X86-NEXT:    pushl %esi
1197 ; X86-NEXT:    .cfi_def_cfa_offset 12
1198 ; X86-NEXT:    .cfi_offset %esi, -12
1199 ; X86-NEXT:    .cfi_offset %edi, -8
1200 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1201 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1202 ; X86-NEXT:    xorl %esi, %esi
1203 ; X86-NEXT:    movl %eax, %edi
1204 ; X86-NEXT:    negl %edi
1205 ; X86-NEXT:    sbbl %ecx, %esi
1206 ; X86-NEXT:    andl %ecx, %esi
1207 ; X86-NEXT:    andl %eax, %edi
1208 ; X86-NEXT:    movl %edi, %eax
1209 ; X86-NEXT:    orl %esi, %eax
1210 ; X86-NEXT:    jne .LBB49_2
1211 ; X86-NEXT:  # %bb.1:
1212 ; X86-NEXT:    calll bar
1213 ; X86-NEXT:  .LBB49_2:
1214 ; X86-NEXT:    movl %edi, %eax
1215 ; X86-NEXT:    movl %esi, %edx
1216 ; X86-NEXT:    popl %esi
1217 ; X86-NEXT:    .cfi_def_cfa_offset 8
1218 ; X86-NEXT:    popl %edi
1219 ; X86-NEXT:    .cfi_def_cfa_offset 4
1220 ; X86-NEXT:    retl
1222 ; X64-LABEL: blsi64_branch:
1223 ; X64:       # %bb.0:
1224 ; X64-NEXT:    pushq %rbx
1225 ; X64-NEXT:    .cfi_def_cfa_offset 16
1226 ; X64-NEXT:    .cfi_offset %rbx, -16
1227 ; X64-NEXT:    blsiq %rdi, %rbx
1228 ; X64-NEXT:    jne .LBB49_2
1229 ; X64-NEXT:  # %bb.1:
1230 ; X64-NEXT:    callq bar
1231 ; X64-NEXT:  .LBB49_2:
1232 ; X64-NEXT:    movq %rbx, %rax
1233 ; X64-NEXT:    popq %rbx
1234 ; X64-NEXT:    .cfi_def_cfa_offset 8
1235 ; X64-NEXT:    retq
1236   %tmp = sub i64 0, %x
1237   %tmp2 = and i64 %x, %tmp
1238   %cmp = icmp eq i64 %tmp2, 0
1239   br i1 %cmp, label %1, label %2
1241   tail call void @bar()
1242   br label %2
1243   ret i64 %tmp2
1246 declare void @bar()
1248 define void @pr42118_i32(i32 %x) {
1249 ; X86-LABEL: pr42118_i32:
1250 ; X86:       # %bb.0:
1251 ; X86-NEXT:    blsrl {{[0-9]+}}(%esp), %eax
1252 ; X86-NEXT:    jne .LBB50_1
1253 ; X86-NEXT:  # %bb.2:
1254 ; X86-NEXT:    jmp bar # TAILCALL
1255 ; X86-NEXT:  .LBB50_1:
1256 ; X86-NEXT:    retl
1258 ; X64-LABEL: pr42118_i32:
1259 ; X64:       # %bb.0:
1260 ; X64-NEXT:    blsrl %edi, %eax
1261 ; X64-NEXT:    jne .LBB50_1
1262 ; X64-NEXT:  # %bb.2:
1263 ; X64-NEXT:    jmp bar # TAILCALL
1264 ; X64-NEXT:  .LBB50_1:
1265 ; X64-NEXT:    retq
1266   %tmp = sub i32 0, %x
1267   %tmp1 = and i32 %tmp, %x
1268   %cmp = icmp eq i32 %tmp1, %x
1269   br i1 %cmp, label %1, label %2
1271   tail call void @bar()
1272   br label %2
1274   ret void
1277 define void @pr42118_i64(i64 %x) {
1278 ; X86-LABEL: pr42118_i64:
1279 ; X86:       # %bb.0:
1280 ; X86-NEXT:    pushl %esi
1281 ; X86-NEXT:    .cfi_def_cfa_offset 8
1282 ; X86-NEXT:    .cfi_offset %esi, -8
1283 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1284 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1285 ; X86-NEXT:    movl %eax, %edx
1286 ; X86-NEXT:    addl $-1, %edx
1287 ; X86-NEXT:    movl %ecx, %esi
1288 ; X86-NEXT:    adcl $-1, %esi
1289 ; X86-NEXT:    andl %eax, %edx
1290 ; X86-NEXT:    andl %ecx, %esi
1291 ; X86-NEXT:    orl %edx, %esi
1292 ; X86-NEXT:    jne .LBB51_1
1293 ; X86-NEXT:  # %bb.2:
1294 ; X86-NEXT:    popl %esi
1295 ; X86-NEXT:    .cfi_def_cfa_offset 4
1296 ; X86-NEXT:    jmp bar # TAILCALL
1297 ; X86-NEXT:  .LBB51_1:
1298 ; X86-NEXT:    .cfi_def_cfa_offset 8
1299 ; X86-NEXT:    popl %esi
1300 ; X86-NEXT:    .cfi_def_cfa_offset 4
1301 ; X86-NEXT:    retl
1303 ; X64-LABEL: pr42118_i64:
1304 ; X64:       # %bb.0:
1305 ; X64-NEXT:    blsrq %rdi, %rax
1306 ; X64-NEXT:    jne .LBB51_1
1307 ; X64-NEXT:  # %bb.2:
1308 ; X64-NEXT:    jmp bar # TAILCALL
1309 ; X64-NEXT:  .LBB51_1:
1310 ; X64-NEXT:    retq
1311   %tmp = sub i64 0, %x
1312   %tmp1 = and i64 %tmp, %x
1313   %cmp = icmp eq i64 %tmp1, %x
1314   br i1 %cmp, label %1, label %2
1316   tail call void @bar()
1317   br label %2
1319   ret void
1322 define i32 @blsi_cflag_32(i32 %x, i32 %y) nounwind {
1323 ; X86-LABEL: blsi_cflag_32:
1324 ; X86:       # %bb.0:
1325 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1326 ; X86-NEXT:    testl %eax, %eax
1327 ; X86-NEXT:    jne .LBB52_1
1328 ; X86-NEXT:  # %bb.2:
1329 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1330 ; X86-NEXT:    retl
1331 ; X86-NEXT:  .LBB52_1:
1332 ; X86-NEXT:    blsil %eax, %eax
1333 ; X86-NEXT:    retl
1335 ; X64-LABEL: blsi_cflag_32:
1336 ; X64:       # %bb.0:
1337 ; X64-NEXT:    blsil %edi, %eax
1338 ; X64-NEXT:    cmovael %esi, %eax
1339 ; X64-NEXT:    retq
1340   %tobool = icmp eq i32 %x, 0
1341   %sub = sub nsw i32 0, %x
1342   %and = and i32 %sub, %x
1343   %cond = select i1 %tobool, i32 %y, i32 %and
1344   ret i32 %cond
1347 define i64 @blsi_cflag_64(i64 %x, i64 %y) nounwind {
1348 ; X86-LABEL: blsi_cflag_64:
1349 ; X86:       # %bb.0:
1350 ; X86-NEXT:    pushl %edi
1351 ; X86-NEXT:    pushl %esi
1352 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1353 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1354 ; X86-NEXT:    xorl %edx, %edx
1355 ; X86-NEXT:    movl %ecx, %eax
1356 ; X86-NEXT:    negl %eax
1357 ; X86-NEXT:    sbbl %esi, %edx
1358 ; X86-NEXT:    movl %ecx, %edi
1359 ; X86-NEXT:    orl %esi, %edi
1360 ; X86-NEXT:    jne .LBB53_1
1361 ; X86-NEXT:  # %bb.2:
1362 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1363 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1364 ; X86-NEXT:    jmp .LBB53_3
1365 ; X86-NEXT:  .LBB53_1:
1366 ; X86-NEXT:    andl %esi, %edx
1367 ; X86-NEXT:    andl %ecx, %eax
1368 ; X86-NEXT:  .LBB53_3:
1369 ; X86-NEXT:    popl %esi
1370 ; X86-NEXT:    popl %edi
1371 ; X86-NEXT:    retl
1373 ; X64-LABEL: blsi_cflag_64:
1374 ; X64:       # %bb.0:
1375 ; X64-NEXT:    blsiq %rdi, %rax
1376 ; X64-NEXT:    cmovaeq %rsi, %rax
1377 ; X64-NEXT:    retq
1378   %tobool = icmp eq i64 %x, 0
1379   %sub = sub nsw i64 0, %x
1380   %and = and i64 %sub, %x
1381   %cond = select i1 %tobool, i64 %y, i64 %and
1382   ret i64 %cond