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
4define i32 @test_x86_tbm_bextri_u32(i32 %a) nounwind {
5; CHECK-LABEL: test_x86_tbm_bextri_u32:
6; CHECK:       # %bb.0:
7; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
8; CHECK-NEXT:    retq
9  %t0 = lshr i32 %a, 4
10  %t1 = and i32 %t0, 4095
11  ret i32 %t1
12}
13
14; Make sure we still use AH subreg trick for extracting bits 15:8
15define i32 @test_x86_tbm_bextri_u32_subreg(i32 %a) nounwind {
16; CHECK-LABEL: test_x86_tbm_bextri_u32_subreg:
17; CHECK:       # %bb.0:
18; CHECK-NEXT:    movl %edi, %eax
19; CHECK-NEXT:    movzbl %ah, %eax
20; CHECK-NEXT:    retq
21  %t0 = lshr i32 %a, 8
22  %t1 = and i32 %t0, 255
23  ret i32 %t1
24}
25
26define i32 @test_x86_tbm_bextri_u32_m(i32* nocapture %a) nounwind {
27; CHECK-LABEL: test_x86_tbm_bextri_u32_m:
28; CHECK:       # %bb.0:
29; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
30; CHECK-NEXT:    retq
31  %t0 = load i32, i32* %a
32  %t1 = lshr i32 %t0, 4
33  %t2 = and i32 %t1, 4095
34  ret i32 %t2
35}
36
37define i32 @test_x86_tbm_bextri_u32_z(i32 %a, i32 %b) nounwind {
38; CHECK-LABEL: test_x86_tbm_bextri_u32_z:
39; CHECK:       # %bb.0:
40; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
41; CHECK-NEXT:    cmovel %esi, %eax
42; CHECK-NEXT:    retq
43  %t0 = lshr i32 %a, 4
44  %t1 = and i32 %t0, 4095
45  %t2 = icmp eq i32 %t1, 0
46  %t3 = select i1 %t2, i32 %b, i32 %t1
47  ret i32 %t3
48}
49
50define i32 @test_x86_tbm_bextri_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
51; CHECK-LABEL: test_x86_tbm_bextri_u32_z2:
52; CHECK:       # %bb.0:
53; CHECK-NEXT:    movl %esi, %eax
54; CHECK-NEXT:    bextrl $3076, %edi, %ecx # imm = 0xC04
55; CHECK-NEXT:    cmovnel %edx, %eax
56; CHECK-NEXT:    retq
57  %t0 = lshr i32 %a, 4
58  %t1 = and i32 %t0, 4095
59  %t2 = icmp eq i32 %t1, 0
60  %t3 = select i1 %t2, i32 %b, i32 %c
61  ret i32 %t3
62}
63
64define i64 @test_x86_tbm_bextri_u64(i64 %a) nounwind {
65; CHECK-LABEL: test_x86_tbm_bextri_u64:
66; CHECK:       # %bb.0:
67; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
68; CHECK-NEXT:    retq
69  %t0 = lshr i64 %a, 4
70  %t1 = and i64 %t0, 4095
71  ret i64 %t1
72}
73
74; Make sure we still use AH subreg trick for extracting bits 15:8
75define i64 @test_x86_tbm_bextri_u64_subreg(i64 %a) nounwind {
76; CHECK-LABEL: test_x86_tbm_bextri_u64_subreg:
77; CHECK:       # %bb.0:
78; CHECK-NEXT:    movq %rdi, %rax
79; CHECK-NEXT:    movzbl %ah, %eax
80; CHECK-NEXT:    retq
81  %t0 = lshr i64 %a, 8
82  %t1 = and i64 %t0, 255
83  ret i64 %t1
84}
85
86define i64 @test_x86_tbm_bextri_u64_m(i64* nocapture %a) nounwind {
87; CHECK-LABEL: test_x86_tbm_bextri_u64_m:
88; CHECK:       # %bb.0:
89; CHECK-NEXT:    bextrl $3076, (%rdi), %eax # imm = 0xC04
90; CHECK-NEXT:    retq
91  %t0 = load i64, i64* %a
92  %t1 = lshr i64 %t0, 4
93  %t2 = and i64 %t1, 4095
94  ret i64 %t2
95}
96
97define i64 @test_x86_tbm_bextri_u64_z(i64 %a, i64 %b) nounwind {
98; CHECK-LABEL: test_x86_tbm_bextri_u64_z:
99; CHECK:       # %bb.0:
100; CHECK-NEXT:    bextrl $3076, %edi, %eax # imm = 0xC04
101; CHECK-NEXT:    cmoveq %rsi, %rax
102; CHECK-NEXT:    retq
103  %t0 = lshr i64 %a, 4
104  %t1 = and i64 %t0, 4095
105  %t2 = icmp eq i64 %t1, 0
106  %t3 = select i1 %t2, i64 %b, i64 %t1
107  ret i64 %t3
108}
109
110define i64 @test_x86_tbm_bextri_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
111; CHECK-LABEL: test_x86_tbm_bextri_u64_z2:
112; CHECK:       # %bb.0:
113; CHECK-NEXT:    movq %rsi, %rax
114; CHECK-NEXT:    bextrl $3076, %edi, %ecx # imm = 0xC04
115; CHECK-NEXT:    cmovneq %rdx, %rax
116; CHECK-NEXT:    retq
117  %t0 = lshr i64 %a, 4
118  %t1 = and i64 %t0, 4095
119  %t2 = icmp eq i64 %t1, 0
120  %t3 = select i1 %t2, i64 %b, i64 %c
121  ret i64 %t3
122}
123
124define i32 @test_x86_tbm_blcfill_u32(i32 %a) nounwind {
125; CHECK-LABEL: test_x86_tbm_blcfill_u32:
126; CHECK:       # %bb.0:
127; CHECK-NEXT:    blcfilll %edi, %eax
128; CHECK-NEXT:    retq
129  %t0 = add i32 %a, 1
130  %t1 = and i32 %t0, %a
131  ret i32 %t1
132}
133
134define i32 @test_x86_tbm_blcfill_u32_z(i32 %a, i32 %b) nounwind {
135; CHECK-LABEL: test_x86_tbm_blcfill_u32_z:
136; CHECK:       # %bb.0:
137; CHECK-NEXT:    blcfilll %edi, %eax
138; CHECK-NEXT:    cmovel %esi, %eax
139; CHECK-NEXT:    retq
140  %t0 = add i32 %a, 1
141  %t1 = and i32 %t0, %a
142  %t2 = icmp eq i32 %t1, 0
143  %t3 = select i1 %t2, i32 %b, i32 %t1
144  ret i32 %t3
145}
146
147define i32 @test_x86_tbm_blcfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
148; CHECK-LABEL: test_x86_tbm_blcfill_u32_z2:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    movl %esi, %eax
151; CHECK-NEXT:    blcfilll %edi, %ecx
152; CHECK-NEXT:    cmovnel %edx, %eax
153; CHECK-NEXT:    retq
154  %t0 = add i32 %a, 1
155  %t1 = and i32 %t0, %a
156  %t2 = icmp eq i32 %t1, 0
157  %t3 = select i1 %t2, i32 %b, i32 %c
158  ret i32 %t3
159}
160
161define i64 @test_x86_tbm_blcfill_u64(i64 %a) nounwind {
162; CHECK-LABEL: test_x86_tbm_blcfill_u64:
163; CHECK:       # %bb.0:
164; CHECK-NEXT:    blcfillq %rdi, %rax
165; CHECK-NEXT:    retq
166  %t0 = add i64 %a, 1
167  %t1 = and i64 %t0, %a
168  ret i64 %t1
169}
170
171define i64 @test_x86_tbm_blcfill_u64_z(i64 %a, i64 %b) nounwind {
172; CHECK-LABEL: test_x86_tbm_blcfill_u64_z:
173; CHECK:       # %bb.0:
174; CHECK-NEXT:    blcfillq %rdi, %rax
175; CHECK-NEXT:    cmoveq %rsi, %rax
176; CHECK-NEXT:    retq
177  %t0 = add i64 %a, 1
178  %t1 = and i64 %t0, %a
179  %t2 = icmp eq i64 %t1, 0
180  %t3 = select i1 %t2, i64 %b, i64 %t1
181  ret i64 %t3
182}
183
184define i64 @test_x86_tbm_blcfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
185; CHECK-LABEL: test_x86_tbm_blcfill_u64_z2:
186; CHECK:       # %bb.0:
187; CHECK-NEXT:    movq %rsi, %rax
188; CHECK-NEXT:    blcfillq %rdi, %rcx
189; CHECK-NEXT:    cmovneq %rdx, %rax
190; CHECK-NEXT:    retq
191  %t0 = add i64 %a, 1
192  %t1 = and i64 %t0, %a
193  %t2 = icmp eq i64 %t1, 0
194  %t3 = select i1 %t2, i64 %b, i64 %c
195  ret i64 %t3
196}
197
198define i32 @test_x86_tbm_blci_u32(i32 %a) nounwind {
199; CHECK-LABEL: test_x86_tbm_blci_u32:
200; CHECK:       # %bb.0:
201; CHECK-NEXT:    blcil %edi, %eax
202; CHECK-NEXT:    retq
203  %t0 = add i32 1, %a
204  %t1 = xor i32 %t0, -1
205  %t2 = or i32 %t1, %a
206  ret i32 %t2
207}
208
209define i32 @test_x86_tbm_blci_u32_z(i32 %a, i32 %b) nounwind {
210; CHECK-LABEL: test_x86_tbm_blci_u32_z:
211; CHECK:       # %bb.0:
212; CHECK-NEXT:    blcil %edi, %eax
213; CHECK-NEXT:    cmovel %esi, %eax
214; CHECK-NEXT:    retq
215  %t0 = add i32 1, %a
216  %t1 = xor i32 %t0, -1
217  %t2 = or i32 %t1, %a
218  %t3 = icmp eq i32 %t2, 0
219  %t4 = select i1 %t3, i32 %b, i32 %t2
220  ret i32 %t4
221}
222
223define i32 @test_x86_tbm_blci_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
224; CHECK-LABEL: test_x86_tbm_blci_u32_z2:
225; CHECK:       # %bb.0:
226; CHECK-NEXT:    movl %esi, %eax
227; CHECK-NEXT:    blcil %edi, %ecx
228; CHECK-NEXT:    cmovnel %edx, %eax
229; CHECK-NEXT:    retq
230  %t0 = add i32 1, %a
231  %t1 = xor i32 %t0, -1
232  %t2 = or i32 %t1, %a
233  %t3 = icmp eq i32 %t2, 0
234  %t4 = select i1 %t3, i32 %b, i32 %c
235  ret i32 %t4
236}
237
238define i64 @test_x86_tbm_blci_u64(i64 %a) nounwind {
239; CHECK-LABEL: test_x86_tbm_blci_u64:
240; CHECK:       # %bb.0:
241; CHECK-NEXT:    blciq %rdi, %rax
242; CHECK-NEXT:    retq
243  %t0 = add i64 1, %a
244  %t1 = xor i64 %t0, -1
245  %t2 = or i64 %t1, %a
246  ret i64 %t2
247}
248
249define i64 @test_x86_tbm_blci_u64_z(i64 %a, i64 %b) nounwind {
250; CHECK-LABEL: test_x86_tbm_blci_u64_z:
251; CHECK:       # %bb.0:
252; CHECK-NEXT:    blciq %rdi, %rax
253; CHECK-NEXT:    cmoveq %rsi, %rax
254; CHECK-NEXT:    retq
255  %t0 = add i64 1, %a
256  %t1 = xor i64 %t0, -1
257  %t2 = or i64 %t1, %a
258  %t3 = icmp eq i64 %t2, 0
259  %t4 = select i1 %t3, i64 %b, i64 %t2
260  ret i64 %t4
261}
262
263define i64 @test_x86_tbm_blci_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
264; CHECK-LABEL: test_x86_tbm_blci_u64_z2:
265; CHECK:       # %bb.0:
266; CHECK-NEXT:    movq %rsi, %rax
267; CHECK-NEXT:    blciq %rdi, %rcx
268; CHECK-NEXT:    cmovneq %rdx, %rax
269; CHECK-NEXT:    retq
270  %t0 = add i64 1, %a
271  %t1 = xor i64 %t0, -1
272  %t2 = or i64 %t1, %a
273  %t3 = icmp eq i64 %t2, 0
274  %t4 = select i1 %t3, i64 %b, i64 %c
275  ret i64 %t4
276}
277
278define i32 @test_x86_tbm_blci_u32_b(i32 %a) nounwind {
279; CHECK-LABEL: test_x86_tbm_blci_u32_b:
280; CHECK:       # %bb.0:
281; CHECK-NEXT:    blcil %edi, %eax
282; CHECK-NEXT:    retq
283  %t0 = sub i32 -2, %a
284  %t1 = or i32 %t0, %a
285  ret i32 %t1
286}
287
288define i64 @test_x86_tbm_blci_u64_b(i64 %a) nounwind {
289; CHECK-LABEL: test_x86_tbm_blci_u64_b:
290; CHECK:       # %bb.0:
291; CHECK-NEXT:    blciq %rdi, %rax
292; CHECK-NEXT:    retq
293  %t0 = sub i64 -2, %a
294  %t1 = or i64 %t0, %a
295  ret i64 %t1
296}
297
298define i32 @test_x86_tbm_blcic_u32(i32 %a) nounwind {
299; CHECK-LABEL: test_x86_tbm_blcic_u32:
300; CHECK:       # %bb.0:
301; CHECK-NEXT:    blcicl %edi, %eax
302; CHECK-NEXT:    retq
303  %t0 = xor i32 %a, -1
304  %t1 = add i32 %a, 1
305  %t2 = and i32 %t1, %t0
306  ret i32 %t2
307}
308
309define i32 @test_x86_tbm_blcic_u32_z(i32 %a, i32 %b) nounwind {
310; CHECK-LABEL: test_x86_tbm_blcic_u32_z:
311; CHECK:       # %bb.0:
312; CHECK-NEXT:    blcicl %edi, %eax
313; CHECK-NEXT:    cmovel %esi, %eax
314; CHECK-NEXT:    retq
315  %t0 = xor i32 %a, -1
316  %t1 = add i32 %a, 1
317  %t2 = and i32 %t1, %t0
318  %t3 = icmp eq i32 %t2, 0
319  %t4 = select i1 %t3, i32 %b, i32 %t2
320  ret i32 %t4
321}
322
323define i32 @test_x86_tbm_blcic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
324; CHECK-LABEL: test_x86_tbm_blcic_u32_z2:
325; CHECK:       # %bb.0:
326; CHECK-NEXT:    movl %esi, %eax
327; CHECK-NEXT:    blcicl %edi, %ecx
328; CHECK-NEXT:    cmovnel %edx, %eax
329; CHECK-NEXT:    retq
330  %t0 = xor i32 %a, -1
331  %t1 = add i32 %a, 1
332  %t2 = and i32 %t1, %t0
333  %t3 = icmp eq i32 %t2, 0
334  %t4 = select i1 %t3, i32 %b, i32 %c
335  ret i32 %t4
336}
337
338define i64 @test_x86_tbm_blcic_u64(i64 %a) nounwind {
339; CHECK-LABEL: test_x86_tbm_blcic_u64:
340; CHECK:       # %bb.0:
341; CHECK-NEXT:    blcicq %rdi, %rax
342; CHECK-NEXT:    retq
343  %t0 = xor i64 %a, -1
344  %t1 = add i64 %a, 1
345  %t2 = and i64 %t1, %t0
346  ret i64 %t2
347}
348
349define i64 @test_x86_tbm_blcic_u64_z(i64 %a, i64 %b) nounwind {
350; CHECK-LABEL: test_x86_tbm_blcic_u64_z:
351; CHECK:       # %bb.0:
352; CHECK-NEXT:    blcicq %rdi, %rax
353; CHECK-NEXT:    cmoveq %rsi, %rax
354; CHECK-NEXT:    retq
355  %t0 = xor i64 %a, -1
356  %t1 = add i64 %a, 1
357  %t2 = and i64 %t1, %t0
358  %t3 = icmp eq i64 %t2, 0
359  %t4 = select i1 %t3, i64 %b, i64 %t2
360  ret i64 %t4
361}
362
363define i64 @test_x86_tbm_blcic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
364; CHECK-LABEL: test_x86_tbm_blcic_u64_z2:
365; CHECK:       # %bb.0:
366; CHECK-NEXT:    movq %rsi, %rax
367; CHECK-NEXT:    blcicq %rdi, %rcx
368; CHECK-NEXT:    cmovneq %rdx, %rax
369; CHECK-NEXT:    retq
370  %t0 = xor i64 %a, -1
371  %t1 = add i64 %a, 1
372  %t2 = and i64 %t1, %t0
373  %t3 = icmp eq i64 %t2, 0
374  %t4 = select i1 %t3, i64 %b, i64 %c
375  ret i64 %t4
376}
377
378define i32 @test_x86_tbm_blcmsk_u32(i32 %a) nounwind {
379; CHECK-LABEL: test_x86_tbm_blcmsk_u32:
380; CHECK:       # %bb.0:
381; CHECK-NEXT:    blcmskl %edi, %eax
382; CHECK-NEXT:    retq
383  %t0 = add i32 %a, 1
384  %t1 = xor i32 %t0, %a
385  ret i32 %t1
386}
387
388define i32 @test_x86_tbm_blcmsk_u32_z(i32 %a, i32 %b) nounwind {
389; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z:
390; CHECK:       # %bb.0:
391; CHECK-NEXT:    blcmskl %edi, %eax
392; CHECK-NEXT:    cmovel %esi, %eax
393; CHECK-NEXT:    retq
394  %t0 = add i32 %a, 1
395  %t1 = xor i32 %t0, %a
396  %t2 = icmp eq i32 %t1, 0
397  %t3 = select i1 %t2, i32 %b, i32 %t1
398  ret i32 %t3
399}
400
401define i32 @test_x86_tbm_blcmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
402; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z2:
403; CHECK:       # %bb.0:
404; CHECK-NEXT:    movl %esi, %eax
405; CHECK-NEXT:    blcmskl %edi, %ecx
406; CHECK-NEXT:    cmovnel %edx, %eax
407; CHECK-NEXT:    retq
408  %t0 = add i32 %a, 1
409  %t1 = xor i32 %t0, %a
410  %t2 = icmp eq i32 %t1, 0
411  %t3 = select i1 %t2, i32 %b, i32 %c
412  ret i32 %t3
413}
414
415define i64 @test_x86_tbm_blcmsk_u64(i64 %a) nounwind {
416; CHECK-LABEL: test_x86_tbm_blcmsk_u64:
417; CHECK:       # %bb.0:
418; CHECK-NEXT:    blcmskq %rdi, %rax
419; CHECK-NEXT:    retq
420  %t0 = add i64 %a, 1
421  %t1 = xor i64 %t0, %a
422  ret i64 %t1
423}
424
425define i64 @test_x86_tbm_blcmsk_u64_z(i64 %a, i64 %b) nounwind {
426; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z:
427; CHECK:       # %bb.0:
428; CHECK-NEXT:    blcmskq %rdi, %rax
429; CHECK-NEXT:    cmoveq %rsi, %rax
430; CHECK-NEXT:    retq
431  %t0 = add i64 %a, 1
432  %t1 = xor i64 %t0, %a
433  %t2 = icmp eq i64 %t1, 0
434  %t3 = select i1 %t2, i64 %b, i64 %t1
435  ret i64 %t3
436}
437
438define i64 @test_x86_tbm_blcmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
439; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z2:
440; CHECK:       # %bb.0:
441; CHECK-NEXT:    movq %rsi, %rax
442; CHECK-NEXT:    blcmskq %rdi, %rcx
443; CHECK-NEXT:    cmovneq %rdx, %rax
444; CHECK-NEXT:    retq
445  %t0 = add i64 %a, 1
446  %t1 = xor i64 %t0, %a
447  %t2 = icmp eq i64 %t1, 0
448  %t3 = select i1 %t2, i64 %b, i64 %c
449  ret i64 %t3
450}
451
452define i32 @test_x86_tbm_blcs_u32(i32 %a) nounwind {
453; CHECK-LABEL: test_x86_tbm_blcs_u32:
454; CHECK:       # %bb.0:
455; CHECK-NEXT:    blcsl %edi, %eax
456; CHECK-NEXT:    retq
457  %t0 = add i32 %a, 1
458  %t1 = or i32 %t0, %a
459  ret i32 %t1
460}
461
462define i32 @test_x86_tbm_blcs_u32_z(i32 %a, i32 %b) nounwind {
463; CHECK-LABEL: test_x86_tbm_blcs_u32_z:
464; CHECK:       # %bb.0:
465; CHECK-NEXT:    blcsl %edi, %eax
466; CHECK-NEXT:    cmovel %esi, %eax
467; CHECK-NEXT:    retq
468  %t0 = add i32 %a, 1
469  %t1 = or i32 %t0, %a
470  %t2 = icmp eq i32 %t1, 0
471  %t3 = select i1 %t2, i32 %b, i32 %t1
472  ret i32 %t3
473}
474
475define i32 @test_x86_tbm_blcs_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
476; CHECK-LABEL: test_x86_tbm_blcs_u32_z2:
477; CHECK:       # %bb.0:
478; CHECK-NEXT:    movl %esi, %eax
479; CHECK-NEXT:    blcsl %edi, %ecx
480; CHECK-NEXT:    cmovnel %edx, %eax
481; CHECK-NEXT:    retq
482  %t0 = add i32 %a, 1
483  %t1 = or i32 %t0, %a
484  %t2 = icmp eq i32 %t1, 0
485  %t3 = select i1 %t2, i32 %b, i32 %c
486  ret i32 %t3
487}
488
489define i64 @test_x86_tbm_blcs_u64(i64 %a) nounwind {
490; CHECK-LABEL: test_x86_tbm_blcs_u64:
491; CHECK:       # %bb.0:
492; CHECK-NEXT:    blcsq %rdi, %rax
493; CHECK-NEXT:    retq
494  %t0 = add i64 %a, 1
495  %t1 = or i64 %t0, %a
496  ret i64 %t1
497}
498
499define i64 @test_x86_tbm_blcs_u64_z(i64 %a, i64 %b) nounwind {
500; CHECK-LABEL: test_x86_tbm_blcs_u64_z:
501; CHECK:       # %bb.0:
502; CHECK-NEXT:    blcsq %rdi, %rax
503; CHECK-NEXT:    cmoveq %rsi, %rax
504; CHECK-NEXT:    retq
505  %t0 = add i64 %a, 1
506  %t1 = or i64 %t0, %a
507  %t2 = icmp eq i64 %t1, 0
508  %t3 = select i1 %t2, i64 %b, i64 %t1
509  ret i64 %t3
510}
511
512define i64 @test_x86_tbm_blcs_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
513; CHECK-LABEL: test_x86_tbm_blcs_u64_z2:
514; CHECK:       # %bb.0:
515; CHECK-NEXT:    movq %rsi, %rax
516; CHECK-NEXT:    blcsq %rdi, %rcx
517; CHECK-NEXT:    cmovneq %rdx, %rax
518; CHECK-NEXT:    retq
519  %t0 = add i64 %a, 1
520  %t1 = or i64 %t0, %a
521  %t2 = icmp eq i64 %t1, 0
522  %t3 = select i1 %t2, i64 %b, i64 %c
523  ret i64 %t3
524}
525
526define i32 @test_x86_tbm_blsfill_u32(i32 %a) nounwind {
527; CHECK-LABEL: test_x86_tbm_blsfill_u32:
528; CHECK:       # %bb.0:
529; CHECK-NEXT:    blsfilll %edi, %eax
530; CHECK-NEXT:    retq
531  %t0 = add i32 %a, -1
532  %t1 = or i32 %t0, %a
533  ret i32 %t1
534}
535
536define i32 @test_x86_tbm_blsfill_u32_z(i32 %a, i32 %b) nounwind {
537; CHECK-LABEL: test_x86_tbm_blsfill_u32_z:
538; CHECK:       # %bb.0:
539; CHECK-NEXT:    blsfilll %edi, %eax
540; CHECK-NEXT:    cmovel %esi, %eax
541; CHECK-NEXT:    retq
542  %t0 = add i32 %a, -1
543  %t1 = or i32 %t0, %a
544  %t2 = icmp eq i32 %t1, 0
545  %t3 = select i1 %t2, i32 %b, i32 %t1
546  ret i32 %t3
547}
548
549define i32 @test_x86_tbm_blsfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
550; CHECK-LABEL: test_x86_tbm_blsfill_u32_z2:
551; CHECK:       # %bb.0:
552; CHECK-NEXT:    movl %esi, %eax
553; CHECK-NEXT:    blsfilll %edi, %ecx
554; CHECK-NEXT:    cmovnel %edx, %eax
555; CHECK-NEXT:    retq
556  %t0 = add i32 %a, -1
557  %t1 = or i32 %t0, %a
558  %t2 = icmp eq i32 %t1, 0
559  %t3 = select i1 %t2, i32 %b, i32 %c
560  ret i32 %t3
561}
562
563define i64 @test_x86_tbm_blsfill_u64(i64 %a) nounwind {
564; CHECK-LABEL: test_x86_tbm_blsfill_u64:
565; CHECK:       # %bb.0:
566; CHECK-NEXT:    blsfillq %rdi, %rax
567; CHECK-NEXT:    retq
568  %t0 = add i64 %a, -1
569  %t1 = or i64 %t0, %a
570  ret i64 %t1
571}
572
573define i64 @test_x86_tbm_blsfill_u64_z(i64 %a, i64 %b) nounwind {
574; CHECK-LABEL: test_x86_tbm_blsfill_u64_z:
575; CHECK:       # %bb.0:
576; CHECK-NEXT:    blsfillq %rdi, %rax
577; CHECK-NEXT:    cmoveq %rsi, %rax
578; CHECK-NEXT:    retq
579  %t0 = add i64 %a, -1
580  %t1 = or i64 %t0, %a
581  %t2 = icmp eq i64 %t1, 0
582  %t3 = select i1 %t2, i64 %b, i64 %t1
583  ret i64 %t3
584}
585
586define i64 @test_x86_tbm_blsfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
587; CHECK-LABEL: test_x86_tbm_blsfill_u64_z2:
588; CHECK:       # %bb.0:
589; CHECK-NEXT:    movq %rsi, %rax
590; CHECK-NEXT:    blsfillq %rdi, %rcx
591; CHECK-NEXT:    cmovneq %rdx, %rax
592; CHECK-NEXT:    retq
593  %t0 = add i64 %a, -1
594  %t1 = or i64 %t0, %a
595  %t2 = icmp eq i64 %t1, 0
596  %t3 = select i1 %t2, i64 %b, i64 %c
597  ret i64 %t3
598}
599
600define i32 @test_x86_tbm_blsic_u32(i32 %a) nounwind {
601; CHECK-LABEL: test_x86_tbm_blsic_u32:
602; CHECK:       # %bb.0:
603; CHECK-NEXT:    blsicl %edi, %eax
604; CHECK-NEXT:    retq
605  %t0 = xor i32 %a, -1
606  %t1 = add i32 %a, -1
607  %t2 = or i32 %t0, %t1
608  ret i32 %t2
609}
610
611define i32 @test_x86_tbm_blsic_u32_z(i32 %a, i32 %b) nounwind {
612; CHECK-LABEL: test_x86_tbm_blsic_u32_z:
613; CHECK:       # %bb.0:
614; CHECK-NEXT:    blsicl %edi, %eax
615; CHECK-NEXT:    cmovel %esi, %eax
616; CHECK-NEXT:    retq
617  %t0 = xor i32 %a, -1
618  %t1 = add i32 %a, -1
619  %t2 = or i32 %t0, %t1
620  %t3 = icmp eq i32 %t2, 0
621  %t4 = select i1 %t3, i32 %b, i32 %t2
622  ret i32 %t4
623}
624
625define i32 @test_x86_tbm_blsic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
626; CHECK-LABEL: test_x86_tbm_blsic_u32_z2:
627; CHECK:       # %bb.0:
628; CHECK-NEXT:    movl %esi, %eax
629; CHECK-NEXT:    blsicl %edi, %ecx
630; CHECK-NEXT:    cmovnel %edx, %eax
631; CHECK-NEXT:    retq
632  %t0 = xor i32 %a, -1
633  %t1 = add i32 %a, -1
634  %t2 = or i32 %t0, %t1
635  %t3 = icmp eq i32 %t2, 0
636  %t4 = select i1 %t3, i32 %b, i32 %c
637  ret i32 %t4
638}
639
640define i64 @test_x86_tbm_blsic_u64(i64 %a) nounwind {
641; CHECK-LABEL: test_x86_tbm_blsic_u64:
642; CHECK:       # %bb.0:
643; CHECK-NEXT:    blsicq %rdi, %rax
644; CHECK-NEXT:    retq
645  %t0 = xor i64 %a, -1
646  %t1 = add i64 %a, -1
647  %t2 = or i64 %t0, %t1
648  ret i64 %t2
649}
650
651define i64 @test_x86_tbm_blsic_u64_z(i64 %a, i64 %b) nounwind {
652; CHECK-LABEL: test_x86_tbm_blsic_u64_z:
653; CHECK:       # %bb.0:
654; CHECK-NEXT:    blsicq %rdi, %rax
655; CHECK-NEXT:    cmoveq %rsi, %rax
656; CHECK-NEXT:    retq
657  %t0 = xor i64 %a, -1
658  %t1 = add i64 %a, -1
659  %t2 = or i64 %t0, %t1
660  %t3 = icmp eq i64 %t2, 0
661  %t4 = select i1 %t3, i64 %b, i64 %t2
662  ret i64 %t4
663}
664
665define i64 @test_x86_tbm_blsic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
666; CHECK-LABEL: test_x86_tbm_blsic_u64_z2:
667; CHECK:       # %bb.0:
668; CHECK-NEXT:    movq %rsi, %rax
669; CHECK-NEXT:    blsicq %rdi, %rcx
670; CHECK-NEXT:    cmovneq %rdx, %rax
671; CHECK-NEXT:    retq
672  %t0 = xor i64 %a, -1
673  %t1 = add i64 %a, -1
674  %t2 = or i64 %t0, %t1
675  %t3 = icmp eq i64 %t2, 0
676  %t4 = select i1 %t3, i64 %b, i64 %c
677  ret i64 %t4
678}
679
680define i32 @test_x86_tbm_t1mskc_u32(i32 %a) nounwind {
681; CHECK-LABEL: test_x86_tbm_t1mskc_u32:
682; CHECK:       # %bb.0:
683; CHECK-NEXT:    t1mskcl %edi, %eax
684; CHECK-NEXT:    retq
685  %t0 = xor i32 %a, -1
686  %t1 = add i32 %a, 1
687  %t2 = or i32 %t0, %t1
688  ret i32 %t2
689}
690
691define i32 @test_x86_tbm_t1mskc_u32_z(i32 %a, i32 %b) nounwind {
692; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z:
693; CHECK:       # %bb.0:
694; CHECK-NEXT:    t1mskcl %edi, %eax
695; CHECK-NEXT:    cmovel %esi, %eax
696; CHECK-NEXT:    retq
697  %t0 = xor i32 %a, -1
698  %t1 = add i32 %a, 1
699  %t2 = or i32 %t0, %t1
700  %t3 = icmp eq i32 %t2, 0
701  %t4 = select i1 %t3, i32 %b, i32 %t2
702  ret i32 %t4
703}
704
705define i32 @test_x86_tbm_t1mskc_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
706; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z2:
707; CHECK:       # %bb.0:
708; CHECK-NEXT:    movl %esi, %eax
709; CHECK-NEXT:    t1mskcl %edi, %ecx
710; CHECK-NEXT:    cmovnel %edx, %eax
711; CHECK-NEXT:    retq
712  %t0 = xor i32 %a, -1
713  %t1 = add i32 %a, 1
714  %t2 = or i32 %t0, %t1
715  %t3 = icmp eq i32 %t2, 0
716  %t4 = select i1 %t3, i32 %b, i32 %c
717  ret i32 %t4
718}
719
720define i64 @test_x86_tbm_t1mskc_u64(i64 %a) nounwind {
721; CHECK-LABEL: test_x86_tbm_t1mskc_u64:
722; CHECK:       # %bb.0:
723; CHECK-NEXT:    t1mskcq %rdi, %rax
724; CHECK-NEXT:    retq
725  %t0 = xor i64 %a, -1
726  %t1 = add i64 %a, 1
727  %t2 = or i64 %t0, %t1
728  ret i64 %t2
729}
730
731define i64 @test_x86_tbm_t1mskc_u64_z(i64 %a, i64 %b) nounwind {
732; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z:
733; CHECK:       # %bb.0:
734; CHECK-NEXT:    t1mskcq %rdi, %rax
735; CHECK-NEXT:    cmoveq %rsi, %rax
736; CHECK-NEXT:    retq
737  %t0 = xor i64 %a, -1
738  %t1 = add i64 %a, 1
739  %t2 = or i64 %t0, %t1
740  %t3 = icmp eq i64 %t2, 0
741  %t4 = select i1 %t3, i64 %b, i64 %t2
742  ret i64 %t4
743}
744
745define i64 @test_x86_tbm_t1mskc_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
746; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z2:
747; CHECK:       # %bb.0:
748; CHECK-NEXT:    movq %rsi, %rax
749; CHECK-NEXT:    t1mskcq %rdi, %rcx
750; CHECK-NEXT:    cmovneq %rdx, %rax
751; CHECK-NEXT:    retq
752  %t0 = xor i64 %a, -1
753  %t1 = add i64 %a, 1
754  %t2 = or i64 %t0, %t1
755  %t3 = icmp eq i64 %t2, 0
756  %t4 = select i1 %t3, i64 %b, i64 %c
757  ret i64 %t4
758}
759
760define i32 @test_x86_tbm_tzmsk_u32(i32 %a) nounwind {
761; CHECK-LABEL: test_x86_tbm_tzmsk_u32:
762; CHECK:       # %bb.0:
763; CHECK-NEXT:    tzmskl %edi, %eax
764; CHECK-NEXT:    retq
765  %t0 = xor i32 %a, -1
766  %t1 = add i32 %a, -1
767  %t2 = and i32 %t0, %t1
768  ret i32 %t2
769}
770
771define i32 @test_x86_tbm_tzmsk_u32_z(i32 %a, i32 %b) nounwind {
772; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z:
773; CHECK:       # %bb.0:
774; CHECK-NEXT:    tzmskl %edi, %eax
775; CHECK-NEXT:    cmovel %esi, %eax
776; CHECK-NEXT:    retq
777  %t0 = xor i32 %a, -1
778  %t1 = add i32 %a, -1
779  %t2 = and i32 %t0, %t1
780  %t3 = icmp eq i32 %t2, 0
781  %t4 = select i1 %t3, i32 %b, i32 %t2
782  ret i32 %t4
783}
784
785define i32 @test_x86_tbm_tzmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind {
786; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z2:
787; CHECK:       # %bb.0:
788; CHECK-NEXT:    movl %esi, %eax
789; CHECK-NEXT:    tzmskl %edi, %ecx
790; CHECK-NEXT:    cmovnel %edx, %eax
791; CHECK-NEXT:    retq
792  %t0 = xor i32 %a, -1
793  %t1 = add i32 %a, -1
794  %t2 = and i32 %t0, %t1
795  %t3 = icmp eq i32 %t2, 0
796  %t4 = select i1 %t3, i32 %b, i32 %c
797  ret i32 %t4
798}
799
800define i64 @test_x86_tbm_tzmsk_u64(i64 %a) nounwind {
801; CHECK-LABEL: test_x86_tbm_tzmsk_u64:
802; CHECK:       # %bb.0:
803; CHECK-NEXT:    tzmskq %rdi, %rax
804; CHECK-NEXT:    retq
805  %t0 = xor i64 %a, -1
806  %t1 = add i64 %a, -1
807  %t2 = and i64 %t0, %t1
808  ret i64 %t2
809}
810
811define i64 @test_x86_tbm_tzmsk_u64_z(i64 %a, i64 %b) nounwind {
812; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z:
813; CHECK:       # %bb.0:
814; CHECK-NEXT:    tzmskq %rdi, %rax
815; CHECK-NEXT:    cmoveq %rsi, %rax
816; CHECK-NEXT:    retq
817  %t0 = xor i64 %a, -1
818  %t1 = add i64 %a, -1
819  %t2 = and i64 %t0, %t1
820  %t3 = icmp eq i64 %t2, 0
821  %t4 = select i1 %t3, i64 %b, i64 %t2
822  ret i64 %t4
823}
824
825define i64 @test_x86_tbm_tzmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind {
826; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z2:
827; CHECK:       # %bb.0:
828; CHECK-NEXT:    movq %rsi, %rax
829; CHECK-NEXT:    tzmskq %rdi, %rcx
830; CHECK-NEXT:    cmovneq %rdx, %rax
831; CHECK-NEXT:    retq
832  %t0 = xor i64 %a, -1
833  %t1 = add i64 %a, -1
834  %t2 = and i64 %t0, %t1
835  %t3 = icmp eq i64 %t2, 0
836  %t4 = select i1 %t3, i64 %b, i64 %c
837  ret i64 %t4
838}
839
840define i64 @test_and_large_constant_mask(i64 %x) {
841; CHECK-LABEL: test_and_large_constant_mask:
842; CHECK:       # %bb.0: # %entry
843; CHECK-NEXT:    bextrq $15872, %rdi, %rax # imm = 0x3E00
844; CHECK-NEXT:    retq
845entry:
846  %and = and i64 %x, 4611686018427387903
847  ret i64 %and
848}
849
850define i64 @test_and_large_constant_mask_load(i64* %x) {
851; CHECK-LABEL: test_and_large_constant_mask_load:
852; CHECK:       # %bb.0: # %entry
853; CHECK-NEXT:    bextrq $15872, (%rdi), %rax # imm = 0x3E00
854; CHECK-NEXT:    retq
855entry:
856  %x1 = load i64, i64* %x
857  %and = and i64 %x1, 4611686018427387903
858  ret i64 %and
859}
860
861; Make sure the mask doesn't break our matching of blcic
862define  i64 @masked_blcic(i64) {
863; CHECK-LABEL: masked_blcic:
864; CHECK:       # %bb.0:
865; CHECK-NEXT:    movzwl %di, %eax
866; CHECK-NEXT:    blcicl %eax, %eax
867; CHECK-NEXT:    retq
868  %2 = and i64 %0, 65535
869  %3 = xor i64 %2, -1
870  %4 = add nuw nsw i64 %2, 1
871  %5 = and i64 %4, %3
872  ret i64 %5
873}
874
875define i32 @blcic32_branch(i32 %x) nounwind {
876; CHECK-LABEL: blcic32_branch:
877; CHECK:       # %bb.0:
878; CHECK-NEXT:    pushq %rbx
879; CHECK-NEXT:    blcicl %edi, %ebx
880; CHECK-NEXT:    jne .LBB69_2
881; CHECK-NEXT:  # %bb.1:
882; CHECK-NEXT:    callq bar
883; CHECK-NEXT:  .LBB69_2:
884; CHECK-NEXT:    movl %ebx, %eax
885; CHECK-NEXT:    popq %rbx
886; CHECK-NEXT:    retq
887  %tmp = xor i32 %x, -1
888  %tmp2 = add i32 %x, 1
889  %tmp3 = and i32 %tmp, %tmp2
890  %cmp = icmp eq i32 %tmp3, 0
891  br i1 %cmp, label %1, label %2
892
893  tail call void @bar()
894  br label %2
895  ret i32 %tmp3
896}
897
898define i64 @blcic64_branch(i64 %x) nounwind {
899; CHECK-LABEL: blcic64_branch:
900; CHECK:       # %bb.0:
901; CHECK-NEXT:    pushq %rbx
902; CHECK-NEXT:    blcicq %rdi, %rbx
903; CHECK-NEXT:    jne .LBB70_2
904; CHECK-NEXT:  # %bb.1:
905; CHECK-NEXT:    callq bar
906; CHECK-NEXT:  .LBB70_2:
907; CHECK-NEXT:    movq %rbx, %rax
908; CHECK-NEXT:    popq %rbx
909; CHECK-NEXT:    retq
910  %tmp = xor i64 %x, -1
911  %tmp2 = add i64 %x, 1
912  %tmp3 = and i64 %tmp, %tmp2
913  %cmp = icmp eq i64 %tmp3, 0
914  br i1 %cmp, label %1, label %2
915
916  tail call void @bar()
917  br label %2
918  ret i64 %tmp3
919}
920
921define i32 @tzmsk32_branch(i32 %x) nounwind {
922; CHECK-LABEL: tzmsk32_branch:
923; CHECK:       # %bb.0:
924; CHECK-NEXT:    pushq %rbx
925; CHECK-NEXT:    tzmskl %edi, %ebx
926; CHECK-NEXT:    jne .LBB71_2
927; CHECK-NEXT:  # %bb.1:
928; CHECK-NEXT:    callq bar
929; CHECK-NEXT:  .LBB71_2:
930; CHECK-NEXT:    movl %ebx, %eax
931; CHECK-NEXT:    popq %rbx
932; CHECK-NEXT:    retq
933  %tmp = xor i32 %x, -1
934  %tmp2 = add i32 %x, -1
935  %tmp3 = and i32 %tmp, %tmp2
936  %cmp = icmp eq i32 %tmp3, 0
937  br i1 %cmp, label %1, label %2
938
939  tail call void @bar()
940  br label %2
941  ret i32 %tmp3
942}
943
944define i64 @tzmsk64_branch(i64 %x) nounwind {
945; CHECK-LABEL: tzmsk64_branch:
946; CHECK:       # %bb.0:
947; CHECK-NEXT:    pushq %rbx
948; CHECK-NEXT:    tzmskq %rdi, %rbx
949; CHECK-NEXT:    jne .LBB72_2
950; CHECK-NEXT:  # %bb.1:
951; CHECK-NEXT:    callq bar
952; CHECK-NEXT:  .LBB72_2:
953; CHECK-NEXT:    movq %rbx, %rax
954; CHECK-NEXT:    popq %rbx
955; CHECK-NEXT:    retq
956  %tmp = xor i64 %x, -1
957  %tmp2 = add i64 %x, -1
958  %tmp3 = and i64 %tmp, %tmp2
959  %cmp = icmp eq i64 %tmp3, 0
960  br i1 %cmp, label %1, label %2
961
962  tail call void @bar()
963  br label %2
964  ret i64 %tmp3
965}
966
967declare void @bar()
968