• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=X64
5
6; PR3253
7
8; The register+memory form of the BT instruction should be usable on
9; pentium4, however it is currently disabled due to the register+memory
10; form having different semantics than the register+register form.
11
12; Test these patterns:
13;    (X & (1 << N))  != 0  -->  BT(X, N).
14;    ((X >>u N) & 1) != 0  -->  BT(X, N).
15; as well as several variations:
16;    - The second form can use an arithmetic shift.
17;    - Either form can use == instead of !=.
18;    - Either form can compare with an operand of the &
19;      instead of with 0.
20;    - The comparison can be commuted (only cases where neither
21;      operand is constant are included).
22;    - The and can be commuted.
23
24define void @test2(i32 %x, i32 %n) nounwind {
25; X86-LABEL: test2:
26; X86:       # %bb.0: # %entry
27; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
28; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
29; X86-NEXT:    btl %ecx, %eax
30; X86-NEXT:    jb .LBB0_2
31; X86-NEXT:  # %bb.1: # %bb
32; X86-NEXT:    calll foo
33; X86-NEXT:  .LBB0_2: # %UnifiedReturnBlock
34; X86-NEXT:    retl
35;
36; X64-LABEL: test2:
37; X64:       # %bb.0: # %entry
38; X64-NEXT:    btl %esi, %edi
39; X64-NEXT:    jb .LBB0_2
40; X64-NEXT:  # %bb.1: # %bb
41; X64-NEXT:    pushq %rax
42; X64-NEXT:    callq foo
43; X64-NEXT:    popq %rax
44; X64-NEXT:  .LBB0_2: # %UnifiedReturnBlock
45; X64-NEXT:    retq
46entry:
47  %tmp29 = lshr i32 %x, %n
48  %tmp3 = and i32 %tmp29, 1
49  %tmp4 = icmp eq i32 %tmp3, 0
50  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
51
52bb:
53  call void @foo()
54  ret void
55
56UnifiedReturnBlock:
57  ret void
58}
59
60define void @test2b(i32 %x, i32 %n) nounwind {
61; X86-LABEL: test2b:
62; X86:       # %bb.0: # %entry
63; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
64; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
65; X86-NEXT:    btl %ecx, %eax
66; X86-NEXT:    jae .LBB1_1
67; X86-NEXT:  # %bb.2: # %UnifiedReturnBlock
68; X86-NEXT:    retl
69; X86-NEXT:  .LBB1_1: # %bb
70; X86-NEXT:    calll foo
71; X86-NEXT:    retl
72;
73; X64-LABEL: test2b:
74; X64:       # %bb.0: # %entry
75; X64-NEXT:    btl %esi, %edi
76; X64-NEXT:    jae .LBB1_1
77; X64-NEXT:  # %bb.2: # %UnifiedReturnBlock
78; X64-NEXT:    retq
79; X64-NEXT:  .LBB1_1: # %bb
80; X64-NEXT:    pushq %rax
81; X64-NEXT:    callq foo
82; X64-NEXT:    popq %rax
83; X64-NEXT:    retq
84entry:
85  %tmp29 = lshr i32 %x, %n
86  %tmp3 = and i32 1, %tmp29
87  %tmp4 = icmp eq i32 %tmp3, 0
88  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
89
90bb:
91  call void @foo()
92  ret void
93
94UnifiedReturnBlock:
95  ret void
96}
97
98define void @atest2(i32 %x, i32 %n) nounwind {
99; X86-LABEL: atest2:
100; X86:       # %bb.0: # %entry
101; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
102; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
103; X86-NEXT:    btl %ecx, %eax
104; X86-NEXT:    jb .LBB2_2
105; X86-NEXT:  # %bb.1: # %bb
106; X86-NEXT:    calll foo
107; X86-NEXT:  .LBB2_2: # %UnifiedReturnBlock
108; X86-NEXT:    retl
109;
110; X64-LABEL: atest2:
111; X64:       # %bb.0: # %entry
112; X64-NEXT:    btl %esi, %edi
113; X64-NEXT:    jb .LBB2_2
114; X64-NEXT:  # %bb.1: # %bb
115; X64-NEXT:    pushq %rax
116; X64-NEXT:    callq foo
117; X64-NEXT:    popq %rax
118; X64-NEXT:  .LBB2_2: # %UnifiedReturnBlock
119; X64-NEXT:    retq
120entry:
121  %tmp29 = ashr i32 %x, %n
122  %tmp3 = and i32 %tmp29, 1
123  %tmp4 = icmp eq i32 %tmp3, 0
124  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
125
126bb:
127  call void @foo()
128  ret void
129
130UnifiedReturnBlock:
131  ret void
132}
133
134define void @atest2b(i32 %x, i32 %n) nounwind {
135; X86-LABEL: atest2b:
136; X86:       # %bb.0: # %entry
137; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
138; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
139; X86-NEXT:    btl %ecx, %eax
140; X86-NEXT:    jae .LBB3_1
141; X86-NEXT:  # %bb.2: # %UnifiedReturnBlock
142; X86-NEXT:    retl
143; X86-NEXT:  .LBB3_1: # %bb
144; X86-NEXT:    calll foo
145; X86-NEXT:    retl
146;
147; X64-LABEL: atest2b:
148; X64:       # %bb.0: # %entry
149; X64-NEXT:    btl %esi, %edi
150; X64-NEXT:    jae .LBB3_1
151; X64-NEXT:  # %bb.2: # %UnifiedReturnBlock
152; X64-NEXT:    retq
153; X64-NEXT:  .LBB3_1: # %bb
154; X64-NEXT:    pushq %rax
155; X64-NEXT:    callq foo
156; X64-NEXT:    popq %rax
157; X64-NEXT:    retq
158entry:
159  %tmp29 = ashr i32 %x, %n
160  %tmp3 = and i32 1, %tmp29
161  %tmp4 = icmp eq i32 %tmp3, 0
162  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
163
164bb:
165  call void @foo()
166  ret void
167
168UnifiedReturnBlock:
169  ret void
170}
171
172define void @test3(i32 %x, i32 %n) nounwind {
173; X86-LABEL: test3:
174; X86:       # %bb.0: # %entry
175; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
176; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
177; X86-NEXT:    btl %ecx, %eax
178; X86-NEXT:    jae .LBB4_1
179; X86-NEXT:  # %bb.2: # %UnifiedReturnBlock
180; X86-NEXT:    retl
181; X86-NEXT:  .LBB4_1: # %bb
182; X86-NEXT:    calll foo
183; X86-NEXT:    retl
184;
185; X64-LABEL: test3:
186; X64:       # %bb.0: # %entry
187; X64-NEXT:    btl %esi, %edi
188; X64-NEXT:    jae .LBB4_1
189; X64-NEXT:  # %bb.2: # %UnifiedReturnBlock
190; X64-NEXT:    retq
191; X64-NEXT:  .LBB4_1: # %bb
192; X64-NEXT:    pushq %rax
193; X64-NEXT:    callq foo
194; X64-NEXT:    popq %rax
195; X64-NEXT:    retq
196entry:
197  %tmp29 = shl i32 1, %n
198  %tmp3 = and i32 %tmp29, %x
199  %tmp4 = icmp eq i32 %tmp3, 0
200  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
201
202bb:
203  call void @foo()
204  ret void
205
206UnifiedReturnBlock:
207  ret void
208}
209
210define void @test3b(i32 %x, i32 %n) nounwind {
211; X86-LABEL: test3b:
212; X86:       # %bb.0: # %entry
213; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
214; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
215; X86-NEXT:    btl %ecx, %eax
216; X86-NEXT:    jae .LBB5_1
217; X86-NEXT:  # %bb.2: # %UnifiedReturnBlock
218; X86-NEXT:    retl
219; X86-NEXT:  .LBB5_1: # %bb
220; X86-NEXT:    calll foo
221; X86-NEXT:    retl
222;
223; X64-LABEL: test3b:
224; X64:       # %bb.0: # %entry
225; X64-NEXT:    btl %esi, %edi
226; X64-NEXT:    jae .LBB5_1
227; X64-NEXT:  # %bb.2: # %UnifiedReturnBlock
228; X64-NEXT:    retq
229; X64-NEXT:  .LBB5_1: # %bb
230; X64-NEXT:    pushq %rax
231; X64-NEXT:    callq foo
232; X64-NEXT:    popq %rax
233; X64-NEXT:    retq
234entry:
235  %tmp29 = shl i32 1, %n
236  %tmp3 = and i32 %x, %tmp29
237  %tmp4 = icmp eq i32 %tmp3, 0
238  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
239
240bb:
241  call void @foo()
242  ret void
243
244UnifiedReturnBlock:
245  ret void
246}
247
248define void @testne2(i32 %x, i32 %n) nounwind {
249; X86-LABEL: testne2:
250; X86:       # %bb.0: # %entry
251; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
252; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
253; X86-NEXT:    btl %ecx, %eax
254; X86-NEXT:    jae .LBB6_2
255; X86-NEXT:  # %bb.1: # %bb
256; X86-NEXT:    calll foo
257; X86-NEXT:  .LBB6_2: # %UnifiedReturnBlock
258; X86-NEXT:    retl
259;
260; X64-LABEL: testne2:
261; X64:       # %bb.0: # %entry
262; X64-NEXT:    btl %esi, %edi
263; X64-NEXT:    jae .LBB6_2
264; X64-NEXT:  # %bb.1: # %bb
265; X64-NEXT:    pushq %rax
266; X64-NEXT:    callq foo
267; X64-NEXT:    popq %rax
268; X64-NEXT:  .LBB6_2: # %UnifiedReturnBlock
269; X64-NEXT:    retq
270entry:
271  %tmp29 = lshr i32 %x, %n
272  %tmp3 = and i32 %tmp29, 1
273  %tmp4 = icmp ne i32 %tmp3, 0
274  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
275
276bb:
277  call void @foo()
278  ret void
279
280UnifiedReturnBlock:
281  ret void
282}
283
284define void @testne2b(i32 %x, i32 %n) nounwind {
285; X86-LABEL: testne2b:
286; X86:       # %bb.0: # %entry
287; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
288; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
289; X86-NEXT:    btl %ecx, %eax
290; X86-NEXT:    jae .LBB7_2
291; X86-NEXT:  # %bb.1: # %bb
292; X86-NEXT:    calll foo
293; X86-NEXT:  .LBB7_2: # %UnifiedReturnBlock
294; X86-NEXT:    retl
295;
296; X64-LABEL: testne2b:
297; X64:       # %bb.0: # %entry
298; X64-NEXT:    btl %esi, %edi
299; X64-NEXT:    jae .LBB7_2
300; X64-NEXT:  # %bb.1: # %bb
301; X64-NEXT:    pushq %rax
302; X64-NEXT:    callq foo
303; X64-NEXT:    popq %rax
304; X64-NEXT:  .LBB7_2: # %UnifiedReturnBlock
305; X64-NEXT:    retq
306entry:
307  %tmp29 = lshr i32 %x, %n
308  %tmp3 = and i32 1, %tmp29
309  %tmp4 = icmp ne i32 %tmp3, 0
310  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
311
312bb:
313  call void @foo()
314  ret void
315
316UnifiedReturnBlock:
317  ret void
318}
319
320define void @atestne2(i32 %x, i32 %n) nounwind {
321; X86-LABEL: atestne2:
322; X86:       # %bb.0: # %entry
323; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
324; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
325; X86-NEXT:    btl %ecx, %eax
326; X86-NEXT:    jae .LBB8_2
327; X86-NEXT:  # %bb.1: # %bb
328; X86-NEXT:    calll foo
329; X86-NEXT:  .LBB8_2: # %UnifiedReturnBlock
330; X86-NEXT:    retl
331;
332; X64-LABEL: atestne2:
333; X64:       # %bb.0: # %entry
334; X64-NEXT:    btl %esi, %edi
335; X64-NEXT:    jae .LBB8_2
336; X64-NEXT:  # %bb.1: # %bb
337; X64-NEXT:    pushq %rax
338; X64-NEXT:    callq foo
339; X64-NEXT:    popq %rax
340; X64-NEXT:  .LBB8_2: # %UnifiedReturnBlock
341; X64-NEXT:    retq
342entry:
343  %tmp29 = ashr i32 %x, %n
344  %tmp3 = and i32 %tmp29, 1
345  %tmp4 = icmp ne i32 %tmp3, 0
346  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
347
348bb:
349  call void @foo()
350  ret void
351
352UnifiedReturnBlock:
353  ret void
354}
355
356define void @atestne2b(i32 %x, i32 %n) nounwind {
357; X86-LABEL: atestne2b:
358; X86:       # %bb.0: # %entry
359; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
360; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
361; X86-NEXT:    btl %ecx, %eax
362; X86-NEXT:    jae .LBB9_2
363; X86-NEXT:  # %bb.1: # %bb
364; X86-NEXT:    calll foo
365; X86-NEXT:  .LBB9_2: # %UnifiedReturnBlock
366; X86-NEXT:    retl
367;
368; X64-LABEL: atestne2b:
369; X64:       # %bb.0: # %entry
370; X64-NEXT:    btl %esi, %edi
371; X64-NEXT:    jae .LBB9_2
372; X64-NEXT:  # %bb.1: # %bb
373; X64-NEXT:    pushq %rax
374; X64-NEXT:    callq foo
375; X64-NEXT:    popq %rax
376; X64-NEXT:  .LBB9_2: # %UnifiedReturnBlock
377; X64-NEXT:    retq
378entry:
379  %tmp29 = ashr i32 %x, %n
380  %tmp3 = and i32 1, %tmp29
381  %tmp4 = icmp ne i32 %tmp3, 0
382  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
383
384bb:
385  call void @foo()
386  ret void
387
388UnifiedReturnBlock:
389  ret void
390}
391
392define void @testne3(i32 %x, i32 %n) nounwind {
393; X86-LABEL: testne3:
394; X86:       # %bb.0: # %entry
395; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
396; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
397; X86-NEXT:    btl %ecx, %eax
398; X86-NEXT:    jae .LBB10_2
399; X86-NEXT:  # %bb.1: # %bb
400; X86-NEXT:    calll foo
401; X86-NEXT:  .LBB10_2: # %UnifiedReturnBlock
402; X86-NEXT:    retl
403;
404; X64-LABEL: testne3:
405; X64:       # %bb.0: # %entry
406; X64-NEXT:    btl %esi, %edi
407; X64-NEXT:    jae .LBB10_2
408; X64-NEXT:  # %bb.1: # %bb
409; X64-NEXT:    pushq %rax
410; X64-NEXT:    callq foo
411; X64-NEXT:    popq %rax
412; X64-NEXT:  .LBB10_2: # %UnifiedReturnBlock
413; X64-NEXT:    retq
414entry:
415  %tmp29 = shl i32 1, %n
416  %tmp3 = and i32 %tmp29, %x
417  %tmp4 = icmp ne i32 %tmp3, 0
418  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
419
420bb:
421  call void @foo()
422  ret void
423
424UnifiedReturnBlock:
425  ret void
426}
427
428define void @testne3b(i32 %x, i32 %n) nounwind {
429; X86-LABEL: testne3b:
430; X86:       # %bb.0: # %entry
431; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
432; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
433; X86-NEXT:    btl %ecx, %eax
434; X86-NEXT:    jae .LBB11_2
435; X86-NEXT:  # %bb.1: # %bb
436; X86-NEXT:    calll foo
437; X86-NEXT:  .LBB11_2: # %UnifiedReturnBlock
438; X86-NEXT:    retl
439;
440; X64-LABEL: testne3b:
441; X64:       # %bb.0: # %entry
442; X64-NEXT:    btl %esi, %edi
443; X64-NEXT:    jae .LBB11_2
444; X64-NEXT:  # %bb.1: # %bb
445; X64-NEXT:    pushq %rax
446; X64-NEXT:    callq foo
447; X64-NEXT:    popq %rax
448; X64-NEXT:  .LBB11_2: # %UnifiedReturnBlock
449; X64-NEXT:    retq
450entry:
451  %tmp29 = shl i32 1, %n
452  %tmp3 = and i32 %x, %tmp29
453  %tmp4 = icmp ne i32 %tmp3, 0
454  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
455
456bb:
457  call void @foo()
458  ret void
459
460UnifiedReturnBlock:
461  ret void
462}
463
464define void @query2(i32 %x, i32 %n) nounwind {
465; X86-LABEL: query2:
466; X86:       # %bb.0: # %entry
467; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
468; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
469; X86-NEXT:    btl %ecx, %eax
470; X86-NEXT:    jae .LBB12_2
471; X86-NEXT:  # %bb.1: # %bb
472; X86-NEXT:    calll foo
473; X86-NEXT:  .LBB12_2: # %UnifiedReturnBlock
474; X86-NEXT:    retl
475;
476; X64-LABEL: query2:
477; X64:       # %bb.0: # %entry
478; X64-NEXT:    btl %esi, %edi
479; X64-NEXT:    jae .LBB12_2
480; X64-NEXT:  # %bb.1: # %bb
481; X64-NEXT:    pushq %rax
482; X64-NEXT:    callq foo
483; X64-NEXT:    popq %rax
484; X64-NEXT:  .LBB12_2: # %UnifiedReturnBlock
485; X64-NEXT:    retq
486entry:
487  %tmp29 = lshr i32 %x, %n
488  %tmp3 = and i32 %tmp29, 1
489  %tmp4 = icmp eq i32 %tmp3, 1
490  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
491
492bb:
493  call void @foo()
494  ret void
495
496UnifiedReturnBlock:
497  ret void
498}
499
500define void @query2b(i32 %x, i32 %n) nounwind {
501; X86-LABEL: query2b:
502; X86:       # %bb.0: # %entry
503; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
504; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
505; X86-NEXT:    btl %ecx, %eax
506; X86-NEXT:    jae .LBB13_2
507; X86-NEXT:  # %bb.1: # %bb
508; X86-NEXT:    calll foo
509; X86-NEXT:  .LBB13_2: # %UnifiedReturnBlock
510; X86-NEXT:    retl
511;
512; X64-LABEL: query2b:
513; X64:       # %bb.0: # %entry
514; X64-NEXT:    btl %esi, %edi
515; X64-NEXT:    jae .LBB13_2
516; X64-NEXT:  # %bb.1: # %bb
517; X64-NEXT:    pushq %rax
518; X64-NEXT:    callq foo
519; X64-NEXT:    popq %rax
520; X64-NEXT:  .LBB13_2: # %UnifiedReturnBlock
521; X64-NEXT:    retq
522entry:
523  %tmp29 = lshr i32 %x, %n
524  %tmp3 = and i32 1, %tmp29
525  %tmp4 = icmp eq i32 %tmp3, 1
526  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
527
528bb:
529  call void @foo()
530  ret void
531
532UnifiedReturnBlock:
533  ret void
534}
535
536define void @aquery2(i32 %x, i32 %n) nounwind {
537; X86-LABEL: aquery2:
538; X86:       # %bb.0: # %entry
539; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
540; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
541; X86-NEXT:    btl %ecx, %eax
542; X86-NEXT:    jae .LBB14_2
543; X86-NEXT:  # %bb.1: # %bb
544; X86-NEXT:    calll foo
545; X86-NEXT:  .LBB14_2: # %UnifiedReturnBlock
546; X86-NEXT:    retl
547;
548; X64-LABEL: aquery2:
549; X64:       # %bb.0: # %entry
550; X64-NEXT:    btl %esi, %edi
551; X64-NEXT:    jae .LBB14_2
552; X64-NEXT:  # %bb.1: # %bb
553; X64-NEXT:    pushq %rax
554; X64-NEXT:    callq foo
555; X64-NEXT:    popq %rax
556; X64-NEXT:  .LBB14_2: # %UnifiedReturnBlock
557; X64-NEXT:    retq
558entry:
559  %tmp29 = ashr i32 %x, %n
560  %tmp3 = and i32 %tmp29, 1
561  %tmp4 = icmp eq i32 %tmp3, 1
562  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
563
564bb:
565  call void @foo()
566  ret void
567
568UnifiedReturnBlock:
569  ret void
570}
571
572define void @aquery2b(i32 %x, i32 %n) nounwind {
573; X86-LABEL: aquery2b:
574; X86:       # %bb.0: # %entry
575; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
576; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
577; X86-NEXT:    btl %ecx, %eax
578; X86-NEXT:    jae .LBB15_2
579; X86-NEXT:  # %bb.1: # %bb
580; X86-NEXT:    calll foo
581; X86-NEXT:  .LBB15_2: # %UnifiedReturnBlock
582; X86-NEXT:    retl
583;
584; X64-LABEL: aquery2b:
585; X64:       # %bb.0: # %entry
586; X64-NEXT:    btl %esi, %edi
587; X64-NEXT:    jae .LBB15_2
588; X64-NEXT:  # %bb.1: # %bb
589; X64-NEXT:    pushq %rax
590; X64-NEXT:    callq foo
591; X64-NEXT:    popq %rax
592; X64-NEXT:  .LBB15_2: # %UnifiedReturnBlock
593; X64-NEXT:    retq
594entry:
595  %tmp29 = ashr i32 %x, %n
596  %tmp3 = and i32 1, %tmp29
597  %tmp4 = icmp eq i32 %tmp3, 1
598  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
599
600bb:
601  call void @foo()
602  ret void
603
604UnifiedReturnBlock:
605  ret void
606}
607
608define void @query3(i32 %x, i32 %n) nounwind {
609; X86-LABEL: query3:
610; X86:       # %bb.0: # %entry
611; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
612; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
613; X86-NEXT:    btl %ecx, %eax
614; X86-NEXT:    jae .LBB16_2
615; X86-NEXT:  # %bb.1: # %bb
616; X86-NEXT:    calll foo
617; X86-NEXT:  .LBB16_2: # %UnifiedReturnBlock
618; X86-NEXT:    retl
619;
620; X64-LABEL: query3:
621; X64:       # %bb.0: # %entry
622; X64-NEXT:    btl %esi, %edi
623; X64-NEXT:    jae .LBB16_2
624; X64-NEXT:  # %bb.1: # %bb
625; X64-NEXT:    pushq %rax
626; X64-NEXT:    callq foo
627; X64-NEXT:    popq %rax
628; X64-NEXT:  .LBB16_2: # %UnifiedReturnBlock
629; X64-NEXT:    retq
630entry:
631  %tmp29 = shl i32 1, %n
632  %tmp3 = and i32 %tmp29, %x
633  %tmp4 = icmp eq i32 %tmp3, %tmp29
634  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
635
636bb:
637  call void @foo()
638  ret void
639
640UnifiedReturnBlock:
641  ret void
642}
643
644define void @query3b(i32 %x, i32 %n) nounwind {
645; X86-LABEL: query3b:
646; X86:       # %bb.0: # %entry
647; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
648; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
649; X86-NEXT:    btl %ecx, %eax
650; X86-NEXT:    jae .LBB17_2
651; X86-NEXT:  # %bb.1: # %bb
652; X86-NEXT:    calll foo
653; X86-NEXT:  .LBB17_2: # %UnifiedReturnBlock
654; X86-NEXT:    retl
655;
656; X64-LABEL: query3b:
657; X64:       # %bb.0: # %entry
658; X64-NEXT:    btl %esi, %edi
659; X64-NEXT:    jae .LBB17_2
660; X64-NEXT:  # %bb.1: # %bb
661; X64-NEXT:    pushq %rax
662; X64-NEXT:    callq foo
663; X64-NEXT:    popq %rax
664; X64-NEXT:  .LBB17_2: # %UnifiedReturnBlock
665; X64-NEXT:    retq
666entry:
667  %tmp29 = shl i32 1, %n
668  %tmp3 = and i32 %x, %tmp29
669  %tmp4 = icmp eq i32 %tmp3, %tmp29
670  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
671
672bb:
673  call void @foo()
674  ret void
675
676UnifiedReturnBlock:
677  ret void
678}
679
680define void @query3x(i32 %x, i32 %n) nounwind {
681; X86-LABEL: query3x:
682; X86:       # %bb.0: # %entry
683; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
684; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
685; X86-NEXT:    btl %ecx, %eax
686; X86-NEXT:    jae .LBB18_2
687; X86-NEXT:  # %bb.1: # %bb
688; X86-NEXT:    calll foo
689; X86-NEXT:  .LBB18_2: # %UnifiedReturnBlock
690; X86-NEXT:    retl
691;
692; X64-LABEL: query3x:
693; X64:       # %bb.0: # %entry
694; X64-NEXT:    btl %esi, %edi
695; X64-NEXT:    jae .LBB18_2
696; X64-NEXT:  # %bb.1: # %bb
697; X64-NEXT:    pushq %rax
698; X64-NEXT:    callq foo
699; X64-NEXT:    popq %rax
700; X64-NEXT:  .LBB18_2: # %UnifiedReturnBlock
701; X64-NEXT:    retq
702entry:
703  %tmp29 = shl i32 1, %n
704  %tmp3 = and i32 %tmp29, %x
705  %tmp4 = icmp eq i32 %tmp29, %tmp3
706  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
707
708bb:
709  call void @foo()
710  ret void
711
712UnifiedReturnBlock:
713  ret void
714}
715
716define void @query3bx(i32 %x, i32 %n) nounwind {
717; X86-LABEL: query3bx:
718; X86:       # %bb.0: # %entry
719; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
720; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
721; X86-NEXT:    btl %ecx, %eax
722; X86-NEXT:    jae .LBB19_2
723; X86-NEXT:  # %bb.1: # %bb
724; X86-NEXT:    calll foo
725; X86-NEXT:  .LBB19_2: # %UnifiedReturnBlock
726; X86-NEXT:    retl
727;
728; X64-LABEL: query3bx:
729; X64:       # %bb.0: # %entry
730; X64-NEXT:    btl %esi, %edi
731; X64-NEXT:    jae .LBB19_2
732; X64-NEXT:  # %bb.1: # %bb
733; X64-NEXT:    pushq %rax
734; X64-NEXT:    callq foo
735; X64-NEXT:    popq %rax
736; X64-NEXT:  .LBB19_2: # %UnifiedReturnBlock
737; X64-NEXT:    retq
738entry:
739  %tmp29 = shl i32 1, %n
740  %tmp3 = and i32 %x, %tmp29
741  %tmp4 = icmp eq i32 %tmp29, %tmp3
742  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
743
744bb:
745  call void @foo()
746  ret void
747
748UnifiedReturnBlock:
749  ret void
750}
751
752define void @queryne2(i32 %x, i32 %n) nounwind {
753; X86-LABEL: queryne2:
754; X86:       # %bb.0: # %entry
755; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
756; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
757; X86-NEXT:    btl %ecx, %eax
758; X86-NEXT:    jb .LBB20_2
759; X86-NEXT:  # %bb.1: # %bb
760; X86-NEXT:    calll foo
761; X86-NEXT:  .LBB20_2: # %UnifiedReturnBlock
762; X86-NEXT:    retl
763;
764; X64-LABEL: queryne2:
765; X64:       # %bb.0: # %entry
766; X64-NEXT:    btl %esi, %edi
767; X64-NEXT:    jb .LBB20_2
768; X64-NEXT:  # %bb.1: # %bb
769; X64-NEXT:    pushq %rax
770; X64-NEXT:    callq foo
771; X64-NEXT:    popq %rax
772; X64-NEXT:  .LBB20_2: # %UnifiedReturnBlock
773; X64-NEXT:    retq
774entry:
775  %tmp29 = lshr i32 %x, %n
776  %tmp3 = and i32 %tmp29, 1
777  %tmp4 = icmp ne i32 %tmp3, 1
778  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
779
780bb:
781  call void @foo()
782  ret void
783
784UnifiedReturnBlock:
785  ret void
786}
787
788define void @queryne2b(i32 %x, i32 %n) nounwind {
789; X86-LABEL: queryne2b:
790; X86:       # %bb.0: # %entry
791; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
792; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
793; X86-NEXT:    btl %ecx, %eax
794; X86-NEXT:    jb .LBB21_2
795; X86-NEXT:  # %bb.1: # %bb
796; X86-NEXT:    calll foo
797; X86-NEXT:  .LBB21_2: # %UnifiedReturnBlock
798; X86-NEXT:    retl
799;
800; X64-LABEL: queryne2b:
801; X64:       # %bb.0: # %entry
802; X64-NEXT:    btl %esi, %edi
803; X64-NEXT:    jb .LBB21_2
804; X64-NEXT:  # %bb.1: # %bb
805; X64-NEXT:    pushq %rax
806; X64-NEXT:    callq foo
807; X64-NEXT:    popq %rax
808; X64-NEXT:  .LBB21_2: # %UnifiedReturnBlock
809; X64-NEXT:    retq
810entry:
811  %tmp29 = lshr i32 %x, %n
812  %tmp3 = and i32 1, %tmp29
813  %tmp4 = icmp ne i32 %tmp3, 1
814  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
815
816bb:
817  call void @foo()
818  ret void
819
820UnifiedReturnBlock:
821  ret void
822}
823
824define void @aqueryne2(i32 %x, i32 %n) nounwind {
825; X86-LABEL: aqueryne2:
826; X86:       # %bb.0: # %entry
827; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
828; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
829; X86-NEXT:    btl %ecx, %eax
830; X86-NEXT:    jb .LBB22_2
831; X86-NEXT:  # %bb.1: # %bb
832; X86-NEXT:    calll foo
833; X86-NEXT:  .LBB22_2: # %UnifiedReturnBlock
834; X86-NEXT:    retl
835;
836; X64-LABEL: aqueryne2:
837; X64:       # %bb.0: # %entry
838; X64-NEXT:    btl %esi, %edi
839; X64-NEXT:    jb .LBB22_2
840; X64-NEXT:  # %bb.1: # %bb
841; X64-NEXT:    pushq %rax
842; X64-NEXT:    callq foo
843; X64-NEXT:    popq %rax
844; X64-NEXT:  .LBB22_2: # %UnifiedReturnBlock
845; X64-NEXT:    retq
846entry:
847  %tmp29 = ashr i32 %x, %n
848  %tmp3 = and i32 %tmp29, 1
849  %tmp4 = icmp ne i32 %tmp3, 1
850  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
851
852bb:
853  call void @foo()
854  ret void
855
856UnifiedReturnBlock:
857  ret void
858}
859
860define void @aqueryne2b(i32 %x, i32 %n) nounwind {
861; X86-LABEL: aqueryne2b:
862; X86:       # %bb.0: # %entry
863; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
864; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
865; X86-NEXT:    btl %ecx, %eax
866; X86-NEXT:    jb .LBB23_2
867; X86-NEXT:  # %bb.1: # %bb
868; X86-NEXT:    calll foo
869; X86-NEXT:  .LBB23_2: # %UnifiedReturnBlock
870; X86-NEXT:    retl
871;
872; X64-LABEL: aqueryne2b:
873; X64:       # %bb.0: # %entry
874; X64-NEXT:    btl %esi, %edi
875; X64-NEXT:    jb .LBB23_2
876; X64-NEXT:  # %bb.1: # %bb
877; X64-NEXT:    pushq %rax
878; X64-NEXT:    callq foo
879; X64-NEXT:    popq %rax
880; X64-NEXT:  .LBB23_2: # %UnifiedReturnBlock
881; X64-NEXT:    retq
882entry:
883  %tmp29 = ashr i32 %x, %n
884  %tmp3 = and i32 1, %tmp29
885  %tmp4 = icmp ne i32 %tmp3, 1
886  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
887
888bb:
889  call void @foo()
890  ret void
891
892UnifiedReturnBlock:
893  ret void
894}
895
896define void @queryne3(i32 %x, i32 %n) nounwind {
897; X86-LABEL: queryne3:
898; X86:       # %bb.0: # %entry
899; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
900; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
901; X86-NEXT:    btl %ecx, %eax
902; X86-NEXT:    jb .LBB24_2
903; X86-NEXT:  # %bb.1: # %bb
904; X86-NEXT:    calll foo
905; X86-NEXT:  .LBB24_2: # %UnifiedReturnBlock
906; X86-NEXT:    retl
907;
908; X64-LABEL: queryne3:
909; X64:       # %bb.0: # %entry
910; X64-NEXT:    btl %esi, %edi
911; X64-NEXT:    jb .LBB24_2
912; X64-NEXT:  # %bb.1: # %bb
913; X64-NEXT:    pushq %rax
914; X64-NEXT:    callq foo
915; X64-NEXT:    popq %rax
916; X64-NEXT:  .LBB24_2: # %UnifiedReturnBlock
917; X64-NEXT:    retq
918entry:
919  %tmp29 = shl i32 1, %n
920  %tmp3 = and i32 %tmp29, %x
921  %tmp4 = icmp ne i32 %tmp3, %tmp29
922  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
923
924bb:
925  call void @foo()
926  ret void
927
928UnifiedReturnBlock:
929  ret void
930}
931
932define void @queryne3b(i32 %x, i32 %n) nounwind {
933; X86-LABEL: queryne3b:
934; X86:       # %bb.0: # %entry
935; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
936; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
937; X86-NEXT:    btl %ecx, %eax
938; X86-NEXT:    jb .LBB25_2
939; X86-NEXT:  # %bb.1: # %bb
940; X86-NEXT:    calll foo
941; X86-NEXT:  .LBB25_2: # %UnifiedReturnBlock
942; X86-NEXT:    retl
943;
944; X64-LABEL: queryne3b:
945; X64:       # %bb.0: # %entry
946; X64-NEXT:    btl %esi, %edi
947; X64-NEXT:    jb .LBB25_2
948; X64-NEXT:  # %bb.1: # %bb
949; X64-NEXT:    pushq %rax
950; X64-NEXT:    callq foo
951; X64-NEXT:    popq %rax
952; X64-NEXT:  .LBB25_2: # %UnifiedReturnBlock
953; X64-NEXT:    retq
954entry:
955  %tmp29 = shl i32 1, %n
956  %tmp3 = and i32 %x, %tmp29
957  %tmp4 = icmp ne i32 %tmp3, %tmp29
958  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
959
960bb:
961  call void @foo()
962  ret void
963
964UnifiedReturnBlock:
965  ret void
966}
967
968define void @queryne3x(i32 %x, i32 %n) nounwind {
969; X86-LABEL: queryne3x:
970; X86:       # %bb.0: # %entry
971; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
972; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
973; X86-NEXT:    btl %ecx, %eax
974; X86-NEXT:    jb .LBB26_2
975; X86-NEXT:  # %bb.1: # %bb
976; X86-NEXT:    calll foo
977; X86-NEXT:  .LBB26_2: # %UnifiedReturnBlock
978; X86-NEXT:    retl
979;
980; X64-LABEL: queryne3x:
981; X64:       # %bb.0: # %entry
982; X64-NEXT:    btl %esi, %edi
983; X64-NEXT:    jb .LBB26_2
984; X64-NEXT:  # %bb.1: # %bb
985; X64-NEXT:    pushq %rax
986; X64-NEXT:    callq foo
987; X64-NEXT:    popq %rax
988; X64-NEXT:  .LBB26_2: # %UnifiedReturnBlock
989; X64-NEXT:    retq
990entry:
991  %tmp29 = shl i32 1, %n
992  %tmp3 = and i32 %tmp29, %x
993  %tmp4 = icmp ne i32 %tmp29, %tmp3
994  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
995
996bb:
997  call void @foo()
998  ret void
999
1000UnifiedReturnBlock:
1001  ret void
1002}
1003
1004define void @queryne3bx(i32 %x, i32 %n) nounwind {
1005; X86-LABEL: queryne3bx:
1006; X86:       # %bb.0: # %entry
1007; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1008; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1009; X86-NEXT:    btl %ecx, %eax
1010; X86-NEXT:    jb .LBB27_2
1011; X86-NEXT:  # %bb.1: # %bb
1012; X86-NEXT:    calll foo
1013; X86-NEXT:  .LBB27_2: # %UnifiedReturnBlock
1014; X86-NEXT:    retl
1015;
1016; X64-LABEL: queryne3bx:
1017; X64:       # %bb.0: # %entry
1018; X64-NEXT:    btl %esi, %edi
1019; X64-NEXT:    jb .LBB27_2
1020; X64-NEXT:  # %bb.1: # %bb
1021; X64-NEXT:    pushq %rax
1022; X64-NEXT:    callq foo
1023; X64-NEXT:    popq %rax
1024; X64-NEXT:  .LBB27_2: # %UnifiedReturnBlock
1025; X64-NEXT:    retq
1026entry:
1027  %tmp29 = shl i32 1, %n
1028  %tmp3 = and i32 %x, %tmp29
1029  %tmp4 = icmp ne i32 %tmp29, %tmp3
1030  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
1031
1032bb:
1033  call void @foo()
1034  ret void
1035
1036UnifiedReturnBlock:
1037  ret void
1038}
1039
1040declare void @foo()
1041
1042define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind {
1043; X86-LABEL: invert:
1044; X86:       # %bb.0:
1045; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1046; X86-NEXT:    notl %eax
1047; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1048; X86-NEXT:    btl %ecx, %eax
1049; X86-NEXT:    setb %al
1050; X86-NEXT:    retl
1051;
1052; X64-LABEL: invert:
1053; X64:       # %bb.0:
1054; X64-NEXT:    notl %edi
1055; X64-NEXT:    btl %esi, %edi
1056; X64-NEXT:    setb %al
1057; X64-NEXT:    retq
1058  %neg = xor i32 %flags, -1
1059  %shl = shl i32 1, %flag
1060  %and = and i32 %shl, %neg
1061  %tobool = icmp ne i32 %and, 0
1062  ret i1 %tobool
1063}
1064
1065define zeroext i1 @extend(i32 %bit, i64 %bits) {
1066; X86-LABEL: extend:
1067; X86:       # %bb.0: # %entry
1068; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1069; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1070; X86-NEXT:    btl %eax, %ecx
1071; X86-NEXT:    setb %al
1072; X86-NEXT:    retl
1073;
1074; X64-LABEL: extend:
1075; X64:       # %bb.0: # %entry
1076; X64-NEXT:    btl %edi, %esi
1077; X64-NEXT:    setb %al
1078; X64-NEXT:    retq
1079entry:
1080  %and = and i32 %bit, 31
1081  %sh_prom = zext i32 %and to i64
1082  %shl = shl i64 1, %sh_prom
1083  %and1 = and i64 %shl, %bits
1084  %tobool = icmp ne i64 %and1, 0
1085  ret i1 %tobool
1086}
1087
1088; TODO: BT fails to look through to demanded bits as c%32 has more than one use.
1089; void demanded_i32(int *a, int *b, unsigned c) {
1090;   if ((a[c/32] >> (c % 32)) & 1)
1091;     b[c/32] |= 1 << (c % 32);
1092; }
1093define void @demanded_i32(i32* nocapture readonly, i32* nocapture, i32) nounwind {
1094; X86-LABEL: demanded_i32:
1095; X86:       # %bb.0:
1096; X86-NEXT:    pushl %esi
1097; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1098; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1099; X86-NEXT:    movl %ecx, %eax
1100; X86-NEXT:    shrl $5, %eax
1101; X86-NEXT:    movl (%edx,%eax,4), %esi
1102; X86-NEXT:    movl $1, %edx
1103; X86-NEXT:    shll %cl, %edx
1104; X86-NEXT:    btl %ecx, %esi
1105; X86-NEXT:    jae .LBB30_2
1106; X86-NEXT:  # %bb.1:
1107; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1108; X86-NEXT:    orl %edx, (%ecx,%eax,4)
1109; X86-NEXT:  .LBB30_2:
1110; X86-NEXT:    popl %esi
1111; X86-NEXT:    retl
1112;
1113; X64-LABEL: demanded_i32:
1114; X64:       # %bb.0:
1115; X64-NEXT:    movl %edx, %eax
1116; X64-NEXT:    shrl $5, %eax
1117; X64-NEXT:    movl (%rdi,%rax,4), %r8d
1118; X64-NEXT:    movl $1, %edi
1119; X64-NEXT:    movl %edx, %ecx
1120; X64-NEXT:    shll %cl, %edi
1121; X64-NEXT:    btl %edx, %r8d
1122; X64-NEXT:    jae .LBB30_2
1123; X64-NEXT:  # %bb.1:
1124; X64-NEXT:    orl %edi, (%rsi,%rax,4)
1125; X64-NEXT:  .LBB30_2:
1126; X64-NEXT:    retq
1127  %4 = lshr i32 %2, 5
1128  %5 = zext i32 %4 to i64
1129  %6 = getelementptr inbounds i32, i32* %0, i64 %5
1130  %7 = load i32, i32* %6, align 4
1131  %8 = and i32 %2, 31
1132  %9 = shl i32 1, %8
1133  %10 = and i32 %7, %9
1134  %11 = icmp eq i32 %10, 0
1135  br i1 %11, label %16, label %12
1136
1137; <label>:12:
1138  %13 = getelementptr inbounds i32, i32* %1, i64 %5
1139  %14 = load i32, i32* %13, align 4
1140  %15 = or i32 %14, %9
1141  store i32 %15, i32* %13, align 4
1142  br label %16
1143
1144; <label>:16:
1145  ret void
1146}
1147