[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / X86 / tbm_patterns.ll
blobde47391acb289e80532d1c99fef60d392f031be6
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 define 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
14 ; Make sure we still use AH subreg trick for extracting bits 15:8
15 define 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
26 define 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
37 define 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
50 define 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
64 define 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
74 ; Make sure we still use AH subreg trick for extracting bits 15:8
75 define 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
86 define 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
97 define 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
110 define 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
124 define 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
134 define 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
147 define 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
161 define 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
171 define 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
184 define 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
198 define 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
209 define 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
223 define 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
238 define 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
249 define 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
263 define 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
278 define 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
288 define 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
298 define 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
309 define 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
323 define 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
338 define 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
349 define 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
363 define 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
378 define 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
388 define 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
401 define 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
415 define 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
425 define 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
438 define 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
452 define 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
462 define 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
475 define 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
489 define 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
499 define 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
512 define 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
526 define 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
536 define 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
549 define 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
563 define 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
573 define 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
586 define 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
600 define 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
611 define 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
625 define 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
640 define 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
651 define 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
665 define 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
680 define 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
691 define 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
705 define 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
720 define 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
731 define 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
745 define 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
760 define 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
771 define 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
785 define 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
800 define 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
811 define 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
825 define 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
840 define 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
845 entry:
846   %and = and i64 %x, 4611686018427387903
847   ret i64 %and
850 define 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
855 entry:
856   %x1 = load i64, i64* %x
857   %and = and i64 %x1, 4611686018427387903
858   ret i64 %and
861 ; Make sure the mask doesn't break our matching of blcic
862 define  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
875 define 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
893   tail call void @bar()
894   br label %2
895   ret i32 %tmp3
898 define 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
916   tail call void @bar()
917   br label %2
918   ret i64 %tmp3
921 define 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
939   tail call void @bar()
940   br label %2
941   ret i32 %tmp3
944 define 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
962   tail call void @bar()
963   br label %2
964   ret i64 %tmp3
967 declare void @bar()