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
3
4; TODO - Patterns fail to fold with ZF flags and prevents TBM instruction selection.
5
6define 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
14}
15
16; Make sure we still use AH subreg trick for extracting bits 15:8
17define 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
26}
27
28define 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
37}
38
39define 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
50}
51
52define 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
64}
65
66define 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
74}
75
76; Make sure we still use AH subreg trick for extracting bits 15:8
77define 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
86}
87
88define 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
97}
98
99define 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
110}
111
112define 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
124}
125
126define 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
134}
135
136define 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
147}
148
149define 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
161}
162
163define 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
171}
172
173define 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
184}
185
186define 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
198}
199
200define 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
209}
210
211define 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
223}
224
225define 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
238}
239
240define 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
249}
250
251define 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
263}
264
265define 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
278}
279
280define 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
288}
289
290define 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
298}
299
300define 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
309}
310
311define 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
323}
324
325define 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
338}
339
340define 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
349}
350
351define 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
363}
364
365define 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
378}
379
380define 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
388}
389
390define 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
401}
402
403define 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
415}
416
417define 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
425}
426
427define 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
438}
439
440define 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
452}
453
454define 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
462}
463
464define 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
475}
476
477define 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
489}
490
491define 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
499}
500
501define 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
512}
513
514define 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
526}
527
528define 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
536}
537
538define 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
549}
550
551define 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
563}
564
565define 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
573}
574
575define 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
586}
587
588define 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
600}
601
602define 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
611}
612
613define 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
625}
626
627define 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
640}
641
642define 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
651}
652
653define 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
665}
666
667define 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
680}
681
682define 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
691}
692
693define 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
705}
706
707define 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
720}
721
722define 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
731}
732
733define 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
745}
746
747define 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
760}
761
762define 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
771}
772
773define 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
785}
786
787define 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
800}
801
802define 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
811}
812
813define 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
825}
826
827define 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
840}
841
842define 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
847entry:
848  %and = and i64 %x, 4611686018427387903
849  ret i64 %and
850}
851
852define 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
857entry:
858  %x1 = load i64, i64* %x
859  %and = and i64 %x1, 4611686018427387903
860  ret i64 %and
861}
862
863; Make sure the mask doesn't break our matching of blcic
864define  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
875}
876