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