• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test the use of TEST UNDER MASK for 64-bit operations.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
5
6@g = global i32 0
7
8; Check the lowest useful TMLL value.
9define void @f1(i64 %a) {
10; CHECK-LABEL: f1:
11; CHECK: tmll %r2, 1
12; CHECK: ber %r14
13; CHECK: br %r14
14entry:
15  %and = and i64 %a, 1
16  %cmp = icmp eq i64 %and, 0
17  br i1 %cmp, label %exit, label %store
18
19store:
20  store i32 1, i32 *@g
21  br label %exit
22
23exit:
24  ret void
25}
26
27; Check the high end of the TMLL range.
28define void @f2(i64 %a) {
29; CHECK-LABEL: f2:
30; CHECK: tmll %r2, 65535
31; CHECK: bner %r14
32; CHECK: br %r14
33entry:
34  %and = and i64 %a, 65535
35  %cmp = icmp ne i64 %and, 0
36  br i1 %cmp, label %exit, label %store
37
38store:
39  store i32 1, i32 *@g
40  br label %exit
41
42exit:
43  ret void
44}
45
46; Check the lowest useful TMLH value, which is the next value up.
47define void @f3(i64 %a) {
48; CHECK-LABEL: f3:
49; CHECK: tmlh %r2, 1
50; CHECK: bner %r14
51; CHECK: br %r14
52entry:
53  %and = and i64 %a, 65536
54  %cmp = icmp ne i64 %and, 0
55  br i1 %cmp, label %exit, label %store
56
57store:
58  store i32 1, i32 *@g
59  br label %exit
60
61exit:
62  ret void
63}
64
65; Check the next value up again, which cannot use TM.
66define void @f4(i64 %a) {
67; CHECK-LABEL: f4:
68; CHECK-NOT: {{tm[lh].}}
69; CHECK: br %r14
70entry:
71  %and = and i64 %a, 4294901759
72  %cmp = icmp eq i64 %and, 0
73  br i1 %cmp, label %exit, label %store
74
75store:
76  store i32 1, i32 *@g
77  br label %exit
78
79exit:
80  ret void
81}
82
83; Check the high end of the TMLH range.
84define void @f5(i64 %a) {
85; CHECK-LABEL: f5:
86; CHECK: tmlh %r2, 65535
87; CHECK: ber %r14
88; CHECK: br %r14
89entry:
90  %and = and i64 %a, 4294901760
91  %cmp = icmp eq i64 %and, 0
92  br i1 %cmp, label %exit, label %store
93
94store:
95  store i32 1, i32 *@g
96  br label %exit
97
98exit:
99  ret void
100}
101
102; Check the lowest useful TMHL value.
103define void @f6(i64 %a) {
104; CHECK-LABEL: f6:
105; CHECK: tmhl %r2, 1
106; CHECK: ber %r14
107; CHECK: br %r14
108entry:
109  %and = and i64 %a, 4294967296
110  %cmp = icmp eq i64 %and, 0
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; Check the next value up again, which cannot use TM.
122define void @f7(i64 %a) {
123; CHECK-LABEL: f7:
124; CHECK-NOT: {{tm[lh].}}
125; CHECK: br %r14
126entry:
127  %and = and i64 %a, 4294967297
128  %cmp = icmp ne i64 %and, 0
129  br i1 %cmp, label %exit, label %store
130
131store:
132  store i32 1, i32 *@g
133  br label %exit
134
135exit:
136  ret void
137}
138
139; Check the high end of the TMHL range.
140define void @f8(i64 %a) {
141; CHECK-LABEL: f8:
142; CHECK: tmhl %r2, 65535
143; CHECK: bner %r14
144; CHECK: br %r14
145entry:
146  %and = and i64 %a, 281470681743360
147  %cmp = icmp ne i64 %and, 0
148  br i1 %cmp, label %exit, label %store
149
150store:
151  store i32 1, i32 *@g
152  br label %exit
153
154exit:
155  ret void
156}
157
158; Check the lowest useful TMHH value.
159define void @f9(i64 %a) {
160; CHECK-LABEL: f9:
161; CHECK: tmhh %r2, 1
162; CHECK: bner %r14
163; CHECK: br %r14
164entry:
165  %and = and i64 %a, 281474976710656
166  %cmp = icmp ne i64 %and, 0
167  br i1 %cmp, label %exit, label %store
168
169store:
170  store i32 1, i32 *@g
171  br label %exit
172
173exit:
174  ret void
175}
176
177; Check the high end of the TMHH range.
178define void @f10(i64 %a) {
179; CHECK-LABEL: f10:
180; CHECK: tmhh %r2, 65535
181; CHECK: ber %r14
182; CHECK: br %r14
183entry:
184  %and = and i64 %a, 18446462598732840960
185  %cmp = icmp eq i64 %and, 0
186  br i1 %cmp, label %exit, label %store
187
188store:
189  store i32 1, i32 *@g
190  br label %exit
191
192exit:
193  ret void
194}
195
196; Check that we can fold an SHL into a TMxx mask.
197define void @f11(i64 %a) {
198; CHECK-LABEL: f11:
199; CHECK: tmhl %r2, 32768
200; CHECK: bner %r14
201; CHECK: br %r14
202entry:
203  %shl = shl i64 %a, 1
204  %and = and i64 %shl, 281474976710656
205  %cmp = icmp ne i64 %and, 0
206  br i1 %cmp, label %exit, label %store
207
208store:
209  store i32 1, i32 *@g
210  br label %exit
211
212exit:
213  ret void
214}
215
216; Check that we can fold an SHR into a TMxx mask.
217define void @f12(i64 %a) {
218; CHECK-LABEL: f12:
219; CHECK: tmhh %r2, 256
220; CHECK: bner %r14
221; CHECK: br %r14
222entry:
223  %shr = lshr i64 %a, 56
224  %and = and i64 %shr, 1
225  %cmp = icmp ne i64 %and, 0
226  br i1 %cmp, label %exit, label %store
227
228store:
229  store i32 1, i32 *@g
230  br label %exit
231
232exit:
233  ret void
234}
235
236; Check a case where TMHH can be used to implement a ult comparison.
237define void @f13(i64 %a) {
238; CHECK-LABEL: f13:
239; CHECK: tmhh %r2, 49152
240; CHECK: bnor %r14
241; CHECK: br %r14
242entry:
243  %cmp = icmp ult i64 %a, 13835058055282163712
244  br i1 %cmp, label %exit, label %store
245
246store:
247  store i32 1, i32 *@g
248  br label %exit
249
250exit:
251  ret void
252}
253
254; And again with ule.
255define void @f14(i64 %a) {
256; CHECK-LABEL: f14:
257; CHECK: tmhh %r2, 49152
258; CHECK: bnor %r14
259; CHECK: br %r14
260entry:
261  %cmp = icmp ule i64 %a, 13835058055282163711
262  br i1 %cmp, label %exit, label %store
263
264store:
265  store i32 1, i32 *@g
266  br label %exit
267
268exit:
269  ret void
270}
271
272; And again with ugt.
273define void @f15(i64 %a) {
274; CHECK-LABEL: f15:
275; CHECK: tmhh %r2, 49152
276; CHECK: bor %r14
277; CHECK: br %r14
278entry:
279  %cmp = icmp ugt i64 %a, 13835058055282163711
280  br i1 %cmp, label %exit, label %store
281
282store:
283  store i32 1, i32 *@g
284  br label %exit
285
286exit:
287  ret void
288}
289
290; And again with uge.
291define void @f16(i64 %a) {
292; CHECK-LABEL: f16:
293; CHECK: tmhh %r2, 49152
294; CHECK: bor %r14
295; CHECK: br %r14
296entry:
297  %cmp = icmp uge i64 %a, 13835058055282163712
298  br i1 %cmp, label %exit, label %store
299
300store:
301  store i32 1, i32 *@g
302  br label %exit
303
304exit:
305  ret void
306}
307
308; Decrease the constant from f13 to make TMHH invalid.
309define void @f17(i64 %a) {
310; CHECK-LABEL: f17:
311; CHECK-NOT: tmhh
312; CHECK: srlg [[REG:%r[0-5]]], %r2, 48
313; CHECK: cgfi [[REG]], 49151
314; CHECK-NOT: tmhh
315; CHECK: br %r14
316entry:
317  %cmp = icmp ult i64 %a, 13834776580305453056
318  br i1 %cmp, label %exit, label %store
319
320store:
321  store i32 1, i32 *@g
322  br label %exit
323
324exit:
325  ret void
326}
327
328; Check that we don't use TMHH just to test the top bit.
329define void @f18(i64 %a) {
330; CHECK-LABEL: f18:
331; CHECK-NOT: tmhh
332; CHECK: cgibhe %r2, 0, 0(%r14)
333; CHECK: br %r14
334entry:
335  %cmp = icmp ult i64 %a, 9223372036854775808
336  br i1 %cmp, label %exit, label %store
337
338store:
339  store i32 1, i32 *@g
340  br label %exit
341
342exit:
343  ret void
344}
345
346; Check that we don't fold a shift if the comparison value
347; would need to be shifted out of range
348define void @f19(i64 %a) {
349; CHECK-LABEL: f19:
350; CHECK-NOT: tmhh
351; CHECK: srlg [[REG:%r[0-5]]], %r2, 63
352; CHECK: cgibl [[REG]], 3, 0(%r14)
353; CHECK: br %r14
354entry:
355  %shr = lshr i64 %a, 63
356  %cmp = icmp ult i64 %shr, 3
357  br i1 %cmp, label %exit, label %store
358
359store:
360  store i32 1, i32 *@g
361  br label %exit
362
363exit:
364  ret void
365}
366
367