1; Test the use of TEST UNDER MASK for 32-bit operations.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
5@g = global i32 0
6
7; Check the lowest useful TMLL value.
8define void @f1(i32 %a) {
9; CHECK-LABEL: f1:
10; CHECK: tmll %r2, 1
11; CHECK: ber %r14
12; CHECK: br %r14
13entry:
14  %and = and i32 %a, 1
15  %cmp = icmp eq i32 %and, 0
16  br i1 %cmp, label %exit, label %store
17
18store:
19  store i32 1, i32 *@g
20  br label %exit
21
22exit:
23  ret void
24}
25
26; Check the high end of the TMLL range.
27define void @f2(i32 %a) {
28; CHECK-LABEL: f2:
29; CHECK: tmll %r2, 65535
30; CHECK: bner %r14
31; CHECK: br %r14
32entry:
33  %and = and i32 %a, 65535
34  %cmp = icmp ne i32 %and, 0
35  br i1 %cmp, label %exit, label %store
36
37store:
38  store i32 1, i32 *@g
39  br label %exit
40
41exit:
42  ret void
43}
44
45; Check the lowest useful TMLH value, which is the next value up.
46define void @f3(i32 %a) {
47; CHECK-LABEL: f3:
48; CHECK: tmlh %r2, 1
49; CHECK: bner %r14
50; CHECK: br %r14
51entry:
52  %and = and i32 %a, 65536
53  %cmp = icmp ne i32 %and, 0
54  br i1 %cmp, label %exit, label %store
55
56store:
57  store i32 1, i32 *@g
58  br label %exit
59
60exit:
61  ret void
62}
63
64; Check the next value up again, which cannot use TM.
65define void @f4(i32 %a) {
66; CHECK-LABEL: f4:
67; CHECK-NOT: {{tm[lh].}}
68; CHECK: br %r14
69entry:
70  %and = and i32 %a, 4294901759
71  %cmp = icmp eq i32 %and, 0
72  br i1 %cmp, label %exit, label %store
73
74store:
75  store i32 1, i32 *@g
76  br label %exit
77
78exit:
79  ret void
80}
81
82; Check the high end of the TMLH range.
83define void @f5(i32 %a) {
84; CHECK-LABEL: f5:
85; CHECK: tmlh %r2, 65535
86; CHECK: ber %r14
87; CHECK: br %r14
88entry:
89  %and = and i32 %a, 4294901760
90  %cmp = icmp eq i32 %and, 0
91  br i1 %cmp, label %exit, label %store
92
93store:
94  store i32 1, i32 *@g
95  br label %exit
96
97exit:
98  ret void
99}
100
101; Check that we can use TMLL for LT comparisons that are equivalent to
102; an equality comparison with zero.
103define void @f6(i32 %a) {
104; CHECK-LABEL: f6:
105; CHECK: tmll %r2, 240
106; CHECK: ber %r14
107; CHECK: br %r14
108entry:
109  %and = and i32 %a, 240
110  %cmp = icmp slt i32 %and, 16
111  br i1 %cmp, label %exit, label %store
112
113store:
114  store i32 1, i32 *@g
115  br label %exit
116
117exit:
118  ret void
119}
120
121; ...same again with LE.
122define void @f7(i32 %a) {
123; CHECK-LABEL: f7:
124; CHECK: tmll %r2, 240
125; CHECK: ber %r14
126; CHECK: br %r14
127entry:
128  %and = and i32 %a, 240
129  %cmp = icmp sle i32 %and, 15
130  br i1 %cmp, label %exit, label %store
131
132store:
133  store i32 1, i32 *@g
134  br label %exit
135
136exit:
137  ret void
138}
139
140; Check that we can use TMLL for GE comparisons that are equivalent to
141; an inequality comparison with zero.
142define void @f8(i32 %a) {
143; CHECK-LABEL: f8:
144; CHECK: tmll %r2, 240
145; CHECK: bner %r14
146; CHECK: br %r14
147entry:
148  %and = and i32 %a, 240
149  %cmp = icmp uge i32 %and, 16
150  br i1 %cmp, label %exit, label %store
151
152store:
153  store i32 1, i32 *@g
154  br label %exit
155
156exit:
157  ret void
158}
159
160; ...same again with GT.
161define void @f9(i32 %a) {
162; CHECK-LABEL: f9:
163; CHECK: tmll %r2, 240
164; CHECK: bner %r14
165; CHECK: br %r14
166entry:
167  %and = and i32 %a, 240
168  %cmp = icmp ugt i32 %and, 15
169  br i1 %cmp, label %exit, label %store
170
171store:
172  store i32 1, i32 *@g
173  br label %exit
174
175exit:
176  ret void
177}
178
179; Check that we can use TMLL for LT comparisons that effectively
180; test whether the top bit is clear.
181define void @f10(i32 %a) {
182; CHECK-LABEL: f10:
183; CHECK: tmll %r2, 35
184; CHECK: bler %r14
185; CHECK: br %r14
186entry:
187  %and = and i32 %a, 35
188  %cmp = icmp ult i32 %and, 8
189  br i1 %cmp, label %exit, label %store
190
191store:
192  store i32 1, i32 *@g
193  br label %exit
194
195exit:
196  ret void
197}
198
199; ...same again with LE.
200define void @f11(i32 %a) {
201; CHECK-LABEL: f11:
202; CHECK: tmll %r2, 35
203; CHECK: bler %r14
204; CHECK: br %r14
205entry:
206  %and = and i32 %a, 35
207  %cmp = icmp ule i32 %and, 31
208  br i1 %cmp, label %exit, label %store
209
210store:
211  store i32 1, i32 *@g
212  br label %exit
213
214exit:
215  ret void
216}
217
218; Check that we can use TMLL for GE comparisons that effectively test
219; whether the top bit is set.
220define void @f12(i32 %a) {
221; CHECK-LABEL: f12:
222; CHECK: tmll %r2, 140
223; CHECK: bnler %r14
224; CHECK: br %r14
225entry:
226  %and = and i32 %a, 140
227  %cmp = icmp uge i32 %and, 128
228  br i1 %cmp, label %exit, label %store
229
230store:
231  store i32 1, i32 *@g
232  br label %exit
233
234exit:
235  ret void
236}
237
238; ...same again for GT.
239define void @f13(i32 %a) {
240; CHECK-LABEL: f13:
241; CHECK: tmll %r2, 140
242; CHECK: bnler %r14
243; CHECK: br %r14
244entry:
245  %and = and i32 %a, 140
246  %cmp = icmp ugt i32 %and, 126
247  br i1 %cmp, label %exit, label %store
248
249store:
250  store i32 1, i32 *@g
251  br label %exit
252
253exit:
254  ret void
255}
256
257; Check that we can use TMLL for equality comparisons with the mask.
258define void @f14(i32 %a) {
259; CHECK-LABEL: f14:
260; CHECK: tmll %r2, 101
261; CHECK: bor %r14
262; CHECK: br %r14
263entry:
264  %and = and i32 %a, 101
265  %cmp = icmp eq i32 %and, 101
266  br i1 %cmp, label %exit, label %store
267
268store:
269  store i32 1, i32 *@g
270  br label %exit
271
272exit:
273  ret void
274}
275
276; Check that we can use TMLL for inequality comparisons with the mask.
277define void @f15(i32 %a) {
278; CHECK-LABEL: f15:
279; CHECK: tmll %r2, 65519
280; CHECK: bnor %r14
281; CHECK: br %r14
282entry:
283  %and = and i32 %a, 65519
284  %cmp = icmp ne i32 %and, 65519
285  br i1 %cmp, label %exit, label %store
286
287store:
288  store i32 1, i32 *@g
289  br label %exit
290
291exit:
292  ret void
293}
294
295; Check that we can use TMLL for LT comparisons that are equivalent
296; to inequality comparisons with the mask.
297define void @f16(i32 %a) {
298; CHECK-LABEL: f16:
299; CHECK: tmll %r2, 130
300; CHECK: bnor %r14
301; CHECK: br %r14
302entry:
303  %and = and i32 %a, 130
304  %cmp = icmp ult i32 %and, 129
305  br i1 %cmp, label %exit, label %store
306
307store:
308  store i32 1, i32 *@g
309  br label %exit
310
311exit:
312  ret void
313}
314
315; ...same again with LE.
316define void @f17(i32 %a) {
317; CHECK-LABEL: f17:
318; CHECK: tmll %r2, 130
319; CHECK: bnor %r14
320; CHECK: br %r14
321entry:
322  %and = and i32 %a, 130
323  %cmp = icmp ule i32 %and, 128
324  br i1 %cmp, label %exit, label %store
325
326store:
327  store i32 1, i32 *@g
328  br label %exit
329
330exit:
331  ret void
332}
333
334; Check that we can use TMLL for GE comparisons that are equivalent
335; to equality comparisons with the mask.
336define void @f18(i32 %a) {
337; CHECK-LABEL: f18:
338; CHECK: tmll %r2, 194
339; CHECK: bor %r14
340; CHECK: br %r14
341entry:
342  %and = and i32 %a, 194
343  %cmp = icmp uge i32 %and, 193
344  br i1 %cmp, label %exit, label %store
345
346store:
347  store i32 1, i32 *@g
348  br label %exit
349
350exit:
351  ret void
352}
353
354; ...same again for GT.
355define void @f19(i32 %a) {
356; CHECK-LABEL: f19:
357; CHECK: tmll %r2, 194
358; CHECK: bor %r14
359; CHECK: br %r14
360entry:
361  %and = and i32 %a, 194
362  %cmp = icmp ugt i32 %and, 192
363  br i1 %cmp, label %exit, label %store
364
365store:
366  store i32 1, i32 *@g
367  br label %exit
368
369exit:
370  ret void
371}
372
373; Check that we can use TMLL for equality comparisons for the low bit
374; when the mask has two bits.
375define void @f20(i32 %a) {
376; CHECK-LABEL: f20:
377; CHECK: tmll %r2, 20
378; CHECK: blr %r14
379; CHECK: br %r14
380entry:
381  %and = and i32 %a, 20
382  %cmp = icmp eq i32 %and, 4
383  br i1 %cmp, label %exit, label %store
384
385store:
386  store i32 1, i32 *@g
387  br label %exit
388
389exit:
390  ret void
391}
392
393; Check that we can use TMLL for inequality comparisons for the low bit
394; when the mask has two bits.
395define void @f21(i32 %a) {
396; CHECK-LABEL: f21:
397; CHECK: tmll %r2, 20
398; CHECK: bnlr %r14
399; CHECK: br %r14
400entry:
401  %and = and i32 %a, 20
402  %cmp = icmp ne i32 %and, 4
403  br i1 %cmp, label %exit, label %store
404
405store:
406  store i32 1, i32 *@g
407  br label %exit
408
409exit:
410  ret void
411}
412
413; Check that we can use TMLL for equality comparisons for the high bit
414; when the mask has two bits.
415define void @f22(i32 %a) {
416; CHECK-LABEL: f22:
417; CHECK: tmll %r2, 20
418; CHECK: bhr %r14
419; CHECK: br %r14
420entry:
421  %and = and i32 %a, 20
422  %cmp = icmp eq i32 %and, 16
423  br i1 %cmp, label %exit, label %store
424
425store:
426  store i32 1, i32 *@g
427  br label %exit
428
429exit:
430  ret void
431}
432
433; Check that we can use TMLL for inequality comparisons for the high bit
434; when the mask has two bits.
435define void @f23(i32 %a) {
436; CHECK-LABEL: f23:
437; CHECK: tmll %r2, 20
438; CHECK: bnhr %r14
439; CHECK: br %r14
440entry:
441  %and = and i32 %a, 20
442  %cmp = icmp ne i32 %and, 16
443  br i1 %cmp, label %exit, label %store
444
445store:
446  store i32 1, i32 *@g
447  br label %exit
448
449exit:
450  ret void
451}
452
453; Check that we can fold an SHL into a TMxx mask.
454define void @f24(i32 %a) {
455; CHECK-LABEL: f24:
456; CHECK: tmll %r2, 255
457; CHECK: bner %r14
458; CHECK: br %r14
459entry:
460  %shl = shl i32 %a, 12
461  %and = and i32 %shl, 1044480
462  %cmp = icmp ne i32 %and, 0
463  br i1 %cmp, label %exit, label %store
464
465store:
466  store i32 1, i32 *@g
467  br label %exit
468
469exit:
470  ret void
471}
472
473; Check that we can fold an SHR into a TMxx mask.
474define void @f25(i32 %a) {
475; CHECK-LABEL: f25:
476; CHECK: tmlh %r2, 512
477; CHECK: bner %r14
478; CHECK: br %r14
479entry:
480  %shr = lshr i32 %a, 25
481  %and = and i32 %shr, 1
482  %cmp = icmp ne i32 %and, 0
483  br i1 %cmp, label %exit, label %store
484
485store:
486  store i32 1, i32 *@g
487  br label %exit
488
489exit:
490  ret void
491}
492