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