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.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
9 ; Check the lowest useful TMLL value.
10 define void @f1(i64 %a) {
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
21 %cmp = icmp eq i64 %and, 0
22 br i1 %cmp, label %exit, label %store
32 ; Check the high end of the TMLL range.
33 define void @f2(i64 %a) {
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
43 %and = and i64 %a, 65535
44 %cmp = icmp ne i64 %and, 0
45 br i1 %cmp, label %exit, label %store
55 ; Check the lowest useful TMLH value, which is the next value up.
56 define void @f3(i64 %a) {
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
66 %and = and i64 %a, 65536
67 %cmp = icmp ne i64 %and, 0
68 br i1 %cmp, label %exit, label %store
78 ; Check the next value up again, which cannot use TM.
79 define void @f4(i64 %a) {
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
90 %and = and i64 %a, 4294901759
91 %cmp = icmp eq i64 %and, 0
92 br i1 %cmp, label %exit, label %store
102 ; Check the high end of the TMLH range.
103 define void @f5(i64 %a) {
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
113 %and = and i64 %a, 4294901760
114 %cmp = icmp eq i64 %and, 0
115 br i1 %cmp, label %exit, label %store
125 ; Check the lowest useful TMHL value.
126 define void @f6(i64 %a) {
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
136 %and = and i64 %a, 4294967296
137 %cmp = icmp eq i64 %and, 0
138 br i1 %cmp, label %exit, label %store
148 ; Check the next value up again, which cannot use TM.
149 define void @f7(i64 %a) {
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
161 %and = and i64 %a, 4294967297
162 %cmp = icmp ne i64 %and, 0
163 br i1 %cmp, label %exit, label %store
173 ; Check the high end of the TMHL range.
174 define void @f8(i64 %a) {
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
184 %and = and i64 %a, 281470681743360
185 %cmp = icmp ne i64 %and, 0
186 br i1 %cmp, label %exit, label %store
196 ; Check the lowest useful TMHH value.
197 define void @f9(i64 %a) {
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
207 %and = and i64 %a, 281474976710656
208 %cmp = icmp ne i64 %and, 0
209 br i1 %cmp, label %exit, label %store
219 ; Check the high end of the TMHH range.
220 define void @f10(i64 %a) {
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
230 %and = and i64 %a, 18446462598732840960
231 %cmp = icmp eq i64 %and, 0
232 br i1 %cmp, label %exit, label %store
242 ; Check that we can fold an SHL into a TMxx mask.
243 define void @f11(i64 %a) {
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
254 %and = and i64 %shl, 281474976710656
255 %cmp = icmp ne i64 %and, 0
256 br i1 %cmp, label %exit, label %store
266 ; Check that we can fold an SHR into a TMxx mask.
267 define void @f12(i64 %a) {
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
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
290 ; Check a case where TMHH can be used to implement a ult comparison.
291 define void @f13(i64 %a) {
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
301 %cmp = icmp ult i64 %a, 13835058055282163712
302 br i1 %cmp, label %exit, label %store
312 ; And again with ule.
313 define void @f14(i64 %a) {
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
323 %cmp = icmp ule i64 %a, 13835058055282163711
324 br i1 %cmp, label %exit, label %store
334 ; And again with ugt.
335 define void @f15(i64 %a) {
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
345 %cmp = icmp ugt i64 %a, 13835058055282163711
346 br i1 %cmp, label %exit, label %store
356 ; And again with uge.
357 define void @f16(i64 %a) {
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
367 %cmp = icmp uge i64 %a, 13835058055282163712
368 br i1 %cmp, label %exit, label %store
378 ; Decrease the constant from f13 to make TMHH invalid.
379 define void @f17(i64 %a) {
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
390 %cmp = icmp ult i64 %a, 13834776580305453056
391 br i1 %cmp, label %exit, label %store
401 ; Check that we don't use TMHH just to test the top bit.
402 define void @f18(i64 %a) {
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
411 %cmp = icmp ult i64 %a, 9223372036854775808
412 br i1 %cmp, label %exit, label %store
422 ; Check that we don't fold a shift if the comparison value
423 ; would need to be shifted out of range
424 define void @f19(i64 %a) {
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
434 %shr = lshr i64 %a, 63
435 %cmp = icmp ult i64 %shr, 3
436 br i1 %cmp, label %exit, label %store