Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / X86 / tbm_patterns.ll
blobf7bfb5bec8c9cadd88b557aefaa9877df22e3a6f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+tbm < %s | FileCheck %s
4 ; TODO - Patterns fail to fold with ZF flags and prevents TBM instruction selection.
6 define i32 @test_x86_tbm_bextri_u32(i32 %a) nounwind {
7 ; CHECK-LABEL: test_x86_tbm_bextri_u32:
8 ; CHECK:       # %bb.0:
9 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
10 ; CHECK-NEXT:    retq
11   %t0 = lshr i32 %a, 4
12   %t1 = and i32 %t0, 4095
13   ret i32 %t1
16 ; Make sure we still use AH subreg trick for extracting bits 15:8
17 define i32 @test_x86_tbm_bextri_u32_subreg(i32 %a) nounwind {
18 ; CHECK-LABEL: test_x86_tbm_bextri_u32_subreg:
19 ; CHECK:       # %bb.0:
20 ; CHECK-NEXT:    movl %edi, %eax
21 ; CHECK-NEXT:    movzbl %ah, %eax
22 ; CHECK-NEXT:    retq
23   %t0 = lshr i32 %a, 8
24   %t1 = and i32 %t0, 255
25   ret i32 %t1
28 define i32 @test_x86_tbm_bextri_u32_m(i32* nocapture %a) nounwind {
29 ; CHECK-LABEL: test_x86_tbm_bextri_u32_m:
30 ; CHECK:       # %bb.0:
31 ; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
32 ; CHECK-NEXT:    retq
33   %t0 = load i32, i32* %a
34   %t1 = lshr i32 %t0, 4
35   %t2 = and i32 %t1, 4095
36   ret i32 %t2
39 define i32 @test_x86_tbm_bextri_u32_z(i32 %a, i32 %b) nounwind {
40 ; CHECK-LABEL: test_x86_tbm_bextri_u32_z:
41 ; CHECK:       # %bb.0:
42 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
43 ; CHECK-NEXT:    cmovel %esi, %eax
44 ; CHECK-NEXT:    retq
45   %t0 = lshr i32 %a, 4
46   %t1 = and i32 %t0, 4095
47   %t2 = icmp eq i32 %t1, 0
48   %t3 = select i1 %t2, i32 %b, i32 %t1
49   ret i32 %t3
52 define i32 @test_x86_tbm_bextri_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
53 ; CHECK-LABEL: test_x86_tbm_bextri_u32_z2:
54 ; CHECK:       # %bb.0:
55 ; CHECK-NEXT:    movl %esi, %eax
56 ; CHECK-NEXT:    bextrl $3076, %edi, %ecx # imm = 0xC04
57 ; CHECK-NEXT:    cmovnel %edx, %eax
58 ; CHECK-NEXT:    retq
59   %t0 = lshr i32 %a, 4
60   %t1 = and i32 %t0, 4095
61   %t2 = icmp eq i32 %t1, 0
62   %t3 = select i1 %t2, i32 %b, i32 %c
63   ret i32 %t3
66 define i64 @test_x86_tbm_bextri_u64(i64 %a) nounwind {
67 ; CHECK-LABEL: test_x86_tbm_bextri_u64:
68 ; CHECK:       # %bb.0:
69 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
70 ; CHECK-NEXT:    retq
71   %t0 = lshr i64 %a, 4
72   %t1 = and i64 %t0, 4095
73   ret i64 %t1
76 ; Make sure we still use AH subreg trick for extracting bits 15:8
77 define i64 @test_x86_tbm_bextri_u64_subreg(i64 %a) nounwind {
78 ; CHECK-LABEL: test_x86_tbm_bextri_u64_subreg:
79 ; CHECK:       # %bb.0:
80 ; CHECK-NEXT:    movq %rdi, %rax
81 ; CHECK-NEXT:    movzbl %ah, %eax
82 ; CHECK-NEXT:    retq
83   %t0 = lshr i64 %a, 8
84   %t1 = and i64 %t0, 255
85   ret i64 %t1
88 define i64 @test_x86_tbm_bextri_u64_m(i64* nocapture %a) nounwind {
89 ; CHECK-LABEL: test_x86_tbm_bextri_u64_m:
90 ; CHECK:       # %bb.0:
91 ; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
92 ; CHECK-NEXT:    retq
93   %t0 = load i64, i64* %a
94   %t1 = lshr i64 %t0, 4
95   %t2 = and i64 %t1, 4095
96   ret i64 %t2
99 define i64 @test_x86_tbm_bextri_u64_z(i64 %a, i64 %b) nounwind {
100 ; CHECK-LABEL: test_x86_tbm_bextri_u64_z:
101 ; CHECK:       # %bb.0:
102 ; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
103 ; CHECK-NEXT:    cmoveq %rsi, %rax
104 ; CHECK-NEXT:    retq
105   %t0 = lshr i64 %a, 4
106   %t1 = and i64 %t0, 4095
107   %t2 = icmp eq i64 %t1, 0
108   %t3 = select i1 %t2, i64 %b, i64 %t1
109   ret i64 %t3
112 define i64 @test_x86_tbm_bextri_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
113 ; CHECK-LABEL: test_x86_tbm_bextri_u64_z2:
114 ; CHECK:       # %bb.0:
115 ; CHECK-NEXT:    movq %rsi, %rax
116 ; CHECK-NEXT:    bextrl $3076, %edi, %ecx # imm = 0xC04
117 ; CHECK-NEXT:    cmovneq %rdx, %rax
118 ; CHECK-NEXT:    retq
119   %t0 = lshr i64 %a, 4
120   %t1 = and i64 %t0, 4095
121   %t2 = icmp eq i64 %t1, 0
122   %t3 = select i1 %t2, i64 %b, i64 %c
123   ret i64 %t3
126 define i32 @test_x86_tbm_blcfill_u32(i32 %a) nounwind {
127 ; CHECK-LABEL: test_x86_tbm_blcfill_u32:
128 ; CHECK:       # %bb.0:
129 ; CHECK-NEXT:    blcfilll %edi, %eax
130 ; CHECK-NEXT:    retq
131   %t0 = add i32 %a, 1
132   %t1 = and i32 %t0, %a
133   ret i32 %t1
136 define i32 @test_x86_tbm_blcfill_u32_z(i32 %a, i32 %b) nounwind {
137 ; CHECK-LABEL: test_x86_tbm_blcfill_u32_z:
138 ; CHECK:       # %bb.0:
139 ; CHECK-NEXT:    blcfilll %edi, %eax
140 ; CHECK-NEXT:    cmovel %esi, %eax
141 ; CHECK-NEXT:    retq
142   %t0 = add i32 %a, 1
143   %t1 = and i32 %t0, %a
144   %t2 = icmp eq i32 %t1, 0
145   %t3 = select i1 %t2, i32 %b, i32 %t1
146   ret i32 %t3
149 define i32 @test_x86_tbm_blcfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
150 ; CHECK-LABEL: test_x86_tbm_blcfill_u32_z2:
151 ; CHECK:       # %bb.0:
152 ; CHECK-NEXT:    movl %esi, %eax
153 ; CHECK-NEXT:    blcfilll %edi, %ecx
154 ; CHECK-NEXT:    cmovnel %edx, %eax
155 ; CHECK-NEXT:    retq
156   %t0 = add i32 %a, 1
157   %t1 = and i32 %t0, %a
158   %t2 = icmp eq i32 %t1, 0
159   %t3 = select i1 %t2, i32 %b, i32 %c
160   ret i32 %t3
163 define i64 @test_x86_tbm_blcfill_u64(i64 %a) nounwind {
164 ; CHECK-LABEL: test_x86_tbm_blcfill_u64:
165 ; CHECK:       # %bb.0:
166 ; CHECK-NEXT:    blcfillq %rdi, %rax
167 ; CHECK-NEXT:    retq
168   %t0 = add i64 %a, 1
169   %t1 = and i64 %t0, %a
170   ret i64 %t1
173 define i64 @test_x86_tbm_blcfill_u64_z(i64 %a, i64 %b) nounwind {
174 ; CHECK-LABEL: test_x86_tbm_blcfill_u64_z:
175 ; CHECK:       # %bb.0:
176 ; CHECK-NEXT:    blcfillq %rdi, %rax
177 ; CHECK-NEXT:    cmoveq %rsi, %rax
178 ; CHECK-NEXT:    retq
179   %t0 = add i64 %a, 1
180   %t1 = and i64 %t0, %a
181   %t2 = icmp eq i64 %t1, 0
182   %t3 = select i1 %t2, i64 %b, i64 %t1
183   ret i64 %t3
186 define i64 @test_x86_tbm_blcfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
187 ; CHECK-LABEL: test_x86_tbm_blcfill_u64_z2:
188 ; CHECK:       # %bb.0:
189 ; CHECK-NEXT:    movq %rsi, %rax
190 ; CHECK-NEXT:    blcfillq %rdi, %rcx
191 ; CHECK-NEXT:    cmovneq %rdx, %rax
192 ; CHECK-NEXT:    retq
193   %t0 = add i64 %a, 1
194   %t1 = and i64 %t0, %a
195   %t2 = icmp eq i64 %t1, 0
196   %t3 = select i1 %t2, i64 %b, i64 %c
197   ret i64 %t3
200 define i32 @test_x86_tbm_blci_u32(i32 %a) nounwind {
201 ; CHECK-LABEL: test_x86_tbm_blci_u32:
202 ; CHECK:       # %bb.0:
203 ; CHECK-NEXT:    blcil %edi, %eax
204 ; CHECK-NEXT:    retq
205   %t0 = add i32 1, %a
206   %t1 = xor i32 %t0, -1
207   %t2 = or i32 %t1, %a
208   ret i32 %t2
211 define i32 @test_x86_tbm_blci_u32_z(i32 %a, i32 %b) nounwind {
212 ; CHECK-LABEL: test_x86_tbm_blci_u32_z:
213 ; CHECK:       # %bb.0:
214 ; CHECK-NEXT:    blcil %edi, %eax
215 ; CHECK-NEXT:    cmovel %esi, %eax
216 ; CHECK-NEXT:    retq
217   %t0 = add i32 1, %a
218   %t1 = xor i32 %t0, -1
219   %t2 = or i32 %t1, %a
220   %t3 = icmp eq i32 %t2, 0
221   %t4 = select i1 %t3, i32 %b, i32 %t2
222   ret i32 %t4
225 define i32 @test_x86_tbm_blci_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
226 ; CHECK-LABEL: test_x86_tbm_blci_u32_z2:
227 ; CHECK:       # %bb.0:
228 ; CHECK-NEXT:    movl %esi, %eax
229 ; CHECK-NEXT:    blcil %edi, %ecx
230 ; CHECK-NEXT:    cmovnel %edx, %eax
231 ; CHECK-NEXT:    retq
232   %t0 = add i32 1, %a
233   %t1 = xor i32 %t0, -1
234   %t2 = or i32 %t1, %a
235   %t3 = icmp eq i32 %t2, 0
236   %t4 = select i1 %t3, i32 %b, i32 %c
237   ret i32 %t4
240 define i64 @test_x86_tbm_blci_u64(i64 %a) nounwind {
241 ; CHECK-LABEL: test_x86_tbm_blci_u64:
242 ; CHECK:       # %bb.0:
243 ; CHECK-NEXT:    blciq %rdi, %rax
244 ; CHECK-NEXT:    retq
245   %t0 = add i64 1, %a
246   %t1 = xor i64 %t0, -1
247   %t2 = or i64 %t1, %a
248   ret i64 %t2
251 define i64 @test_x86_tbm_blci_u64_z(i64 %a, i64 %b) nounwind {
252 ; CHECK-LABEL: test_x86_tbm_blci_u64_z:
253 ; CHECK:       # %bb.0:
254 ; CHECK-NEXT:    blciq %rdi, %rax
255 ; CHECK-NEXT:    cmoveq %rsi, %rax
256 ; CHECK-NEXT:    retq
257   %t0 = add i64 1, %a
258   %t1 = xor i64 %t0, -1
259   %t2 = or i64 %t1, %a
260   %t3 = icmp eq i64 %t2, 0
261   %t4 = select i1 %t3, i64 %b, i64 %t2
262   ret i64 %t4
265 define i64 @test_x86_tbm_blci_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
266 ; CHECK-LABEL: test_x86_tbm_blci_u64_z2:
267 ; CHECK:       # %bb.0:
268 ; CHECK-NEXT:    movq %rsi, %rax
269 ; CHECK-NEXT:    blciq %rdi, %rcx
270 ; CHECK-NEXT:    cmovneq %rdx, %rax
271 ; CHECK-NEXT:    retq
272   %t0 = add i64 1, %a
273   %t1 = xor i64 %t0, -1
274   %t2 = or i64 %t1, %a
275   %t3 = icmp eq i64 %t2, 0
276   %t4 = select i1 %t3, i64 %b, i64 %c
277   ret i64 %t4
280 define i32 @test_x86_tbm_blci_u32_b(i32 %a) nounwind {
281 ; CHECK-LABEL: test_x86_tbm_blci_u32_b:
282 ; CHECK:       # %bb.0:
283 ; CHECK-NEXT:    blcil %edi, %eax
284 ; CHECK-NEXT:    retq
285   %t0 = sub i32 -2, %a
286   %t1 = or i32 %t0, %a
287   ret i32 %t1
290 define i64 @test_x86_tbm_blci_u64_b(i64 %a) nounwind {
291 ; CHECK-LABEL: test_x86_tbm_blci_u64_b:
292 ; CHECK:       # %bb.0:
293 ; CHECK-NEXT:    blciq %rdi, %rax
294 ; CHECK-NEXT:    retq
295   %t0 = sub i64 -2, %a
296   %t1 = or i64 %t0, %a
297   ret i64 %t1
300 define i32 @test_x86_tbm_blcic_u32(i32 %a) nounwind {
301 ; CHECK-LABEL: test_x86_tbm_blcic_u32:
302 ; CHECK:       # %bb.0:
303 ; CHECK-NEXT:    blcicl %edi, %eax
304 ; CHECK-NEXT:    retq
305   %t0 = xor i32 %a, -1
306   %t1 = add i32 %a, 1
307   %t2 = and i32 %t1, %t0
308   ret i32 %t2
311 define i32 @test_x86_tbm_blcic_u32_z(i32 %a, i32 %b) nounwind {
312 ; CHECK-LABEL: test_x86_tbm_blcic_u32_z:
313 ; CHECK:       # %bb.0:
314 ; CHECK-NEXT:    blcicl %edi, %eax
315 ; CHECK-NEXT:    cmovel %esi, %eax
316 ; CHECK-NEXT:    retq
317   %t0 = xor i32 %a, -1
318   %t1 = add i32 %a, 1
319   %t2 = and i32 %t1, %t0
320   %t3 = icmp eq i32 %t2, 0
321   %t4 = select i1 %t3, i32 %b, i32 %t2
322   ret i32 %t4
325 define i32 @test_x86_tbm_blcic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
326 ; CHECK-LABEL: test_x86_tbm_blcic_u32_z2:
327 ; CHECK:       # %bb.0:
328 ; CHECK-NEXT:    movl %esi, %eax
329 ; CHECK-NEXT:    blcicl %edi, %ecx
330 ; CHECK-NEXT:    cmovnel %edx, %eax
331 ; CHECK-NEXT:    retq
332   %t0 = xor i32 %a, -1
333   %t1 = add i32 %a, 1
334   %t2 = and i32 %t1, %t0
335   %t3 = icmp eq i32 %t2, 0
336   %t4 = select i1 %t3, i32 %b, i32 %c
337   ret i32 %t4
340 define i64 @test_x86_tbm_blcic_u64(i64 %a) nounwind {
341 ; CHECK-LABEL: test_x86_tbm_blcic_u64:
342 ; CHECK:       # %bb.0:
343 ; CHECK-NEXT:    blcicq %rdi, %rax
344 ; CHECK-NEXT:    retq
345   %t0 = xor i64 %a, -1
346   %t1 = add i64 %a, 1
347   %t2 = and i64 %t1, %t0
348   ret i64 %t2
351 define i64 @test_x86_tbm_blcic_u64_z(i64 %a, i64 %b) nounwind {
352 ; CHECK-LABEL: test_x86_tbm_blcic_u64_z:
353 ; CHECK:       # %bb.0:
354 ; CHECK-NEXT:    blcicq %rdi, %rax
355 ; CHECK-NEXT:    cmoveq %rsi, %rax
356 ; CHECK-NEXT:    retq
357   %t0 = xor i64 %a, -1
358   %t1 = add i64 %a, 1
359   %t2 = and i64 %t1, %t0
360   %t3 = icmp eq i64 %t2, 0
361   %t4 = select i1 %t3, i64 %b, i64 %t2
362   ret i64 %t4
365 define i64 @test_x86_tbm_blcic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
366 ; CHECK-LABEL: test_x86_tbm_blcic_u64_z2:
367 ; CHECK:       # %bb.0:
368 ; CHECK-NEXT:    movq %rsi, %rax
369 ; CHECK-NEXT:    blcicq %rdi, %rcx
370 ; CHECK-NEXT:    cmovneq %rdx, %rax
371 ; CHECK-NEXT:    retq
372   %t0 = xor i64 %a, -1
373   %t1 = add i64 %a, 1
374   %t2 = and i64 %t1, %t0
375   %t3 = icmp eq i64 %t2, 0
376   %t4 = select i1 %t3, i64 %b, i64 %c
377   ret i64 %t4
380 define i32 @test_x86_tbm_blcmsk_u32(i32 %a) nounwind {
381 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32:
382 ; CHECK:       # %bb.0:
383 ; CHECK-NEXT:    blcmskl %edi, %eax
384 ; CHECK-NEXT:    retq
385   %t0 = add i32 %a, 1
386   %t1 = xor i32 %t0, %a
387   ret i32 %t1
390 define i32 @test_x86_tbm_blcmsk_u32_z(i32 %a, i32 %b) nounwind {
391 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z:
392 ; CHECK:       # %bb.0:
393 ; CHECK-NEXT:    blcmskl %edi, %eax
394 ; CHECK-NEXT:    cmovel %esi, %eax
395 ; CHECK-NEXT:    retq
396   %t0 = add i32 %a, 1
397   %t1 = xor i32 %t0, %a
398   %t2 = icmp eq i32 %t1, 0
399   %t3 = select i1 %t2, i32 %b, i32 %t1
400   ret i32 %t3
403 define i32 @test_x86_tbm_blcmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
404 ; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z2:
405 ; CHECK:       # %bb.0:
406 ; CHECK-NEXT:    movl %esi, %eax
407 ; CHECK-NEXT:    blcmskl %edi, %ecx
408 ; CHECK-NEXT:    cmovnel %edx, %eax
409 ; CHECK-NEXT:    retq
410   %t0 = add i32 %a, 1
411   %t1 = xor i32 %t0, %a
412   %t2 = icmp eq i32 %t1, 0
413   %t3 = select i1 %t2, i32 %b, i32 %c
414   ret i32 %t3
417 define i64 @test_x86_tbm_blcmsk_u64(i64 %a) nounwind {
418 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64:
419 ; CHECK:       # %bb.0:
420 ; CHECK-NEXT:    blcmskq %rdi, %rax
421 ; CHECK-NEXT:    retq
422   %t0 = add i64 %a, 1
423   %t1 = xor i64 %t0, %a
424   ret i64 %t1
427 define i64 @test_x86_tbm_blcmsk_u64_z(i64 %a, i64 %b) nounwind {
428 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z:
429 ; CHECK:       # %bb.0:
430 ; CHECK-NEXT:    blcmskq %rdi, %rax
431 ; CHECK-NEXT:    cmoveq %rsi, %rax
432 ; CHECK-NEXT:    retq
433   %t0 = add i64 %a, 1
434   %t1 = xor i64 %t0, %a
435   %t2 = icmp eq i64 %t1, 0
436   %t3 = select i1 %t2, i64 %b, i64 %t1
437   ret i64 %t3
440 define i64 @test_x86_tbm_blcmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
441 ; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z2:
442 ; CHECK:       # %bb.0:
443 ; CHECK-NEXT:    movq %rsi, %rax
444 ; CHECK-NEXT:    blcmskq %rdi, %rcx
445 ; CHECK-NEXT:    cmovneq %rdx, %rax
446 ; CHECK-NEXT:    retq
447   %t0 = add i64 %a, 1
448   %t1 = xor i64 %t0, %a
449   %t2 = icmp eq i64 %t1, 0
450   %t3 = select i1 %t2, i64 %b, i64 %c
451   ret i64 %t3
454 define i32 @test_x86_tbm_blcs_u32(i32 %a) nounwind {
455 ; CHECK-LABEL: test_x86_tbm_blcs_u32:
456 ; CHECK:       # %bb.0:
457 ; CHECK-NEXT:    blcsl %edi, %eax
458 ; CHECK-NEXT:    retq
459   %t0 = add i32 %a, 1
460   %t1 = or i32 %t0, %a
461   ret i32 %t1
464 define i32 @test_x86_tbm_blcs_u32_z(i32 %a, i32 %b) nounwind {
465 ; CHECK-LABEL: test_x86_tbm_blcs_u32_z:
466 ; CHECK:       # %bb.0:
467 ; CHECK-NEXT:    blcsl %edi, %eax
468 ; CHECK-NEXT:    cmovel %esi, %eax
469 ; CHECK-NEXT:    retq
470   %t0 = add i32 %a, 1
471   %t1 = or i32 %t0, %a
472   %t2 = icmp eq i32 %t1, 0
473   %t3 = select i1 %t2, i32 %b, i32 %t1
474   ret i32 %t3
477 define i32 @test_x86_tbm_blcs_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
478 ; CHECK-LABEL: test_x86_tbm_blcs_u32_z2:
479 ; CHECK:       # %bb.0:
480 ; CHECK-NEXT:    movl %esi, %eax
481 ; CHECK-NEXT:    blcsl %edi, %ecx
482 ; CHECK-NEXT:    cmovnel %edx, %eax
483 ; CHECK-NEXT:    retq
484   %t0 = add i32 %a, 1
485   %t1 = or i32 %t0, %a
486   %t2 = icmp eq i32 %t1, 0
487   %t3 = select i1 %t2, i32 %b, i32 %c
488   ret i32 %t3
491 define i64 @test_x86_tbm_blcs_u64(i64 %a) nounwind {
492 ; CHECK-LABEL: test_x86_tbm_blcs_u64:
493 ; CHECK:       # %bb.0:
494 ; CHECK-NEXT:    blcsq %rdi, %rax
495 ; CHECK-NEXT:    retq
496   %t0 = add i64 %a, 1
497   %t1 = or i64 %t0, %a
498   ret i64 %t1
501 define i64 @test_x86_tbm_blcs_u64_z(i64 %a, i64 %b) nounwind {
502 ; CHECK-LABEL: test_x86_tbm_blcs_u64_z:
503 ; CHECK:       # %bb.0:
504 ; CHECK-NEXT:    blcsq %rdi, %rax
505 ; CHECK-NEXT:    cmoveq %rsi, %rax
506 ; CHECK-NEXT:    retq
507   %t0 = add i64 %a, 1
508   %t1 = or i64 %t0, %a
509   %t2 = icmp eq i64 %t1, 0
510   %t3 = select i1 %t2, i64 %b, i64 %t1
511   ret i64 %t3
514 define i64 @test_x86_tbm_blcs_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
515 ; CHECK-LABEL: test_x86_tbm_blcs_u64_z2:
516 ; CHECK:       # %bb.0:
517 ; CHECK-NEXT:    movq %rsi, %rax
518 ; CHECK-NEXT:    blcsq %rdi, %rcx
519 ; CHECK-NEXT:    cmovneq %rdx, %rax
520 ; CHECK-NEXT:    retq
521   %t0 = add i64 %a, 1
522   %t1 = or i64 %t0, %a
523   %t2 = icmp eq i64 %t1, 0
524   %t3 = select i1 %t2, i64 %b, i64 %c
525   ret i64 %t3
528 define i32 @test_x86_tbm_blsfill_u32(i32 %a) nounwind {
529 ; CHECK-LABEL: test_x86_tbm_blsfill_u32:
530 ; CHECK:       # %bb.0:
531 ; CHECK-NEXT:    blsfilll %edi, %eax
532 ; CHECK-NEXT:    retq
533   %t0 = add i32 %a, -1
534   %t1 = or i32 %t0, %a
535   ret i32 %t1
538 define i32 @test_x86_tbm_blsfill_u32_z(i32 %a, i32 %b) nounwind {
539 ; CHECK-LABEL: test_x86_tbm_blsfill_u32_z:
540 ; CHECK:       # %bb.0:
541 ; CHECK-NEXT:    blsfilll %edi, %eax
542 ; CHECK-NEXT:    cmovel %esi, %eax
543 ; CHECK-NEXT:    retq
544   %t0 = add i32 %a, -1
545   %t1 = or i32 %t0, %a
546   %t2 = icmp eq i32 %t1, 0
547   %t3 = select i1 %t2, i32 %b, i32 %t1
548   ret i32 %t3
551 define i32 @test_x86_tbm_blsfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
552 ; CHECK-LABEL: test_x86_tbm_blsfill_u32_z2:
553 ; CHECK:       # %bb.0:
554 ; CHECK-NEXT:    movl %esi, %eax
555 ; CHECK-NEXT:    blsfilll %edi, %ecx
556 ; CHECK-NEXT:    cmovnel %edx, %eax
557 ; CHECK-NEXT:    retq
558   %t0 = add i32 %a, -1
559   %t1 = or i32 %t0, %a
560   %t2 = icmp eq i32 %t1, 0
561   %t3 = select i1 %t2, i32 %b, i32 %c
562   ret i32 %t3
565 define i64 @test_x86_tbm_blsfill_u64(i64 %a) nounwind {
566 ; CHECK-LABEL: test_x86_tbm_blsfill_u64:
567 ; CHECK:       # %bb.0:
568 ; CHECK-NEXT:    blsfillq %rdi, %rax
569 ; CHECK-NEXT:    retq
570   %t0 = add i64 %a, -1
571   %t1 = or i64 %t0, %a
572   ret i64 %t1
575 define i64 @test_x86_tbm_blsfill_u64_z(i64 %a, i64 %b) nounwind {
576 ; CHECK-LABEL: test_x86_tbm_blsfill_u64_z:
577 ; CHECK:       # %bb.0:
578 ; CHECK-NEXT:    blsfillq %rdi, %rax
579 ; CHECK-NEXT:    cmoveq %rsi, %rax
580 ; CHECK-NEXT:    retq
581   %t0 = add i64 %a, -1
582   %t1 = or i64 %t0, %a
583   %t2 = icmp eq i64 %t1, 0
584   %t3 = select i1 %t2, i64 %b, i64 %t1
585   ret i64 %t3
588 define i64 @test_x86_tbm_blsfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
589 ; CHECK-LABEL: test_x86_tbm_blsfill_u64_z2:
590 ; CHECK:       # %bb.0:
591 ; CHECK-NEXT:    movq %rsi, %rax
592 ; CHECK-NEXT:    blsfillq %rdi, %rcx
593 ; CHECK-NEXT:    cmovneq %rdx, %rax
594 ; CHECK-NEXT:    retq
595   %t0 = add i64 %a, -1
596   %t1 = or i64 %t0, %a
597   %t2 = icmp eq i64 %t1, 0
598   %t3 = select i1 %t2, i64 %b, i64 %c
599   ret i64 %t3
602 define i32 @test_x86_tbm_blsic_u32(i32 %a) nounwind {
603 ; CHECK-LABEL: test_x86_tbm_blsic_u32:
604 ; CHECK:       # %bb.0:
605 ; CHECK-NEXT:    blsicl %edi, %eax
606 ; CHECK-NEXT:    retq
607   %t0 = xor i32 %a, -1
608   %t1 = add i32 %a, -1
609   %t2 = or i32 %t0, %t1
610   ret i32 %t2
613 define i32 @test_x86_tbm_blsic_u32_z(i32 %a, i32 %b) nounwind {
614 ; CHECK-LABEL: test_x86_tbm_blsic_u32_z:
615 ; CHECK:       # %bb.0:
616 ; CHECK-NEXT:    blsicl %edi, %eax
617 ; CHECK-NEXT:    cmovel %esi, %eax
618 ; CHECK-NEXT:    retq
619   %t0 = xor i32 %a, -1
620   %t1 = add i32 %a, -1
621   %t2 = or i32 %t0, %t1
622   %t3 = icmp eq i32 %t2, 0
623   %t4 = select i1 %t3, i32 %b, i32 %t2
624   ret i32 %t4
627 define i32 @test_x86_tbm_blsic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
628 ; CHECK-LABEL: test_x86_tbm_blsic_u32_z2:
629 ; CHECK:       # %bb.0:
630 ; CHECK-NEXT:    movl %esi, %eax
631 ; CHECK-NEXT:    blsicl %edi, %ecx
632 ; CHECK-NEXT:    cmovnel %edx, %eax
633 ; CHECK-NEXT:    retq
634   %t0 = xor i32 %a, -1
635   %t1 = add i32 %a, -1
636   %t2 = or i32 %t0, %t1
637   %t3 = icmp eq i32 %t2, 0
638   %t4 = select i1 %t3, i32 %b, i32 %c
639   ret i32 %t4
642 define i64 @test_x86_tbm_blsic_u64(i64 %a) nounwind {
643 ; CHECK-LABEL: test_x86_tbm_blsic_u64:
644 ; CHECK:       # %bb.0:
645 ; CHECK-NEXT:    blsicq %rdi, %rax
646 ; CHECK-NEXT:    retq
647   %t0 = xor i64 %a, -1
648   %t1 = add i64 %a, -1
649   %t2 = or i64 %t0, %t1
650   ret i64 %t2
653 define i64 @test_x86_tbm_blsic_u64_z(i64 %a, i64 %b) nounwind {
654 ; CHECK-LABEL: test_x86_tbm_blsic_u64_z:
655 ; CHECK:       # %bb.0:
656 ; CHECK-NEXT:    blsicq %rdi, %rax
657 ; CHECK-NEXT:    cmoveq %rsi, %rax
658 ; CHECK-NEXT:    retq
659   %t0 = xor i64 %a, -1
660   %t1 = add i64 %a, -1
661   %t2 = or i64 %t0, %t1
662   %t3 = icmp eq i64 %t2, 0
663   %t4 = select i1 %t3, i64 %b, i64 %t2
664   ret i64 %t4
667 define i64 @test_x86_tbm_blsic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
668 ; CHECK-LABEL: test_x86_tbm_blsic_u64_z2:
669 ; CHECK:       # %bb.0:
670 ; CHECK-NEXT:    movq %rsi, %rax
671 ; CHECK-NEXT:    blsicq %rdi, %rcx
672 ; CHECK-NEXT:    cmovneq %rdx, %rax
673 ; CHECK-NEXT:    retq
674   %t0 = xor i64 %a, -1
675   %t1 = add i64 %a, -1
676   %t2 = or i64 %t0, %t1
677   %t3 = icmp eq i64 %t2, 0
678   %t4 = select i1 %t3, i64 %b, i64 %c
679   ret i64 %t4
682 define i32 @test_x86_tbm_t1mskc_u32(i32 %a) nounwind {
683 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32:
684 ; CHECK:       # %bb.0:
685 ; CHECK-NEXT:    t1mskcl %edi, %eax
686 ; CHECK-NEXT:    retq
687   %t0 = xor i32 %a, -1
688   %t1 = add i32 %a, 1
689   %t2 = or i32 %t0, %t1
690   ret i32 %t2
693 define i32 @test_x86_tbm_t1mskc_u32_z(i32 %a, i32 %b) nounwind {
694 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z:
695 ; CHECK:       # %bb.0:
696 ; CHECK-NEXT:    t1mskcl %edi, %eax
697 ; CHECK-NEXT:    cmovel %esi, %eax
698 ; CHECK-NEXT:    retq
699   %t0 = xor i32 %a, -1
700   %t1 = add i32 %a, 1
701   %t2 = or i32 %t0, %t1
702   %t3 = icmp eq i32 %t2, 0
703   %t4 = select i1 %t3, i32 %b, i32 %t2
704   ret i32 %t4
707 define i32 @test_x86_tbm_t1mskc_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
708 ; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z2:
709 ; CHECK:       # %bb.0:
710 ; CHECK-NEXT:    movl %esi, %eax
711 ; CHECK-NEXT:    t1mskcl %edi, %ecx
712 ; CHECK-NEXT:    cmovnel %edx, %eax
713 ; CHECK-NEXT:    retq
714   %t0 = xor i32 %a, -1
715   %t1 = add i32 %a, 1
716   %t2 = or i32 %t0, %t1
717   %t3 = icmp eq i32 %t2, 0
718   %t4 = select i1 %t3, i32 %b, i32 %c
719   ret i32 %t4
722 define i64 @test_x86_tbm_t1mskc_u64(i64 %a) nounwind {
723 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64:
724 ; CHECK:       # %bb.0:
725 ; CHECK-NEXT:    t1mskcq %rdi, %rax
726 ; CHECK-NEXT:    retq
727   %t0 = xor i64 %a, -1
728   %t1 = add i64 %a, 1
729   %t2 = or i64 %t0, %t1
730   ret i64 %t2
733 define i64 @test_x86_tbm_t1mskc_u64_z(i64 %a, i64 %b) nounwind {
734 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z:
735 ; CHECK:       # %bb.0:
736 ; CHECK-NEXT:    t1mskcq %rdi, %rax
737 ; CHECK-NEXT:    cmoveq %rsi, %rax
738 ; CHECK-NEXT:    retq
739   %t0 = xor i64 %a, -1
740   %t1 = add i64 %a, 1
741   %t2 = or i64 %t0, %t1
742   %t3 = icmp eq i64 %t2, 0
743   %t4 = select i1 %t3, i64 %b, i64 %t2
744   ret i64 %t4
747 define i64 @test_x86_tbm_t1mskc_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
748 ; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z2:
749 ; CHECK:       # %bb.0:
750 ; CHECK-NEXT:    movq %rsi, %rax
751 ; CHECK-NEXT:    t1mskcq %rdi, %rcx
752 ; CHECK-NEXT:    cmovneq %rdx, %rax
753 ; CHECK-NEXT:    retq
754   %t0 = xor i64 %a, -1
755   %t1 = add i64 %a, 1
756   %t2 = or i64 %t0, %t1
757   %t3 = icmp eq i64 %t2, 0
758   %t4 = select i1 %t3, i64 %b, i64 %c
759   ret i64 %t4
762 define i32 @test_x86_tbm_tzmsk_u32(i32 %a) nounwind {
763 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32:
764 ; CHECK:       # %bb.0:
765 ; CHECK-NEXT:    tzmskl %edi, %eax
766 ; CHECK-NEXT:    retq
767   %t0 = xor i32 %a, -1
768   %t1 = add i32 %a, -1
769   %t2 = and i32 %t0, %t1
770   ret i32 %t2
773 define i32 @test_x86_tbm_tzmsk_u32_z(i32 %a, i32 %b) nounwind {
774 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z:
775 ; CHECK:       # %bb.0:
776 ; CHECK-NEXT:    tzmskl %edi, %eax
777 ; CHECK-NEXT:    cmovel %esi, %eax
778 ; CHECK-NEXT:    retq
779   %t0 = xor i32 %a, -1
780   %t1 = add i32 %a, -1
781   %t2 = and i32 %t0, %t1
782   %t3 = icmp eq i32 %t2, 0
783   %t4 = select i1 %t3, i32 %b, i32 %t2
784   ret i32 %t4
787 define i32 @test_x86_tbm_tzmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
788 ; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z2:
789 ; CHECK:       # %bb.0:
790 ; CHECK-NEXT:    movl %esi, %eax
791 ; CHECK-NEXT:    tzmskl %edi, %ecx
792 ; CHECK-NEXT:    cmovnel %edx, %eax
793 ; CHECK-NEXT:    retq
794   %t0 = xor i32 %a, -1
795   %t1 = add i32 %a, -1
796   %t2 = and i32 %t0, %t1
797   %t3 = icmp eq i32 %t2, 0
798   %t4 = select i1 %t3, i32 %b, i32 %c
799   ret i32 %t4
802 define i64 @test_x86_tbm_tzmsk_u64(i64 %a) nounwind {
803 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64:
804 ; CHECK:       # %bb.0:
805 ; CHECK-NEXT:    tzmskq %rdi, %rax
806 ; CHECK-NEXT:    retq
807   %t0 = xor i64 %a, -1
808   %t1 = add i64 %a, -1
809   %t2 = and i64 %t0, %t1
810   ret i64 %t2
813 define i64 @test_x86_tbm_tzmsk_u64_z(i64 %a, i64 %b) nounwind {
814 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z:
815 ; CHECK:       # %bb.0:
816 ; CHECK-NEXT:    tzmskq %rdi, %rax
817 ; CHECK-NEXT:    cmoveq %rsi, %rax
818 ; CHECK-NEXT:    retq
819   %t0 = xor i64 %a, -1
820   %t1 = add i64 %a, -1
821   %t2 = and i64 %t0, %t1
822   %t3 = icmp eq i64 %t2, 0
823   %t4 = select i1 %t3, i64 %b, i64 %t2
824   ret i64 %t4
827 define i64 @test_x86_tbm_tzmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
828 ; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z2:
829 ; CHECK:       # %bb.0:
830 ; CHECK-NEXT:    movq %rsi, %rax
831 ; CHECK-NEXT:    tzmskq %rdi, %rcx
832 ; CHECK-NEXT:    cmovneq %rdx, %rax
833 ; CHECK-NEXT:    retq
834   %t0 = xor i64 %a, -1
835   %t1 = add i64 %a, -1
836   %t2 = and i64 %t0, %t1
837   %t3 = icmp eq i64 %t2, 0
838   %t4 = select i1 %t3, i64 %b, i64 %c
839   ret i64 %t4
842 define i64 @test_and_large_constant_mask(i64 %x) {
843 ; CHECK-LABEL: test_and_large_constant_mask:
844 ; CHECK:       # %bb.0: # %entry
845 ; CHECK-NEXT:    bextrq $15872, %rdi, %rax # imm = 0x3E00
846 ; CHECK-NEXT:    retq
847 entry:
848   %and = and i64 %x, 4611686018427387903
849   ret i64 %and
852 define i64 @test_and_large_constant_mask_load(i64* %x) {
853 ; CHECK-LABEL: test_and_large_constant_mask_load:
854 ; CHECK:       # %bb.0: # %entry
855 ; CHECK-NEXT:    bextrq $15872, (%rdi), %rax # imm = 0x3E00
856 ; CHECK-NEXT:    retq
857 entry:
858   %x1 = load i64, i64* %x
859   %and = and i64 %x1, 4611686018427387903
860   ret i64 %and
863 ; Make sure the mask doesn't break our matching of blcic
864 define  i64 @masked_blcic(i64) {
865 ; CHECK-LABEL: masked_blcic:
866 ; CHECK:       # %bb.0:
867 ; CHECK-NEXT:    movzwl %di, %eax
868 ; CHECK-NEXT:    blcicl %eax, %eax
869 ; CHECK-NEXT:    retq
870   %2 = and i64 %0, 65535
871   %3 = xor i64 %2, -1
872   %4 = add nuw nsw i64 %2, 1
873   %5 = and i64 %4, %3
874   ret i64 %5