1 ; Test 64-bit comparison in which the second operand is a zero-extended i32.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
7 ; Check unsigned register comparison.
8 define double @f1(double %a, double %b, i64 %i1, i32 %unext) {
10 ; CHECK: clgfr %r2, %r3
11 ; CHECK-NEXT: blr %r14
14 %i2 = zext i32 %unext to i64
15 %cond = icmp ult i64 %i1, %i2
16 %res = select i1 %cond, double %a, double %b
20 ; ...and again with a different representation.
21 define double @f2(double %a, double %b, i64 %i1, i64 %unext) {
23 ; CHECK: clgfr %r2, %r3
24 ; CHECK-NEXT: blr %r14
27 %i2 = and i64 %unext, 4294967295
28 %cond = icmp ult i64 %i1, %i2
29 %res = select i1 %cond, double %a, double %b
33 ; Check signed register comparison, which can't use CLGFR.
34 define double @f3(double %a, double %b, i64 %i1, i32 %unext) {
38 %i2 = zext i32 %unext to i64
39 %cond = icmp slt i64 %i1, %i2
40 %res = select i1 %cond, double %a, double %b
44 ; ...and again with a different representation
45 define double @f4(double %a, double %b, i64 %i1, i64 %unext) {
49 %i2 = and i64 %unext, 4294967295
50 %cond = icmp slt i64 %i1, %i2
51 %res = select i1 %cond, double %a, double %b
55 ; Check register equality.
56 define double @f5(double %a, double %b, i64 %i1, i32 %unext) {
58 ; CHECK: clgfr %r2, %r3
59 ; CHECK-NEXT: ber %r14
62 %i2 = zext i32 %unext to i64
63 %cond = icmp eq i64 %i1, %i2
64 %res = select i1 %cond, double %a, double %b
68 ; ...and again with a different representation
69 define double @f6(double %a, double %b, i64 %i1, i64 %unext) {
71 ; CHECK: clgfr %r2, %r3
72 ; CHECK-NEXT: ber %r14
75 %i2 = and i64 %unext, 4294967295
76 %cond = icmp eq i64 %i1, %i2
77 %res = select i1 %cond, double %a, double %b
81 ; Check register inequality.
82 define double @f7(double %a, double %b, i64 %i1, i32 %unext) {
84 ; CHECK: clgfr %r2, %r3
85 ; CHECK-NEXT: blhr %r14
88 %i2 = zext i32 %unext to i64
89 %cond = icmp ne i64 %i1, %i2
90 %res = select i1 %cond, double %a, double %b
94 ; ...and again with a different representation
95 define double @f8(double %a, double %b, i64 %i1, i64 %unext) {
97 ; CHECK: clgfr %r2, %r3
98 ; CHECK-NEXT: blhr %r14
101 %i2 = and i64 %unext, 4294967295
102 %cond = icmp ne i64 %i1, %i2
103 %res = select i1 %cond, double %a, double %b
107 ; Check unsigned comparison with memory.
108 define double @f9(double %a, double %b, i64 %i1, ptr %ptr) {
110 ; CHECK: clgf %r2, 0(%r3)
111 ; CHECK-NEXT: blr %r14
112 ; CHECK: ldr %f0, %f2
114 %unext = load i32, ptr %ptr
115 %i2 = zext i32 %unext to i64
116 %cond = icmp ult i64 %i1, %i2
117 %res = select i1 %cond, double %a, double %b
121 ; Check signed comparison with memory.
122 define double @f10(double %a, double %b, i64 %i1, ptr %ptr) {
126 %unext = load i32, ptr %ptr
127 %i2 = zext i32 %unext to i64
128 %cond = icmp slt i64 %i1, %i2
129 %res = select i1 %cond, double %a, double %b
133 ; Check memory equality.
134 define double @f11(double %a, double %b, i64 %i1, ptr %ptr) {
136 ; CHECK: clgf %r2, 0(%r3)
137 ; CHECK-NEXT: ber %r14
138 ; CHECK: ldr %f0, %f2
140 %unext = load i32, ptr %ptr
141 %i2 = zext i32 %unext to i64
142 %cond = icmp eq i64 %i1, %i2
143 %res = select i1 %cond, double %a, double %b
147 ; Check memory inequality.
148 define double @f12(double %a, double %b, i64 %i1, ptr %ptr) {
150 ; CHECK: clgf %r2, 0(%r3)
151 ; CHECK-NEXT: blhr %r14
152 ; CHECK: ldr %f0, %f2
154 %unext = load i32, ptr %ptr
155 %i2 = zext i32 %unext to i64
156 %cond = icmp ne i64 %i1, %i2
157 %res = select i1 %cond, double %a, double %b
161 ; Check the high end of the aligned CLGF range.
162 define double @f13(double %a, double %b, i64 %i1, ptr %base) {
164 ; CHECK: clgf %r2, 524284(%r3)
165 ; CHECK-NEXT: blr %r14
166 ; CHECK: ldr %f0, %f2
168 %ptr = getelementptr i32, ptr %base, i64 131071
169 %unext = load i32, ptr %ptr
170 %i2 = zext i32 %unext to i64
171 %cond = icmp ult i64 %i1, %i2
172 %res = select i1 %cond, double %a, double %b
176 ; Check the next word up, which needs separate address logic.
177 ; Other sequences besides this one would be OK.
178 define double @f14(double %a, double %b, i64 %i1, ptr %base) {
180 ; CHECK: agfi %r3, 524288
181 ; CHECK: clgf %r2, 0(%r3)
182 ; CHECK-NEXT: blr %r14
183 ; CHECK: ldr %f0, %f2
185 %ptr = getelementptr i32, ptr %base, i64 131072
186 %unext = load i32, ptr %ptr
187 %i2 = zext i32 %unext to i64
188 %cond = icmp ult i64 %i1, %i2
189 %res = select i1 %cond, double %a, double %b
193 ; Check the high end of the negative aligned CLGF range.
194 define double @f15(double %a, double %b, i64 %i1, ptr %base) {
196 ; CHECK: clgf %r2, -4(%r3)
197 ; CHECK-NEXT: blr %r14
198 ; CHECK: ldr %f0, %f2
200 %ptr = getelementptr i32, ptr %base, i64 -1
201 %unext = load i32, ptr %ptr
202 %i2 = zext i32 %unext to i64
203 %cond = icmp ult i64 %i1, %i2
204 %res = select i1 %cond, double %a, double %b
208 ; Check the low end of the CLGF range.
209 define double @f16(double %a, double %b, i64 %i1, ptr %base) {
211 ; CHECK: clgf %r2, -524288(%r3)
212 ; CHECK-NEXT: blr %r14
213 ; CHECK: ldr %f0, %f2
215 %ptr = getelementptr i32, ptr %base, i64 -131072
216 %unext = load i32, ptr %ptr
217 %i2 = zext i32 %unext to i64
218 %cond = icmp ult i64 %i1, %i2
219 %res = select i1 %cond, double %a, double %b
223 ; Check the next word down, which needs separate address logic.
224 ; Other sequences besides this one would be OK.
225 define double @f17(double %a, double %b, i64 %i1, ptr %base) {
227 ; CHECK: agfi %r3, -524292
228 ; CHECK: clgf %r2, 0(%r3)
229 ; CHECK-NEXT: blr %r14
230 ; CHECK: ldr %f0, %f2
232 %ptr = getelementptr i32, ptr %base, i64 -131073
233 %unext = load i32, ptr %ptr
234 %i2 = zext i32 %unext to i64
235 %cond = icmp ult i64 %i1, %i2
236 %res = select i1 %cond, double %a, double %b
240 ; Check that CLGF allows an index.
241 define double @f18(double %a, double %b, i64 %i1, i64 %base, i64 %index) {
243 ; CHECK: clgf %r2, 524284({{%r4,%r3|%r3,%r4}})
244 ; CHECK-NEXT: blr %r14
245 ; CHECK: ldr %f0, %f2
247 %add1 = add i64 %base, %index
248 %add2 = add i64 %add1, 524284
249 %ptr = inttoptr i64 %add2 to ptr
250 %unext = load i32, ptr %ptr
251 %i2 = zext i32 %unext to i64
252 %cond = icmp ult i64 %i1, %i2
253 %res = select i1 %cond, double %a, double %b
257 ; Check that comparisons of spilled values can use CLGF rather than CLGFR.
258 define i64 @f19(ptr %ptr0) {
260 ; CHECK: brasl %r14, foo@PLT
261 ; CHECK: clgf {{%r[0-9]+}}, 16{{[04]}}(%r15)
263 %ptr1 = getelementptr i32, ptr %ptr0, i64 2
264 %ptr2 = getelementptr i32, ptr %ptr0, i64 4
265 %ptr3 = getelementptr i32, ptr %ptr0, i64 6
266 %ptr4 = getelementptr i32, ptr %ptr0, i64 8
267 %ptr5 = getelementptr i32, ptr %ptr0, i64 10
268 %ptr6 = getelementptr i32, ptr %ptr0, i64 12
269 %ptr7 = getelementptr i32, ptr %ptr0, i64 14
270 %ptr8 = getelementptr i32, ptr %ptr0, i64 16
271 %ptr9 = getelementptr i32, ptr %ptr0, i64 18
273 %val0 = load i32, ptr %ptr0
274 %val1 = load i32, ptr %ptr1
275 %val2 = load i32, ptr %ptr2
276 %val3 = load i32, ptr %ptr3
277 %val4 = load i32, ptr %ptr4
278 %val5 = load i32, ptr %ptr5
279 %val6 = load i32, ptr %ptr6
280 %val7 = load i32, ptr %ptr7
281 %val8 = load i32, ptr %ptr8
282 %val9 = load i32, ptr %ptr9
284 %frob0 = add i32 %val0, 100
285 %frob1 = add i32 %val1, 100
286 %frob2 = add i32 %val2, 100
287 %frob3 = add i32 %val3, 100
288 %frob4 = add i32 %val4, 100
289 %frob5 = add i32 %val5, 100
290 %frob6 = add i32 %val6, 100
291 %frob7 = add i32 %val7, 100
292 %frob8 = add i32 %val8, 100
293 %frob9 = add i32 %val9, 100
295 store i32 %frob0, ptr %ptr0
296 store i32 %frob1, ptr %ptr1
297 store i32 %frob2, ptr %ptr2
298 store i32 %frob3, ptr %ptr3
299 store i32 %frob4, ptr %ptr4
300 store i32 %frob5, ptr %ptr5
301 store i32 %frob6, ptr %ptr6
302 store i32 %frob7, ptr %ptr7
303 store i32 %frob8, ptr %ptr8
304 store i32 %frob9, ptr %ptr9
306 %ret = call i64 @foo()
308 %ext0 = zext i32 %frob0 to i64
309 %ext1 = zext i32 %frob1 to i64
310 %ext2 = zext i32 %frob2 to i64
311 %ext3 = zext i32 %frob3 to i64
312 %ext4 = zext i32 %frob4 to i64
313 %ext5 = zext i32 %frob5 to i64
314 %ext6 = zext i32 %frob6 to i64
315 %ext7 = zext i32 %frob7 to i64
316 %ext8 = zext i32 %frob8 to i64
317 %ext9 = zext i32 %frob9 to i64
319 %cmp0 = icmp ult i64 %ret, %ext0
320 %cmp1 = icmp ult i64 %ret, %ext1
321 %cmp2 = icmp ult i64 %ret, %ext2
322 %cmp3 = icmp ult i64 %ret, %ext3
323 %cmp4 = icmp ult i64 %ret, %ext4
324 %cmp5 = icmp ult i64 %ret, %ext5
325 %cmp6 = icmp ult i64 %ret, %ext6
326 %cmp7 = icmp ult i64 %ret, %ext7
327 %cmp8 = icmp ult i64 %ret, %ext8
328 %cmp9 = icmp ult i64 %ret, %ext9
330 %sel0 = select i1 %cmp0, i64 %ret, i64 0
331 %sel1 = select i1 %cmp1, i64 %sel0, i64 1
332 %sel2 = select i1 %cmp2, i64 %sel1, i64 2
333 %sel3 = select i1 %cmp3, i64 %sel2, i64 3
334 %sel4 = select i1 %cmp4, i64 %sel3, i64 4
335 %sel5 = select i1 %cmp5, i64 %sel4, i64 5
336 %sel6 = select i1 %cmp6, i64 %sel5, i64 6
337 %sel7 = select i1 %cmp7, i64 %sel6, i64 7
338 %sel8 = select i1 %cmp8, i64 %sel7, i64 8
339 %sel9 = select i1 %cmp9, i64 %sel8, i64 9
344 ; Check the comparison can be reversed if that allows CLGFR to be used.
345 define double @f20(double %a, double %b, i64 %i1, i32 %unext) {
347 ; CHECK: clgfr %r2, %r3
348 ; CHECK-NEXT: bhr %r14
349 ; CHECK: ldr %f0, %f2
351 %i2 = zext i32 %unext to i64
352 %cond = icmp ult i64 %i2, %i1
353 %res = select i1 %cond, double %a, double %b
357 ; ...and again with the AND representation.
358 define double @f21(double %a, double %b, i64 %i1, i64 %unext) {
360 ; CHECK: clgfr %r2, %r3
361 ; CHECK-NEXT: bhr %r14
362 ; CHECK: ldr %f0, %f2
364 %i2 = and i64 %unext, 4294967295
365 %cond = icmp ult i64 %i2, %i1
366 %res = select i1 %cond, double %a, double %b
370 ; Check the comparison can be reversed if that allows CLGF to be used.
371 define double @f22(double %a, double %b, i64 %i2, ptr %ptr) {
373 ; CHECK: clgf %r2, 0(%r3)
374 ; CHECK-NEXT: bhr %r14
375 ; CHECK: ldr %f0, %f2
377 %unext = load i32, ptr %ptr
378 %i1 = zext i32 %unext to i64
379 %cond = icmp ult i64 %i1, %i2
380 %res = select i1 %cond, double %a, double %b