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