383 lines · plain
1; Test 64-bit comparison in which the second operand is a zero-extended i32.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare i64 @foo()6 7; Check unsigned register comparison.8define double @f1(double %a, double %b, i64 %i1, i32 %unext) {9; CHECK-LABEL: f1:10; CHECK: clgfr %r2, %r311; CHECK-NEXT: blr %r1412; CHECK: ldr %f0, %f213; CHECK: br %r1414 %i2 = zext i32 %unext to i6415 %cond = icmp ult i64 %i1, %i216 %res = select i1 %cond, double %a, double %b17 ret double %res18}19 20; ...and again with a different representation.21define double @f2(double %a, double %b, i64 %i1, i64 %unext) {22; CHECK-LABEL: f2:23; CHECK: clgfr %r2, %r324; CHECK-NEXT: blr %r1425; CHECK: ldr %f0, %f226; CHECK: br %r1427 %i2 = and i64 %unext, 429496729528 %cond = icmp ult i64 %i1, %i229 %res = select i1 %cond, double %a, double %b30 ret double %res31}32 33; Check signed register comparison, which can't use CLGFR.34define double @f3(double %a, double %b, i64 %i1, i32 %unext) {35; CHECK-LABEL: f3:36; CHECK-NOT: clgfr37; CHECK: br %r1438 %i2 = zext i32 %unext to i6439 %cond = icmp slt i64 %i1, %i240 %res = select i1 %cond, double %a, double %b41 ret double %res42}43 44; ...and again with a different representation45define double @f4(double %a, double %b, i64 %i1, i64 %unext) {46; CHECK-LABEL: f4:47; CHECK-NOT: clgfr48; CHECK: br %r1449 %i2 = and i64 %unext, 429496729550 %cond = icmp slt i64 %i1, %i251 %res = select i1 %cond, double %a, double %b52 ret double %res53}54 55; Check register equality.56define double @f5(double %a, double %b, i64 %i1, i32 %unext) {57; CHECK-LABEL: f5:58; CHECK: clgfr %r2, %r359; CHECK-NEXT: ber %r1460; CHECK: ldr %f0, %f261; CHECK: br %r1462 %i2 = zext i32 %unext to i6463 %cond = icmp eq i64 %i1, %i264 %res = select i1 %cond, double %a, double %b65 ret double %res66}67 68; ...and again with a different representation69define double @f6(double %a, double %b, i64 %i1, i64 %unext) {70; CHECK-LABEL: f6:71; CHECK: clgfr %r2, %r372; CHECK-NEXT: ber %r1473; CHECK: ldr %f0, %f274; CHECK: br %r1475 %i2 = and i64 %unext, 429496729576 %cond = icmp eq i64 %i1, %i277 %res = select i1 %cond, double %a, double %b78 ret double %res79}80 81; Check register inequality.82define double @f7(double %a, double %b, i64 %i1, i32 %unext) {83; CHECK-LABEL: f7:84; CHECK: clgfr %r2, %r385; CHECK-NEXT: blhr %r1486; CHECK: ldr %f0, %f287; CHECK: br %r1488 %i2 = zext i32 %unext to i6489 %cond = icmp ne i64 %i1, %i290 %res = select i1 %cond, double %a, double %b91 ret double %res92}93 94; ...and again with a different representation95define double @f8(double %a, double %b, i64 %i1, i64 %unext) {96; CHECK-LABEL: f8:97; CHECK: clgfr %r2, %r398; CHECK-NEXT: blhr %r1499; CHECK: ldr %f0, %f2100; CHECK: br %r14101 %i2 = and i64 %unext, 4294967295102 %cond = icmp ne i64 %i1, %i2103 %res = select i1 %cond, double %a, double %b104 ret double %res105}106 107; Check unsigned comparison with memory.108define double @f9(double %a, double %b, i64 %i1, ptr %ptr) {109; CHECK-LABEL: f9:110; CHECK: clgf %r2, 0(%r3)111; CHECK-NEXT: blr %r14112; CHECK: ldr %f0, %f2113; CHECK: br %r14114 %unext = load i32, ptr %ptr115 %i2 = zext i32 %unext to i64116 %cond = icmp ult i64 %i1, %i2117 %res = select i1 %cond, double %a, double %b118 ret double %res119}120 121; Check signed comparison with memory.122define double @f10(double %a, double %b, i64 %i1, ptr %ptr) {123; CHECK-LABEL: f10:124; CHECK-NOT: clgf125; CHECK: br %r14126 %unext = load i32, ptr %ptr127 %i2 = zext i32 %unext to i64128 %cond = icmp slt i64 %i1, %i2129 %res = select i1 %cond, double %a, double %b130 ret double %res131}132 133; Check memory equality.134define double @f11(double %a, double %b, i64 %i1, ptr %ptr) {135; CHECK-LABEL: f11:136; CHECK: clgf %r2, 0(%r3)137; CHECK-NEXT: ber %r14138; CHECK: ldr %f0, %f2139; CHECK: br %r14140 %unext = load i32, ptr %ptr141 %i2 = zext i32 %unext to i64142 %cond = icmp eq i64 %i1, %i2143 %res = select i1 %cond, double %a, double %b144 ret double %res145}146 147; Check memory inequality.148define double @f12(double %a, double %b, i64 %i1, ptr %ptr) {149; CHECK-LABEL: f12:150; CHECK: clgf %r2, 0(%r3)151; CHECK-NEXT: blhr %r14152; CHECK: ldr %f0, %f2153; CHECK: br %r14154 %unext = load i32, ptr %ptr155 %i2 = zext i32 %unext to i64156 %cond = icmp ne i64 %i1, %i2157 %res = select i1 %cond, double %a, double %b158 ret double %res159}160 161; Check the high end of the aligned CLGF range.162define double @f13(double %a, double %b, i64 %i1, ptr %base) {163; CHECK-LABEL: f13:164; CHECK: clgf %r2, 524284(%r3)165; CHECK-NEXT: blr %r14166; CHECK: ldr %f0, %f2167; CHECK: br %r14168 %ptr = getelementptr i32, ptr %base, i64 131071169 %unext = load i32, ptr %ptr170 %i2 = zext i32 %unext to i64171 %cond = icmp ult i64 %i1, %i2172 %res = select i1 %cond, double %a, double %b173 ret double %res174}175 176; Check the next word up, which needs separate address logic.177; Other sequences besides this one would be OK.178define double @f14(double %a, double %b, i64 %i1, ptr %base) {179; CHECK-LABEL: f14:180; CHECK: agfi %r3, 524288181; CHECK: clgf %r2, 0(%r3)182; CHECK-NEXT: blr %r14183; CHECK: ldr %f0, %f2184; CHECK: br %r14185 %ptr = getelementptr i32, ptr %base, i64 131072186 %unext = load i32, ptr %ptr187 %i2 = zext i32 %unext to i64188 %cond = icmp ult i64 %i1, %i2189 %res = select i1 %cond, double %a, double %b190 ret double %res191}192 193; Check the high end of the negative aligned CLGF range.194define double @f15(double %a, double %b, i64 %i1, ptr %base) {195; CHECK-LABEL: f15:196; CHECK: clgf %r2, -4(%r3)197; CHECK-NEXT: blr %r14198; CHECK: ldr %f0, %f2199; CHECK: br %r14200 %ptr = getelementptr i32, ptr %base, i64 -1201 %unext = load i32, ptr %ptr202 %i2 = zext i32 %unext to i64203 %cond = icmp ult i64 %i1, %i2204 %res = select i1 %cond, double %a, double %b205 ret double %res206}207 208; Check the low end of the CLGF range.209define double @f16(double %a, double %b, i64 %i1, ptr %base) {210; CHECK-LABEL: f16:211; CHECK: clgf %r2, -524288(%r3)212; CHECK-NEXT: blr %r14213; CHECK: ldr %f0, %f2214; CHECK: br %r14215 %ptr = getelementptr i32, ptr %base, i64 -131072216 %unext = load i32, ptr %ptr217 %i2 = zext i32 %unext to i64218 %cond = icmp ult i64 %i1, %i2219 %res = select i1 %cond, double %a, double %b220 ret double %res221}222 223; Check the next word down, which needs separate address logic.224; Other sequences besides this one would be OK.225define double @f17(double %a, double %b, i64 %i1, ptr %base) {226; CHECK-LABEL: f17:227; CHECK: agfi %r3, -524292228; CHECK: clgf %r2, 0(%r3)229; CHECK-NEXT: blr %r14230; CHECK: ldr %f0, %f2231; CHECK: br %r14232 %ptr = getelementptr i32, ptr %base, i64 -131073233 %unext = load i32, ptr %ptr234 %i2 = zext i32 %unext to i64235 %cond = icmp ult i64 %i1, %i2236 %res = select i1 %cond, double %a, double %b237 ret double %res238}239 240; Check that CLGF allows an index.241define double @f18(double %a, double %b, i64 %i1, i64 %base, i64 %index) {242; CHECK-LABEL: f18:243; CHECK: clgf %r2, 524284({{%r4,%r3|%r3,%r4}})244; CHECK-NEXT: blr %r14245; CHECK: ldr %f0, %f2246; CHECK: br %r14247 %add1 = add i64 %base, %index248 %add2 = add i64 %add1, 524284249 %ptr = inttoptr i64 %add2 to ptr250 %unext = load i32, ptr %ptr251 %i2 = zext i32 %unext to i64252 %cond = icmp ult i64 %i1, %i2253 %res = select i1 %cond, double %a, double %b254 ret double %res255}256 257; Check that comparisons of spilled values can use CLGF rather than CLGFR.258define i64 @f19(ptr %ptr0) {259; CHECK-LABEL: f19:260; CHECK: brasl %r14, foo@PLT261; CHECK: clgf {{%r[0-9]+}}, 16{{[04]}}(%r15)262; CHECK: br %r14263 %ptr1 = getelementptr i32, ptr %ptr0, i64 2264 %ptr2 = getelementptr i32, ptr %ptr0, i64 4265 %ptr3 = getelementptr i32, ptr %ptr0, i64 6266 %ptr4 = getelementptr i32, ptr %ptr0, i64 8267 %ptr5 = getelementptr i32, ptr %ptr0, i64 10268 %ptr6 = getelementptr i32, ptr %ptr0, i64 12269 %ptr7 = getelementptr i32, ptr %ptr0, i64 14270 %ptr8 = getelementptr i32, ptr %ptr0, i64 16271 %ptr9 = getelementptr i32, ptr %ptr0, i64 18272 273 %val0 = load i32, ptr %ptr0274 %val1 = load i32, ptr %ptr1275 %val2 = load i32, ptr %ptr2276 %val3 = load i32, ptr %ptr3277 %val4 = load i32, ptr %ptr4278 %val5 = load i32, ptr %ptr5279 %val6 = load i32, ptr %ptr6280 %val7 = load i32, ptr %ptr7281 %val8 = load i32, ptr %ptr8282 %val9 = load i32, ptr %ptr9283 284 %frob0 = add i32 %val0, 100285 %frob1 = add i32 %val1, 100286 %frob2 = add i32 %val2, 100287 %frob3 = add i32 %val3, 100288 %frob4 = add i32 %val4, 100289 %frob5 = add i32 %val5, 100290 %frob6 = add i32 %val6, 100291 %frob7 = add i32 %val7, 100292 %frob8 = add i32 %val8, 100293 %frob9 = add i32 %val9, 100294 295 store i32 %frob0, ptr %ptr0296 store i32 %frob1, ptr %ptr1297 store i32 %frob2, ptr %ptr2298 store i32 %frob3, ptr %ptr3299 store i32 %frob4, ptr %ptr4300 store i32 %frob5, ptr %ptr5301 store i32 %frob6, ptr %ptr6302 store i32 %frob7, ptr %ptr7303 store i32 %frob8, ptr %ptr8304 store i32 %frob9, ptr %ptr9305 306 %ret = call i64 @foo()307 308 %ext0 = zext i32 %frob0 to i64309 %ext1 = zext i32 %frob1 to i64310 %ext2 = zext i32 %frob2 to i64311 %ext3 = zext i32 %frob3 to i64312 %ext4 = zext i32 %frob4 to i64313 %ext5 = zext i32 %frob5 to i64314 %ext6 = zext i32 %frob6 to i64315 %ext7 = zext i32 %frob7 to i64316 %ext8 = zext i32 %frob8 to i64317 %ext9 = zext i32 %frob9 to i64318 319 %cmp0 = icmp ult i64 %ret, %ext0320 %cmp1 = icmp ult i64 %ret, %ext1321 %cmp2 = icmp ult i64 %ret, %ext2322 %cmp3 = icmp ult i64 %ret, %ext3323 %cmp4 = icmp ult i64 %ret, %ext4324 %cmp5 = icmp ult i64 %ret, %ext5325 %cmp6 = icmp ult i64 %ret, %ext6326 %cmp7 = icmp ult i64 %ret, %ext7327 %cmp8 = icmp ult i64 %ret, %ext8328 %cmp9 = icmp ult i64 %ret, %ext9329 330 %sel0 = select i1 %cmp0, i64 %ret, i64 0331 %sel1 = select i1 %cmp1, i64 %sel0, i64 1332 %sel2 = select i1 %cmp2, i64 %sel1, i64 2333 %sel3 = select i1 %cmp3, i64 %sel2, i64 3334 %sel4 = select i1 %cmp4, i64 %sel3, i64 4335 %sel5 = select i1 %cmp5, i64 %sel4, i64 5336 %sel6 = select i1 %cmp6, i64 %sel5, i64 6337 %sel7 = select i1 %cmp7, i64 %sel6, i64 7338 %sel8 = select i1 %cmp8, i64 %sel7, i64 8339 %sel9 = select i1 %cmp9, i64 %sel8, i64 9340 341 ret i64 %sel9342}343 344; Check the comparison can be reversed if that allows CLGFR to be used.345define double @f20(double %a, double %b, i64 %i1, i32 %unext) {346; CHECK-LABEL: f20:347; CHECK: clgfr %r2, %r3348; CHECK-NEXT: bhr %r14349; CHECK: ldr %f0, %f2350; CHECK: br %r14351 %i2 = zext i32 %unext to i64352 %cond = icmp ult i64 %i2, %i1353 %res = select i1 %cond, double %a, double %b354 ret double %res355}356 357; ...and again with the AND representation.358define double @f21(double %a, double %b, i64 %i1, i64 %unext) {359; CHECK-LABEL: f21:360; CHECK: clgfr %r2, %r3361; CHECK-NEXT: bhr %r14362; CHECK: ldr %f0, %f2363; CHECK: br %r14364 %i2 = and i64 %unext, 4294967295365 %cond = icmp ult i64 %i2, %i1366 %res = select i1 %cond, double %a, double %b367 ret double %res368}369 370; Check the comparison can be reversed if that allows CLGF to be used.371define double @f22(double %a, double %b, i64 %i2, ptr %ptr) {372; CHECK-LABEL: f22:373; CHECK: clgf %r2, 0(%r3)374; CHECK-NEXT: bhr %r14375; CHECK: ldr %f0, %f2376; CHECK: br %r14377 %unext = load i32, ptr %ptr378 %i1 = zext i32 %unext to i64379 %cond = icmp ult i64 %i1, %i2380 %res = select i1 %cond, double %a, double %b381 ret double %res382}383