1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s
4; PR3253
5
6; The register+memory form of the BT instruction should be usable on
7; pentium4, however it is currently disabled due to the register+memory
8; form having different semantics than the register+register form.
9
10; Test these patterns:
11;    (X & (1 << N))  != 0  -->  BT(X, N).
12;    ((X >>u N) & 1) != 0  -->  BT(X, N).
13; as well as several variations:
14;    - The second form can use an arithmetic shift.
15;    - Either form can use == instead of !=.
16;    - Either form can compare with an operand of the &
17;      instead of with 0.
18;    - The comparison can be commuted (only cases where neither
19;      operand is constant are included).
20;    - The and can be commuted.
21
22define void @test2(i32 %x, i32 %n) nounwind {
23; CHECK-LABEL: test2:
24; CHECK:       # BB#0: # %entry
25; CHECK-NEXT:    btl %esi, %edi
26; CHECK-NEXT:    jb .LBB0_2
27;
28entry:
29  %tmp29 = lshr i32 %x, %n
30  %tmp3 = and i32 %tmp29, 1
31  %tmp4 = icmp eq i32 %tmp3, 0
32  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
33
34bb:
35  call void @foo()
36  ret void
37
38UnifiedReturnBlock:
39  ret void
40}
41
42define void @test2b(i32 %x, i32 %n) nounwind {
43; CHECK-LABEL: test2b:
44; CHECK:       # BB#0: # %entry
45; CHECK-NEXT:    btl %esi, %edi
46; CHECK-NEXT:    jb .LBB1_2
47;
48entry:
49  %tmp29 = lshr i32 %x, %n
50  %tmp3 = and i32 1, %tmp29
51  %tmp4 = icmp eq i32 %tmp3, 0
52  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
53
54bb:
55  call void @foo()
56  ret void
57
58UnifiedReturnBlock:
59  ret void
60}
61
62define void @atest2(i32 %x, i32 %n) nounwind {
63; CHECK-LABEL: atest2:
64; CHECK:       # BB#0: # %entry
65; CHECK-NEXT:    btl %esi, %edi
66; CHECK-NEXT:    jb .LBB2_2
67;
68entry:
69  %tmp29 = ashr i32 %x, %n
70  %tmp3 = and i32 %tmp29, 1
71  %tmp4 = icmp eq i32 %tmp3, 0
72  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
73
74bb:
75  call void @foo()
76  ret void
77
78UnifiedReturnBlock:
79  ret void
80}
81
82define void @atest2b(i32 %x, i32 %n) nounwind {
83; CHECK-LABEL: atest2b:
84; CHECK:       # BB#0: # %entry
85; CHECK-NEXT:    btl %esi, %edi
86; CHECK-NEXT:    jb .LBB3_2
87;
88entry:
89  %tmp29 = ashr i32 %x, %n
90  %tmp3 = and i32 1, %tmp29
91  %tmp4 = icmp eq i32 %tmp3, 0
92  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
93
94bb:
95  call void @foo()
96  ret void
97
98UnifiedReturnBlock:
99  ret void
100}
101
102define void @test3(i32 %x, i32 %n) nounwind {
103; CHECK-LABEL: test3:
104; CHECK:       # BB#0: # %entry
105; CHECK-NEXT:    btl %esi, %edi
106; CHECK-NEXT:    jb .LBB4_2
107;
108entry:
109  %tmp29 = shl i32 1, %n
110  %tmp3 = and i32 %tmp29, %x
111  %tmp4 = icmp eq i32 %tmp3, 0
112  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
113
114bb:
115  call void @foo()
116  ret void
117
118UnifiedReturnBlock:
119  ret void
120}
121
122define void @test3b(i32 %x, i32 %n) nounwind {
123; CHECK-LABEL: test3b:
124; CHECK:       # BB#0: # %entry
125; CHECK-NEXT:    btl %esi, %edi
126; CHECK-NEXT:    jb .LBB5_2
127;
128entry:
129  %tmp29 = shl i32 1, %n
130  %tmp3 = and i32 %x, %tmp29
131  %tmp4 = icmp eq i32 %tmp3, 0
132  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
133
134bb:
135  call void @foo()
136  ret void
137
138UnifiedReturnBlock:
139  ret void
140}
141
142define void @testne2(i32 %x, i32 %n) nounwind {
143; CHECK-LABEL: testne2:
144; CHECK:       # BB#0: # %entry
145; CHECK-NEXT:    btl %esi, %edi
146; CHECK-NEXT:    jae .LBB6_2
147;
148entry:
149  %tmp29 = lshr i32 %x, %n
150  %tmp3 = and i32 %tmp29, 1
151  %tmp4 = icmp ne i32 %tmp3, 0
152  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
153
154bb:
155  call void @foo()
156  ret void
157
158UnifiedReturnBlock:
159  ret void
160}
161
162define void @testne2b(i32 %x, i32 %n) nounwind {
163; CHECK-LABEL: testne2b:
164; CHECK:       # BB#0: # %entry
165; CHECK-NEXT:    btl %esi, %edi
166; CHECK-NEXT:    jae .LBB7_2
167;
168entry:
169  %tmp29 = lshr i32 %x, %n
170  %tmp3 = and i32 1, %tmp29
171  %tmp4 = icmp ne i32 %tmp3, 0
172  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
173
174bb:
175  call void @foo()
176  ret void
177
178UnifiedReturnBlock:
179  ret void
180}
181
182define void @atestne2(i32 %x, i32 %n) nounwind {
183; CHECK-LABEL: atestne2:
184; CHECK:       # BB#0: # %entry
185; CHECK-NEXT:    btl %esi, %edi
186; CHECK-NEXT:    jae .LBB8_2
187;
188entry:
189  %tmp29 = ashr i32 %x, %n
190  %tmp3 = and i32 %tmp29, 1
191  %tmp4 = icmp ne i32 %tmp3, 0
192  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
193
194bb:
195  call void @foo()
196  ret void
197
198UnifiedReturnBlock:
199  ret void
200}
201
202define void @atestne2b(i32 %x, i32 %n) nounwind {
203; CHECK-LABEL: atestne2b:
204; CHECK:       # BB#0: # %entry
205; CHECK-NEXT:    btl %esi, %edi
206; CHECK-NEXT:    jae .LBB9_2
207;
208entry:
209  %tmp29 = ashr i32 %x, %n
210  %tmp3 = and i32 1, %tmp29
211  %tmp4 = icmp ne i32 %tmp3, 0
212  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
213
214bb:
215  call void @foo()
216  ret void
217
218UnifiedReturnBlock:
219  ret void
220}
221
222define void @testne3(i32 %x, i32 %n) nounwind {
223; CHECK-LABEL: testne3:
224; CHECK:       # BB#0: # %entry
225; CHECK-NEXT:    btl %esi, %edi
226; CHECK-NEXT:    jae .LBB10_2
227;
228entry:
229  %tmp29 = shl i32 1, %n
230  %tmp3 = and i32 %tmp29, %x
231  %tmp4 = icmp ne i32 %tmp3, 0
232  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
233
234bb:
235  call void @foo()
236  ret void
237
238UnifiedReturnBlock:
239  ret void
240}
241
242define void @testne3b(i32 %x, i32 %n) nounwind {
243; CHECK-LABEL: testne3b:
244; CHECK:       # BB#0: # %entry
245; CHECK-NEXT:    btl %esi, %edi
246; CHECK-NEXT:    jae .LBB11_2
247;
248entry:
249  %tmp29 = shl i32 1, %n
250  %tmp3 = and i32 %x, %tmp29
251  %tmp4 = icmp ne i32 %tmp3, 0
252  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
253
254bb:
255  call void @foo()
256  ret void
257
258UnifiedReturnBlock:
259  ret void
260}
261
262define void @query2(i32 %x, i32 %n) nounwind {
263; CHECK-LABEL: query2:
264; CHECK:       # BB#0: # %entry
265; CHECK-NEXT:    btl %esi, %edi
266; CHECK-NEXT:    jae .LBB12_2
267;
268entry:
269  %tmp29 = lshr i32 %x, %n
270  %tmp3 = and i32 %tmp29, 1
271  %tmp4 = icmp eq i32 %tmp3, 1
272  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
273
274bb:
275  call void @foo()
276  ret void
277
278UnifiedReturnBlock:
279  ret void
280}
281
282define void @query2b(i32 %x, i32 %n) nounwind {
283; CHECK-LABEL: query2b:
284; CHECK:       # BB#0: # %entry
285; CHECK-NEXT:    btl %esi, %edi
286; CHECK-NEXT:    jae .LBB13_2
287;
288entry:
289  %tmp29 = lshr i32 %x, %n
290  %tmp3 = and i32 1, %tmp29
291  %tmp4 = icmp eq i32 %tmp3, 1
292  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
293
294bb:
295  call void @foo()
296  ret void
297
298UnifiedReturnBlock:
299  ret void
300}
301
302define void @aquery2(i32 %x, i32 %n) nounwind {
303; CHECK-LABEL: aquery2:
304; CHECK:       # BB#0: # %entry
305; CHECK-NEXT:    btl %esi, %edi
306; CHECK-NEXT:    jae .LBB14_2
307;
308entry:
309  %tmp29 = ashr i32 %x, %n
310  %tmp3 = and i32 %tmp29, 1
311  %tmp4 = icmp eq i32 %tmp3, 1
312  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
313
314bb:
315  call void @foo()
316  ret void
317
318UnifiedReturnBlock:
319  ret void
320}
321
322define void @aquery2b(i32 %x, i32 %n) nounwind {
323; CHECK-LABEL: aquery2b:
324; CHECK:       # BB#0: # %entry
325; CHECK-NEXT:    btl %esi, %edi
326; CHECK-NEXT:    jae .LBB15_2
327;
328entry:
329  %tmp29 = ashr i32 %x, %n
330  %tmp3 = and i32 1, %tmp29
331  %tmp4 = icmp eq i32 %tmp3, 1
332  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
333
334bb:
335  call void @foo()
336  ret void
337
338UnifiedReturnBlock:
339  ret void
340}
341
342define void @query3(i32 %x, i32 %n) nounwind {
343; CHECK-LABEL: query3:
344; CHECK:       # BB#0: # %entry
345; CHECK-NEXT:    btl %esi, %edi
346; CHECK-NEXT:    jae .LBB16_2
347;
348entry:
349  %tmp29 = shl i32 1, %n
350  %tmp3 = and i32 %tmp29, %x
351  %tmp4 = icmp eq i32 %tmp3, %tmp29
352  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
353
354bb:
355  call void @foo()
356  ret void
357
358UnifiedReturnBlock:
359  ret void
360}
361
362define void @query3b(i32 %x, i32 %n) nounwind {
363; CHECK-LABEL: query3b:
364; CHECK:       # BB#0: # %entry
365; CHECK-NEXT:    btl %esi, %edi
366; CHECK-NEXT:    jae .LBB17_2
367;
368entry:
369  %tmp29 = shl i32 1, %n
370  %tmp3 = and i32 %x, %tmp29
371  %tmp4 = icmp eq i32 %tmp3, %tmp29
372  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
373
374bb:
375  call void @foo()
376  ret void
377
378UnifiedReturnBlock:
379  ret void
380}
381
382define void @query3x(i32 %x, i32 %n) nounwind {
383; CHECK-LABEL: query3x:
384; CHECK:       # BB#0: # %entry
385; CHECK-NEXT:    btl %esi, %edi
386; CHECK-NEXT:    jae .LBB18_2
387;
388entry:
389  %tmp29 = shl i32 1, %n
390  %tmp3 = and i32 %tmp29, %x
391  %tmp4 = icmp eq i32 %tmp29, %tmp3
392  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
393
394bb:
395  call void @foo()
396  ret void
397
398UnifiedReturnBlock:
399  ret void
400}
401
402define void @query3bx(i32 %x, i32 %n) nounwind {
403; CHECK-LABEL: query3bx:
404; CHECK:       # BB#0: # %entry
405; CHECK-NEXT:    btl %esi, %edi
406; CHECK-NEXT:    jae .LBB19_2
407;
408entry:
409  %tmp29 = shl i32 1, %n
410  %tmp3 = and i32 %x, %tmp29
411  %tmp4 = icmp eq i32 %tmp29, %tmp3
412  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
413
414bb:
415  call void @foo()
416  ret void
417
418UnifiedReturnBlock:
419  ret void
420}
421
422define void @queryne2(i32 %x, i32 %n) nounwind {
423; CHECK-LABEL: queryne2:
424; CHECK:       # BB#0: # %entry
425; CHECK-NEXT:    btl %esi, %edi
426; CHECK-NEXT:    jb .LBB20_2
427;
428entry:
429  %tmp29 = lshr i32 %x, %n
430  %tmp3 = and i32 %tmp29, 1
431  %tmp4 = icmp ne i32 %tmp3, 1
432  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
433
434bb:
435  call void @foo()
436  ret void
437
438UnifiedReturnBlock:
439  ret void
440}
441
442define void @queryne2b(i32 %x, i32 %n) nounwind {
443; CHECK-LABEL: queryne2b:
444; CHECK:       # BB#0: # %entry
445; CHECK-NEXT:    btl %esi, %edi
446; CHECK-NEXT:    jb .LBB21_2
447;
448entry:
449  %tmp29 = lshr i32 %x, %n
450  %tmp3 = and i32 1, %tmp29
451  %tmp4 = icmp ne i32 %tmp3, 1
452  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
453
454bb:
455  call void @foo()
456  ret void
457
458UnifiedReturnBlock:
459  ret void
460}
461
462define void @aqueryne2(i32 %x, i32 %n) nounwind {
463; CHECK-LABEL: aqueryne2:
464; CHECK:       # BB#0: # %entry
465; CHECK-NEXT:    btl %esi, %edi
466; CHECK-NEXT:    jb .LBB22_2
467;
468entry:
469  %tmp29 = ashr i32 %x, %n
470  %tmp3 = and i32 %tmp29, 1
471  %tmp4 = icmp ne i32 %tmp3, 1
472  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
473
474bb:
475  call void @foo()
476  ret void
477
478UnifiedReturnBlock:
479  ret void
480}
481
482define void @aqueryne2b(i32 %x, i32 %n) nounwind {
483; CHECK-LABEL: aqueryne2b:
484; CHECK:       # BB#0: # %entry
485; CHECK-NEXT:    btl %esi, %edi
486; CHECK-NEXT:    jb .LBB23_2
487;
488entry:
489  %tmp29 = ashr i32 %x, %n
490  %tmp3 = and i32 1, %tmp29
491  %tmp4 = icmp ne i32 %tmp3, 1
492  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
493
494bb:
495  call void @foo()
496  ret void
497
498UnifiedReturnBlock:
499  ret void
500}
501
502define void @queryne3(i32 %x, i32 %n) nounwind {
503; CHECK-LABEL: queryne3:
504; CHECK:       # BB#0: # %entry
505; CHECK-NEXT:    btl %esi, %edi
506; CHECK-NEXT:    jb .LBB24_2
507;
508entry:
509  %tmp29 = shl i32 1, %n
510  %tmp3 = and i32 %tmp29, %x
511  %tmp4 = icmp ne i32 %tmp3, %tmp29
512  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
513
514bb:
515  call void @foo()
516  ret void
517
518UnifiedReturnBlock:
519  ret void
520}
521
522define void @queryne3b(i32 %x, i32 %n) nounwind {
523; CHECK-LABEL: queryne3b:
524; CHECK:       # BB#0: # %entry
525; CHECK-NEXT:    btl %esi, %edi
526; CHECK-NEXT:    jb .LBB25_2
527;
528entry:
529  %tmp29 = shl i32 1, %n
530  %tmp3 = and i32 %x, %tmp29
531  %tmp4 = icmp ne i32 %tmp3, %tmp29
532  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
533
534bb:
535  call void @foo()
536  ret void
537
538UnifiedReturnBlock:
539  ret void
540}
541
542define void @queryne3x(i32 %x, i32 %n) nounwind {
543; CHECK-LABEL: queryne3x:
544; CHECK:       # BB#0: # %entry
545; CHECK-NEXT:    btl %esi, %edi
546; CHECK-NEXT:    jb .LBB26_2
547;
548entry:
549  %tmp29 = shl i32 1, %n
550  %tmp3 = and i32 %tmp29, %x
551  %tmp4 = icmp ne i32 %tmp29, %tmp3
552  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
553
554bb:
555  call void @foo()
556  ret void
557
558UnifiedReturnBlock:
559  ret void
560}
561
562define void @queryne3bx(i32 %x, i32 %n) nounwind {
563; CHECK-LABEL: queryne3bx:
564; CHECK:       # BB#0: # %entry
565; CHECK-NEXT:    btl %esi, %edi
566; CHECK-NEXT:    jb .LBB27_2
567;
568entry:
569  %tmp29 = shl i32 1, %n
570  %tmp3 = and i32 %x, %tmp29
571  %tmp4 = icmp ne i32 %tmp29, %tmp3
572  br i1 %tmp4, label %bb, label %UnifiedReturnBlock
573
574bb:
575  call void @foo()
576  ret void
577
578UnifiedReturnBlock:
579  ret void
580}
581
582declare void @foo()
583
584define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind {
585; CHECK-LABEL: invert:
586; CHECK:       # BB#0:
587; CHECK-NEXT:    notl %edi
588; CHECK-NEXT:    btl %esi, %edi
589; CHECK-NEXT:    setb %al
590; CHECK-NEXT:    retq
591;
592  %neg = xor i32 %flags, -1
593  %shl = shl i32 1, %flag
594  %and = and i32 %shl, %neg
595  %tobool = icmp ne i32 %and, 0
596  ret i1 %tobool
597}
598
599define zeroext i1 @extend(i32 %bit, i64 %bits) {
600; CHECK-LABEL: extend:
601; CHECK:       # BB#0:
602; CHECK-NEXT:  btl %edi, %esi
603entry:
604  %and = and i32 %bit, 31
605  %sh_prom = zext i32 %and to i64
606  %shl = shl i64 1, %sh_prom
607  %and1 = and i64 %shl, %bits
608  %tobool = icmp ne i64 %and1, 0
609  ret i1 %tobool
610}
611