xref: /llvm-project/llvm/test/CodeGen/SystemZ/int-cmp-47.ll (revision a1710eb3cd5823c5d14899112ca3086acbdbe9cb)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; Test the use of TEST UNDER MASK for 64-bit operations.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
6
7@g = global i32 0
8
9; Check the lowest useful TMLL value.
10define void @f1(i64 %a) {
11; CHECK-LABEL: f1:
12; CHECK:       # %bb.0: # %entry
13; CHECK-NEXT:    tmll %r2, 1
14; CHECK-NEXT:    ber %r14
15; CHECK-NEXT:  .LBB0_1: # %store
16; CHECK-NEXT:    lgrl %r1, g@GOT
17; CHECK-NEXT:    mvhi 0(%r1), 1
18; CHECK-NEXT:    br %r14
19entry:
20  %and = and i64 %a, 1
21  %cmp = icmp eq i64 %and, 0
22  br i1 %cmp, label %exit, label %store
23
24store:
25  store i32 1, ptr@g
26  br label %exit
27
28exit:
29  ret void
30}
31
32; Check the high end of the TMLL range.
33define void @f2(i64 %a) {
34; CHECK-LABEL: f2:
35; CHECK:       # %bb.0: # %entry
36; CHECK-NEXT:    tmll %r2, 65535
37; CHECK-NEXT:    bner %r14
38; CHECK-NEXT:  .LBB1_1: # %store
39; CHECK-NEXT:    lgrl %r1, g@GOT
40; CHECK-NEXT:    mvhi 0(%r1), 1
41; CHECK-NEXT:    br %r14
42entry:
43  %and = and i64 %a, 65535
44  %cmp = icmp ne i64 %and, 0
45  br i1 %cmp, label %exit, label %store
46
47store:
48  store i32 1, ptr@g
49  br label %exit
50
51exit:
52  ret void
53}
54
55; Check the lowest useful TMLH value, which is the next value up.
56define void @f3(i64 %a) {
57; CHECK-LABEL: f3:
58; CHECK:       # %bb.0: # %entry
59; CHECK-NEXT:    tmlh %r2, 1
60; CHECK-NEXT:    bner %r14
61; CHECK-NEXT:  .LBB2_1: # %store
62; CHECK-NEXT:    lgrl %r1, g@GOT
63; CHECK-NEXT:    mvhi 0(%r1), 1
64; CHECK-NEXT:    br %r14
65entry:
66  %and = and i64 %a, 65536
67  %cmp = icmp ne i64 %and, 0
68  br i1 %cmp, label %exit, label %store
69
70store:
71  store i32 1, ptr@g
72  br label %exit
73
74exit:
75  ret void
76}
77
78; Check the next value up again, which cannot use TM.
79define void @f4(i64 %a) {
80; CHECK-LABEL: f4:
81; CHECK:       # %bb.0: # %entry
82; CHECK-NEXT:    llilf %r0, 4294901759
83; CHECK-NEXT:    ngr %r0, %r2
84; CHECK-NEXT:    ber %r14
85; CHECK-NEXT:  .LBB3_1: # %store
86; CHECK-NEXT:    lgrl %r1, g@GOT
87; CHECK-NEXT:    mvhi 0(%r1), 1
88; CHECK-NEXT:    br %r14
89entry:
90  %and = and i64 %a, 4294901759
91  %cmp = icmp eq i64 %and, 0
92  br i1 %cmp, label %exit, label %store
93
94store:
95  store i32 1, ptr@g
96  br label %exit
97
98exit:
99  ret void
100}
101
102; Check the high end of the TMLH range.
103define void @f5(i64 %a) {
104; CHECK-LABEL: f5:
105; CHECK:       # %bb.0: # %entry
106; CHECK-NEXT:    tmlh %r2, 65535
107; CHECK-NEXT:    ber %r14
108; CHECK-NEXT:  .LBB4_1: # %store
109; CHECK-NEXT:    lgrl %r1, g@GOT
110; CHECK-NEXT:    mvhi 0(%r1), 1
111; CHECK-NEXT:    br %r14
112entry:
113  %and = and i64 %a, 4294901760
114  %cmp = icmp eq i64 %and, 0
115  br i1 %cmp, label %exit, label %store
116
117store:
118  store i32 1, ptr@g
119  br label %exit
120
121exit:
122  ret void
123}
124
125; Check the lowest useful TMHL value.
126define void @f6(i64 %a) {
127; CHECK-LABEL: f6:
128; CHECK:       # %bb.0: # %entry
129; CHECK-NEXT:    tmhl %r2, 1
130; CHECK-NEXT:    ber %r14
131; CHECK-NEXT:  .LBB5_1: # %store
132; CHECK-NEXT:    lgrl %r1, g@GOT
133; CHECK-NEXT:    mvhi 0(%r1), 1
134; CHECK-NEXT:    br %r14
135entry:
136  %and = and i64 %a, 4294967296
137  %cmp = icmp eq i64 %and, 0
138  br i1 %cmp, label %exit, label %store
139
140store:
141  store i32 1, ptr@g
142  br label %exit
143
144exit:
145  ret void
146}
147
148; Check the next value up again, which cannot use TM.
149define void @f7(i64 %a) {
150; CHECK-LABEL: f7:
151; CHECK:       # %bb.0: # %entry
152; CHECK-NEXT:    llihl %r0, 1
153; CHECK-NEXT:    oill %r0, 1
154; CHECK-NEXT:    ngr %r0, %r2
155; CHECK-NEXT:    blr %r14
156; CHECK-NEXT:  .LBB6_1: # %store
157; CHECK-NEXT:    lgrl %r1, g@GOT
158; CHECK-NEXT:    mvhi 0(%r1), 1
159; CHECK-NEXT:    br %r14
160entry:
161  %and = and i64 %a, 4294967297
162  %cmp = icmp ne i64 %and, 0
163  br i1 %cmp, label %exit, label %store
164
165store:
166  store i32 1, ptr@g
167  br label %exit
168
169exit:
170  ret void
171}
172
173; Check the high end of the TMHL range.
174define void @f8(i64 %a) {
175; CHECK-LABEL: f8:
176; CHECK:       # %bb.0: # %entry
177; CHECK-NEXT:    tmhl %r2, 65535
178; CHECK-NEXT:    bner %r14
179; CHECK-NEXT:  .LBB7_1: # %store
180; CHECK-NEXT:    lgrl %r1, g@GOT
181; CHECK-NEXT:    mvhi 0(%r1), 1
182; CHECK-NEXT:    br %r14
183entry:
184  %and = and i64 %a, 281470681743360
185  %cmp = icmp ne i64 %and, 0
186  br i1 %cmp, label %exit, label %store
187
188store:
189  store i32 1, ptr@g
190  br label %exit
191
192exit:
193  ret void
194}
195
196; Check the lowest useful TMHH value.
197define void @f9(i64 %a) {
198; CHECK-LABEL: f9:
199; CHECK:       # %bb.0: # %entry
200; CHECK-NEXT:    tmhh %r2, 1
201; CHECK-NEXT:    bner %r14
202; CHECK-NEXT:  .LBB8_1: # %store
203; CHECK-NEXT:    lgrl %r1, g@GOT
204; CHECK-NEXT:    mvhi 0(%r1), 1
205; CHECK-NEXT:    br %r14
206entry:
207  %and = and i64 %a, 281474976710656
208  %cmp = icmp ne i64 %and, 0
209  br i1 %cmp, label %exit, label %store
210
211store:
212  store i32 1, ptr@g
213  br label %exit
214
215exit:
216  ret void
217}
218
219; Check the high end of the TMHH range.
220define void @f10(i64 %a) {
221; CHECK-LABEL: f10:
222; CHECK:       # %bb.0: # %entry
223; CHECK-NEXT:    tmhh %r2, 65535
224; CHECK-NEXT:    ber %r14
225; CHECK-NEXT:  .LBB9_1: # %store
226; CHECK-NEXT:    lgrl %r1, g@GOT
227; CHECK-NEXT:    mvhi 0(%r1), 1
228; CHECK-NEXT:    br %r14
229entry:
230  %and = and i64 %a, 18446462598732840960
231  %cmp = icmp eq i64 %and, 0
232  br i1 %cmp, label %exit, label %store
233
234store:
235  store i32 1, ptr@g
236  br label %exit
237
238exit:
239  ret void
240}
241
242; Check that we can fold an SHL into a TMxx mask.
243define void @f11(i64 %a) {
244; CHECK-LABEL: f11:
245; CHECK:       # %bb.0: # %entry
246; CHECK-NEXT:    tmhl %r2, 32768
247; CHECK-NEXT:    bner %r14
248; CHECK-NEXT:  .LBB10_1: # %store
249; CHECK-NEXT:    lgrl %r1, g@GOT
250; CHECK-NEXT:    mvhi 0(%r1), 1
251; CHECK-NEXT:    br %r14
252entry:
253  %shl = shl i64 %a, 1
254  %and = and i64 %shl, 281474976710656
255  %cmp = icmp ne i64 %and, 0
256  br i1 %cmp, label %exit, label %store
257
258store:
259  store i32 1, ptr@g
260  br label %exit
261
262exit:
263  ret void
264}
265
266; Check that we can fold an SHR into a TMxx mask.
267define void @f12(i64 %a) {
268; CHECK-LABEL: f12:
269; CHECK:       # %bb.0: # %entry
270; CHECK-NEXT:    tmhh %r2, 256
271; CHECK-NEXT:    bner %r14
272; CHECK-NEXT:  .LBB11_1: # %store
273; CHECK-NEXT:    lgrl %r1, g@GOT
274; CHECK-NEXT:    mvhi 0(%r1), 1
275; CHECK-NEXT:    br %r14
276entry:
277  %shr = lshr i64 %a, 56
278  %and = and i64 %shr, 1
279  %cmp = icmp ne i64 %and, 0
280  br i1 %cmp, label %exit, label %store
281
282store:
283  store i32 1, ptr@g
284  br label %exit
285
286exit:
287  ret void
288}
289
290; Check a case where TMHH can be used to implement a ult comparison.
291define void @f13(i64 %a) {
292; CHECK-LABEL: f13:
293; CHECK:       # %bb.0: # %entry
294; CHECK-NEXT:    tmhh %r2, 49152
295; CHECK-NEXT:    bnor %r14
296; CHECK-NEXT:  .LBB12_1: # %store
297; CHECK-NEXT:    lgrl %r1, g@GOT
298; CHECK-NEXT:    mvhi 0(%r1), 1
299; CHECK-NEXT:    br %r14
300entry:
301  %cmp = icmp ult i64 %a, 13835058055282163712
302  br i1 %cmp, label %exit, label %store
303
304store:
305  store i32 1, ptr@g
306  br label %exit
307
308exit:
309  ret void
310}
311
312; And again with ule.
313define void @f14(i64 %a) {
314; CHECK-LABEL: f14:
315; CHECK:       # %bb.0: # %entry
316; CHECK-NEXT:    tmhh %r2, 49152
317; CHECK-NEXT:    bnor %r14
318; CHECK-NEXT:  .LBB13_1: # %store
319; CHECK-NEXT:    lgrl %r1, g@GOT
320; CHECK-NEXT:    mvhi 0(%r1), 1
321; CHECK-NEXT:    br %r14
322entry:
323  %cmp = icmp ule i64 %a, 13835058055282163711
324  br i1 %cmp, label %exit, label %store
325
326store:
327  store i32 1, ptr@g
328  br label %exit
329
330exit:
331  ret void
332}
333
334; And again with ugt.
335define void @f15(i64 %a) {
336; CHECK-LABEL: f15:
337; CHECK:       # %bb.0: # %entry
338; CHECK-NEXT:    tmhh %r2, 49152
339; CHECK-NEXT:    bor %r14
340; CHECK-NEXT:  .LBB14_1: # %store
341; CHECK-NEXT:    lgrl %r1, g@GOT
342; CHECK-NEXT:    mvhi 0(%r1), 1
343; CHECK-NEXT:    br %r14
344entry:
345  %cmp = icmp ugt i64 %a, 13835058055282163711
346  br i1 %cmp, label %exit, label %store
347
348store:
349  store i32 1, ptr@g
350  br label %exit
351
352exit:
353  ret void
354}
355
356; And again with uge.
357define void @f16(i64 %a) {
358; CHECK-LABEL: f16:
359; CHECK:       # %bb.0: # %entry
360; CHECK-NEXT:    tmhh %r2, 49152
361; CHECK-NEXT:    bor %r14
362; CHECK-NEXT:  .LBB15_1: # %store
363; CHECK-NEXT:    lgrl %r1, g@GOT
364; CHECK-NEXT:    mvhi 0(%r1), 1
365; CHECK-NEXT:    br %r14
366entry:
367  %cmp = icmp uge i64 %a, 13835058055282163712
368  br i1 %cmp, label %exit, label %store
369
370store:
371  store i32 1, ptr@g
372  br label %exit
373
374exit:
375  ret void
376}
377
378; Decrease the constant from f13 to make TMHH invalid.
379define void @f17(i64 %a) {
380; CHECK-LABEL: f17:
381; CHECK:       # %bb.0: # %entry
382; CHECK-NEXT:    srlg %r0, %r2, 48
383; CHECK-NEXT:    cgfi %r0, 49151
384; CHECK-NEXT:    blr %r14
385; CHECK-NEXT:  .LBB16_1: # %store
386; CHECK-NEXT:    lgrl %r1, g@GOT
387; CHECK-NEXT:    mvhi 0(%r1), 1
388; CHECK-NEXT:    br %r14
389entry:
390  %cmp = icmp ult i64 %a, 13834776580305453056
391  br i1 %cmp, label %exit, label %store
392
393store:
394  store i32 1, ptr@g
395  br label %exit
396
397exit:
398  ret void
399}
400
401; Check that we don't use TMHH just to test the top bit.
402define void @f18(i64 %a) {
403; CHECK-LABEL: f18:
404; CHECK:       # %bb.0: # %entry
405; CHECK-NEXT:    cgibhe %r2, 0, 0(%r14)
406; CHECK-NEXT:  .LBB17_1: # %store
407; CHECK-NEXT:    lgrl %r1, g@GOT
408; CHECK-NEXT:    mvhi 0(%r1), 1
409; CHECK-NEXT:    br %r14
410entry:
411  %cmp = icmp ult i64 %a, 9223372036854775808
412  br i1 %cmp, label %exit, label %store
413
414store:
415  store i32 1, ptr@g
416  br label %exit
417
418exit:
419  ret void
420}
421
422; Check that we don't fold a shift if the comparison value
423; would need to be shifted out of range
424define void @f19(i64 %a) {
425; CHECK-LABEL: f19:
426; CHECK:       # %bb.0: # %entry
427; CHECK-NEXT:    srlg %r0, %r2, 63
428; CHECK-NEXT:    cgibl %r0, 3, 0(%r14)
429; CHECK-NEXT:  .LBB18_1: # %store
430; CHECK-NEXT:    lgrl %r1, g@GOT
431; CHECK-NEXT:    mvhi 0(%r1), 1
432; CHECK-NEXT:    br %r14
433entry:
434  %shr = lshr i64 %a, 63
435  %cmp = icmp ult i64 %shr, 3
436  br i1 %cmp, label %exit, label %store
437
438store:
439  store i32 1, ptr@g
440  br label %exit
441
442exit:
443  ret void
444}
445
446