1 ; Test 64-bit comparison in which the second operand is a sign-extended i32.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
7 ; Check signed register comparison.
8 define double @f1(double %a, double %b, i64 %i1, i32 %unext) {
10 ; CHECK: cgfr %r2, %r3
11 ; CHECK-NEXT: blr %r14
14 %i2 = sext i32 %unext to i64
15 %cond = icmp slt i64 %i1, %i2
16 %res = select i1 %cond, double %a, double %b
20 ; Check unsigned register comparison, which can't use CGFR.
21 define double @f2(double %a, double %b, i64 %i1, i32 %unext) {
25 %i2 = sext i32 %unext to i64
26 %cond = icmp ult i64 %i1, %i2
27 %res = select i1 %cond, double %a, double %b
31 ; Check register equality.
32 define double @f3(double %a, double %b, i64 %i1, i32 %unext) {
34 ; CHECK: cgfr %r2, %r3
35 ; CHECK-NEXT: ber %r14
38 %i2 = sext i32 %unext to i64
39 %cond = icmp eq i64 %i1, %i2
40 %res = select i1 %cond, double %a, double %b
44 ; Check register inequality.
45 define double @f4(double %a, double %b, i64 %i1, i32 %unext) {
47 ; CHECK: cgfr %r2, %r3
48 ; CHECK-NEXT: blhr %r14
51 %i2 = sext i32 %unext to i64
52 %cond = icmp ne i64 %i1, %i2
53 %res = select i1 %cond, double %a, double %b
57 ; Check signed comparison with memory.
58 define double @f5(double %a, double %b, i64 %i1, i32 *%ptr) {
60 ; CHECK: cgf %r2, 0(%r3)
61 ; CHECK-NEXT: blr %r14
64 %unext = load i32, i32 *%ptr
65 %i2 = sext i32 %unext to i64
66 %cond = icmp slt i64 %i1, %i2
67 %res = select i1 %cond, double %a, double %b
71 ; Check unsigned comparison with memory.
72 define double @f6(double %a, double %b, i64 %i1, i32 *%ptr) {
76 %unext = load i32, i32 *%ptr
77 %i2 = sext i32 %unext to i64
78 %cond = icmp ult i64 %i1, %i2
79 %res = select i1 %cond, double %a, double %b
83 ; Check memory equality.
84 define double @f7(double %a, double %b, i64 %i1, i32 *%ptr) {
86 ; CHECK: cgf %r2, 0(%r3)
87 ; CHECK-NEXT: ber %r14
90 %unext = load i32, i32 *%ptr
91 %i2 = sext i32 %unext to i64
92 %cond = icmp eq i64 %i1, %i2
93 %res = select i1 %cond, double %a, double %b
97 ; Check memory inequality.
98 define double @f8(double %a, double %b, i64 %i1, i32 *%ptr) {
100 ; CHECK: cgf %r2, 0(%r3)
101 ; CHECK-NEXT: blhr %r14
102 ; CHECK: ldr %f0, %f2
104 %unext = load i32, i32 *%ptr
105 %i2 = sext i32 %unext to i64
106 %cond = icmp ne i64 %i1, %i2
107 %res = select i1 %cond, double %a, double %b
111 ; Check the high end of the aligned CGF range.
112 define double @f9(double %a, double %b, i64 %i1, i32 *%base) {
114 ; CHECK: cgf %r2, 524284(%r3)
115 ; CHECK-NEXT: blr %r14
116 ; CHECK: ldr %f0, %f2
118 %ptr = getelementptr i32, i32 *%base, i64 131071
119 %unext = load i32, i32 *%ptr
120 %i2 = sext i32 %unext to i64
121 %cond = icmp slt i64 %i1, %i2
122 %res = select i1 %cond, double %a, double %b
126 ; Check the next word up, which needs separate address logic.
127 ; Other sequences besides this one would be OK.
128 define double @f10(double %a, double %b, i64 %i1, i32 *%base) {
130 ; CHECK: agfi %r3, 524288
131 ; CHECK: cgf %r2, 0(%r3)
132 ; CHECK-NEXT: blr %r14
133 ; CHECK: ldr %f0, %f2
135 %ptr = getelementptr i32, i32 *%base, i64 131072
136 %unext = load i32, i32 *%ptr
137 %i2 = sext i32 %unext to i64
138 %cond = icmp slt i64 %i1, %i2
139 %res = select i1 %cond, double %a, double %b
143 ; Check the high end of the negative aligned CGF range.
144 define double @f11(double %a, double %b, i64 %i1, i32 *%base) {
146 ; CHECK: cgf %r2, -4(%r3)
147 ; CHECK-NEXT: blr %r14
148 ; CHECK: ldr %f0, %f2
150 %ptr = getelementptr i32, i32 *%base, i64 -1
151 %unext = load i32, i32 *%ptr
152 %i2 = sext i32 %unext to i64
153 %cond = icmp slt i64 %i1, %i2
154 %res = select i1 %cond, double %a, double %b
158 ; Check the low end of the CGF range.
159 define double @f12(double %a, double %b, i64 %i1, i32 *%base) {
161 ; CHECK: cgf %r2, -524288(%r3)
162 ; CHECK-NEXT: blr %r14
163 ; CHECK: ldr %f0, %f2
165 %ptr = getelementptr i32, i32 *%base, i64 -131072
166 %unext = load i32, i32 *%ptr
167 %i2 = sext i32 %unext to i64
168 %cond = icmp slt i64 %i1, %i2
169 %res = select i1 %cond, double %a, double %b
173 ; Check the next word down, which needs separate address logic.
174 ; Other sequences besides this one would be OK.
175 define double @f13(double %a, double %b, i64 %i1, i32 *%base) {
177 ; CHECK: agfi %r3, -524292
178 ; CHECK: cgf %r2, 0(%r3)
179 ; CHECK-NEXT: blr %r14
180 ; CHECK: ldr %f0, %f2
182 %ptr = getelementptr i32, i32 *%base, i64 -131073
183 %unext = load i32, i32 *%ptr
184 %i2 = sext i32 %unext to i64
185 %cond = icmp slt i64 %i1, %i2
186 %res = select i1 %cond, double %a, double %b
190 ; Check that CGF allows an index.
191 define double @f14(double %a, double %b, i64 %i1, i64 %base, i64 %index) {
193 ; CHECK: cgf %r2, 524284({{%r4,%r3|%r3,%r4}})
194 ; CHECK-NEXT: blr %r14
195 ; CHECK: ldr %f0, %f2
197 %add1 = add i64 %base, %index
198 %add2 = add i64 %add1, 524284
199 %ptr = inttoptr i64 %add2 to i32 *
200 %unext = load i32, i32 *%ptr
201 %i2 = sext i32 %unext to i64
202 %cond = icmp slt i64 %i1, %i2
203 %res = select i1 %cond, double %a, double %b
207 ; Check that comparisons of spilled values can use CGF rather than CGFR.
208 define i64 @f15(i32 *%ptr0) {
210 ; CHECK: brasl %r14, foo@PLT
211 ; CHECK: cgf {{%r[0-9]+}}, 16{{[04]}}(%r15)
213 %ptr1 = getelementptr i32, i32 *%ptr0, i64 2
214 %ptr2 = getelementptr i32, i32 *%ptr0, i64 4
215 %ptr3 = getelementptr i32, i32 *%ptr0, i64 6
216 %ptr4 = getelementptr i32, i32 *%ptr0, i64 8
217 %ptr5 = getelementptr i32, i32 *%ptr0, i64 10
218 %ptr6 = getelementptr i32, i32 *%ptr0, i64 12
219 %ptr7 = getelementptr i32, i32 *%ptr0, i64 14
220 %ptr8 = getelementptr i32, i32 *%ptr0, i64 16
221 %ptr9 = getelementptr i32, i32 *%ptr0, i64 18
223 %val0 = load i32, i32 *%ptr0
224 %val1 = load i32, i32 *%ptr1
225 %val2 = load i32, i32 *%ptr2
226 %val3 = load i32, i32 *%ptr3
227 %val4 = load i32, i32 *%ptr4
228 %val5 = load i32, i32 *%ptr5
229 %val6 = load i32, i32 *%ptr6
230 %val7 = load i32, i32 *%ptr7
231 %val8 = load i32, i32 *%ptr8
232 %val9 = load i32, i32 *%ptr9
234 %frob0 = add i32 %val0, 100
235 %frob1 = add i32 %val1, 100
236 %frob2 = add i32 %val2, 100
237 %frob3 = add i32 %val3, 100
238 %frob4 = add i32 %val4, 100
239 %frob5 = add i32 %val5, 100
240 %frob6 = add i32 %val6, 100
241 %frob7 = add i32 %val7, 100
242 %frob8 = add i32 %val8, 100
243 %frob9 = add i32 %val9, 100
245 store i32 %frob0, i32 *%ptr0
246 store i32 %frob1, i32 *%ptr1
247 store i32 %frob2, i32 *%ptr2
248 store i32 %frob3, i32 *%ptr3
249 store i32 %frob4, i32 *%ptr4
250 store i32 %frob5, i32 *%ptr5
251 store i32 %frob6, i32 *%ptr6
252 store i32 %frob7, i32 *%ptr7
253 store i32 %frob8, i32 *%ptr8
254 store i32 %frob9, i32 *%ptr9
256 %ret = call i64 @foo()
258 %ext0 = sext i32 %frob0 to i64
259 %ext1 = sext i32 %frob1 to i64
260 %ext2 = sext i32 %frob2 to i64
261 %ext3 = sext i32 %frob3 to i64
262 %ext4 = sext i32 %frob4 to i64
263 %ext5 = sext i32 %frob5 to i64
264 %ext6 = sext i32 %frob6 to i64
265 %ext7 = sext i32 %frob7 to i64
266 %ext8 = sext i32 %frob8 to i64
267 %ext9 = sext i32 %frob9 to i64
269 %cmp0 = icmp slt i64 %ret, %ext0
270 %cmp1 = icmp slt i64 %ret, %ext1
271 %cmp2 = icmp slt i64 %ret, %ext2
272 %cmp3 = icmp slt i64 %ret, %ext3
273 %cmp4 = icmp slt i64 %ret, %ext4
274 %cmp5 = icmp slt i64 %ret, %ext5
275 %cmp6 = icmp slt i64 %ret, %ext6
276 %cmp7 = icmp slt i64 %ret, %ext7
277 %cmp8 = icmp slt i64 %ret, %ext8
278 %cmp9 = icmp slt i64 %ret, %ext9
280 %sel0 = select i1 %cmp0, i64 %ret, i64 0
281 %sel1 = select i1 %cmp1, i64 %sel0, i64 1
282 %sel2 = select i1 %cmp2, i64 %sel1, i64 2
283 %sel3 = select i1 %cmp3, i64 %sel2, i64 3
284 %sel4 = select i1 %cmp4, i64 %sel3, i64 4
285 %sel5 = select i1 %cmp5, i64 %sel4, i64 5
286 %sel6 = select i1 %cmp6, i64 %sel5, i64 6
287 %sel7 = select i1 %cmp7, i64 %sel6, i64 7
288 %sel8 = select i1 %cmp8, i64 %sel7, i64 8
289 %sel9 = select i1 %cmp9, i64 %sel8, i64 9
294 ; Check the comparison can be reversed if that allows CGFR to be used.
295 define double @f16(double %a, double %b, i64 %i1, i32 %unext) {
297 ; CHECK: cgfr %r2, %r3
298 ; CHECK-NEXT: bhr %r14
299 ; CHECK: ldr %f0, %f2
301 %i2 = sext i32 %unext to i64
302 %cond = icmp slt i64 %i2, %i1
303 %res = select i1 %cond, double %a, double %b
308 define double @f17(double %a, double %b, i64 %i2, i32 *%ptr) {
310 ; CHECK: cgf %r2, 0(%r3)
311 ; CHECK-NEXT: bhr %r14
312 ; CHECK: ldr %f0, %f2
314 %unext = load i32, i32 *%ptr
315 %i1 = sext i32 %unext to i64
316 %cond = icmp slt i64 %i1, %i2
317 %res = select i1 %cond, double %a, double %b