320 lines · plain
1; Test 64-bit comparison in which the second operand is a sign-extended i32.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare i64 @foo()6 7; Check signed register comparison.8define double @f1(double %a, double %b, i64 %i1, i32 %unext) {9; CHECK-LABEL: f1:10; CHECK: cgfr %r2, %r311; CHECK-NEXT: blr %r1412; CHECK: ldr %f0, %f213; CHECK: br %r1414 %i2 = sext i32 %unext to i6415 %cond = icmp slt i64 %i1, %i216 %res = select i1 %cond, double %a, double %b17 ret double %res18}19 20; Check unsigned register comparison, which can't use CGFR.21define double @f2(double %a, double %b, i64 %i1, i32 %unext) {22; CHECK-LABEL: f2:23; CHECK-NOT: cgfr24; CHECK: br %r1425 %i2 = sext i32 %unext to i6426 %cond = icmp ult i64 %i1, %i227 %res = select i1 %cond, double %a, double %b28 ret double %res29}30 31; Check register equality.32define double @f3(double %a, double %b, i64 %i1, i32 %unext) {33; CHECK-LABEL: f3:34; CHECK: cgfr %r2, %r335; CHECK-NEXT: ber %r1436; CHECK: ldr %f0, %f237; CHECK: br %r1438 %i2 = sext i32 %unext to i6439 %cond = icmp eq i64 %i1, %i240 %res = select i1 %cond, double %a, double %b41 ret double %res42}43 44; Check register inequality.45define double @f4(double %a, double %b, i64 %i1, i32 %unext) {46; CHECK-LABEL: f4:47; CHECK: cgfr %r2, %r348; CHECK-NEXT: blhr %r1449; CHECK: ldr %f0, %f250; CHECK: br %r1451 %i2 = sext i32 %unext to i6452 %cond = icmp ne i64 %i1, %i253 %res = select i1 %cond, double %a, double %b54 ret double %res55}56 57; Check signed comparison with memory.58define double @f5(double %a, double %b, i64 %i1, ptr %ptr) {59; CHECK-LABEL: f5:60; CHECK: cgf %r2, 0(%r3)61; CHECK-NEXT: blr %r1462; CHECK: ldr %f0, %f263; CHECK: br %r1464 %unext = load i32, ptr %ptr65 %i2 = sext i32 %unext to i6466 %cond = icmp slt i64 %i1, %i267 %res = select i1 %cond, double %a, double %b68 ret double %res69}70 71; Check unsigned comparison with memory.72define double @f6(double %a, double %b, i64 %i1, ptr %ptr) {73; CHECK-LABEL: f6:74; CHECK-NOT: cgf75; CHECK: br %r1476 %unext = load i32, ptr %ptr77 %i2 = sext i32 %unext to i6478 %cond = icmp ult i64 %i1, %i279 %res = select i1 %cond, double %a, double %b80 ret double %res81}82 83; Check memory equality.84define double @f7(double %a, double %b, i64 %i1, ptr %ptr) {85; CHECK-LABEL: f7:86; CHECK: cgf %r2, 0(%r3)87; CHECK-NEXT: ber %r1488; CHECK: ldr %f0, %f289; CHECK: br %r1490 %unext = load i32, ptr %ptr91 %i2 = sext i32 %unext to i6492 %cond = icmp eq i64 %i1, %i293 %res = select i1 %cond, double %a, double %b94 ret double %res95}96 97; Check memory inequality.98define double @f8(double %a, double %b, i64 %i1, ptr %ptr) {99; CHECK-LABEL: f8:100; CHECK: cgf %r2, 0(%r3)101; CHECK-NEXT: blhr %r14102; CHECK: ldr %f0, %f2103; CHECK: br %r14104 %unext = load i32, ptr %ptr105 %i2 = sext i32 %unext to i64106 %cond = icmp ne i64 %i1, %i2107 %res = select i1 %cond, double %a, double %b108 ret double %res109}110 111; Check the high end of the aligned CGF range.112define double @f9(double %a, double %b, i64 %i1, ptr %base) {113; CHECK-LABEL: f9:114; CHECK: cgf %r2, 524284(%r3)115; CHECK-NEXT: blr %r14116; CHECK: ldr %f0, %f2117; CHECK: br %r14118 %ptr = getelementptr i32, ptr %base, i64 131071119 %unext = load i32, ptr %ptr120 %i2 = sext i32 %unext to i64121 %cond = icmp slt i64 %i1, %i2122 %res = select i1 %cond, double %a, double %b123 ret double %res124}125 126; Check the next word up, which needs separate address logic.127; Other sequences besides this one would be OK.128define double @f10(double %a, double %b, i64 %i1, ptr %base) {129; CHECK-LABEL: f10:130; CHECK: agfi %r3, 524288131; CHECK: cgf %r2, 0(%r3)132; CHECK-NEXT: blr %r14133; CHECK: ldr %f0, %f2134; CHECK: br %r14135 %ptr = getelementptr i32, ptr %base, i64 131072136 %unext = load i32, ptr %ptr137 %i2 = sext i32 %unext to i64138 %cond = icmp slt i64 %i1, %i2139 %res = select i1 %cond, double %a, double %b140 ret double %res141}142 143; Check the high end of the negative aligned CGF range.144define double @f11(double %a, double %b, i64 %i1, ptr %base) {145; CHECK-LABEL: f11:146; CHECK: cgf %r2, -4(%r3)147; CHECK-NEXT: blr %r14148; CHECK: ldr %f0, %f2149; CHECK: br %r14150 %ptr = getelementptr i32, ptr %base, i64 -1151 %unext = load i32, ptr %ptr152 %i2 = sext i32 %unext to i64153 %cond = icmp slt i64 %i1, %i2154 %res = select i1 %cond, double %a, double %b155 ret double %res156}157 158; Check the low end of the CGF range.159define double @f12(double %a, double %b, i64 %i1, ptr %base) {160; CHECK-LABEL: f12:161; CHECK: cgf %r2, -524288(%r3)162; CHECK-NEXT: blr %r14163; CHECK: ldr %f0, %f2164; CHECK: br %r14165 %ptr = getelementptr i32, ptr %base, i64 -131072166 %unext = load i32, ptr %ptr167 %i2 = sext i32 %unext to i64168 %cond = icmp slt i64 %i1, %i2169 %res = select i1 %cond, double %a, double %b170 ret double %res171}172 173; Check the next word down, which needs separate address logic.174; Other sequences besides this one would be OK.175define double @f13(double %a, double %b, i64 %i1, ptr %base) {176; CHECK-LABEL: f13:177; CHECK: agfi %r3, -524292178; CHECK: cgf %r2, 0(%r3)179; CHECK-NEXT: blr %r14180; CHECK: ldr %f0, %f2181; CHECK: br %r14182 %ptr = getelementptr i32, ptr %base, i64 -131073183 %unext = load i32, ptr %ptr184 %i2 = sext i32 %unext to i64185 %cond = icmp slt i64 %i1, %i2186 %res = select i1 %cond, double %a, double %b187 ret double %res188}189 190; Check that CGF allows an index.191define double @f14(double %a, double %b, i64 %i1, i64 %base, i64 %index) {192; CHECK-LABEL: f14:193; CHECK: cgf %r2, 524284({{%r4,%r3|%r3,%r4}})194; CHECK-NEXT: blr %r14195; CHECK: ldr %f0, %f2196; CHECK: br %r14197 %add1 = add i64 %base, %index198 %add2 = add i64 %add1, 524284199 %ptr = inttoptr i64 %add2 to ptr200 %unext = load i32, ptr %ptr201 %i2 = sext i32 %unext to i64202 %cond = icmp slt i64 %i1, %i2203 %res = select i1 %cond, double %a, double %b204 ret double %res205}206 207; Check that comparisons of spilled values can use CGF rather than CGFR.208define i64 @f15(ptr %ptr0) {209; CHECK-LABEL: f15:210; CHECK: brasl %r14, foo@PLT211; CHECK: cgf {{%r[0-9]+}}, 16{{[04]}}(%r15)212; CHECK: br %r14213 %ptr1 = getelementptr i32, ptr %ptr0, i64 2214 %ptr2 = getelementptr i32, ptr %ptr0, i64 4215 %ptr3 = getelementptr i32, ptr %ptr0, i64 6216 %ptr4 = getelementptr i32, ptr %ptr0, i64 8217 %ptr5 = getelementptr i32, ptr %ptr0, i64 10218 %ptr6 = getelementptr i32, ptr %ptr0, i64 12219 %ptr7 = getelementptr i32, ptr %ptr0, i64 14220 %ptr8 = getelementptr i32, ptr %ptr0, i64 16221 %ptr9 = getelementptr i32, ptr %ptr0, i64 18222 223 %val0 = load i32, ptr %ptr0224 %val1 = load i32, ptr %ptr1225 %val2 = load i32, ptr %ptr2226 %val3 = load i32, ptr %ptr3227 %val4 = load i32, ptr %ptr4228 %val5 = load i32, ptr %ptr5229 %val6 = load i32, ptr %ptr6230 %val7 = load i32, ptr %ptr7231 %val8 = load i32, ptr %ptr8232 %val9 = load i32, ptr %ptr9233 234 %frob0 = add i32 %val0, 100235 %frob1 = add i32 %val1, 100236 %frob2 = add i32 %val2, 100237 %frob3 = add i32 %val3, 100238 %frob4 = add i32 %val4, 100239 %frob5 = add i32 %val5, 100240 %frob6 = add i32 %val6, 100241 %frob7 = add i32 %val7, 100242 %frob8 = add i32 %val8, 100243 %frob9 = add i32 %val9, 100244 245 store i32 %frob0, ptr %ptr0246 store i32 %frob1, ptr %ptr1247 store i32 %frob2, ptr %ptr2248 store i32 %frob3, ptr %ptr3249 store i32 %frob4, ptr %ptr4250 store i32 %frob5, ptr %ptr5251 store i32 %frob6, ptr %ptr6252 store i32 %frob7, ptr %ptr7253 store i32 %frob8, ptr %ptr8254 store i32 %frob9, ptr %ptr9255 256 %ret = call i64 @foo()257 258 %ext0 = sext i32 %frob0 to i64259 %ext1 = sext i32 %frob1 to i64260 %ext2 = sext i32 %frob2 to i64261 %ext3 = sext i32 %frob3 to i64262 %ext4 = sext i32 %frob4 to i64263 %ext5 = sext i32 %frob5 to i64264 %ext6 = sext i32 %frob6 to i64265 %ext7 = sext i32 %frob7 to i64266 %ext8 = sext i32 %frob8 to i64267 %ext9 = sext i32 %frob9 to i64268 269 %cmp0 = icmp slt i64 %ret, %ext0270 %cmp1 = icmp slt i64 %ret, %ext1271 %cmp2 = icmp slt i64 %ret, %ext2272 %cmp3 = icmp slt i64 %ret, %ext3273 %cmp4 = icmp slt i64 %ret, %ext4274 %cmp5 = icmp slt i64 %ret, %ext5275 %cmp6 = icmp slt i64 %ret, %ext6276 %cmp7 = icmp slt i64 %ret, %ext7277 %cmp8 = icmp slt i64 %ret, %ext8278 %cmp9 = icmp slt i64 %ret, %ext9279 280 %sel0 = select i1 %cmp0, i64 %ret, i64 0281 %sel1 = select i1 %cmp1, i64 %sel0, i64 1282 %sel2 = select i1 %cmp2, i64 %sel1, i64 2283 %sel3 = select i1 %cmp3, i64 %sel2, i64 3284 %sel4 = select i1 %cmp4, i64 %sel3, i64 4285 %sel5 = select i1 %cmp5, i64 %sel4, i64 5286 %sel6 = select i1 %cmp6, i64 %sel5, i64 6287 %sel7 = select i1 %cmp7, i64 %sel6, i64 7288 %sel8 = select i1 %cmp8, i64 %sel7, i64 8289 %sel9 = select i1 %cmp9, i64 %sel8, i64 9290 291 ret i64 %sel9292}293 294; Check the comparison can be reversed if that allows CGFR to be used.295define double @f16(double %a, double %b, i64 %i1, i32 %unext) {296; CHECK-LABEL: f16:297; CHECK: cgfr %r2, %r3298; CHECK-NEXT: bhr %r14299; CHECK: ldr %f0, %f2300; CHECK: br %r14301 %i2 = sext i32 %unext to i64302 %cond = icmp slt i64 %i2, %i1303 %res = select i1 %cond, double %a, double %b304 ret double %res305}306 307; Likewise CGF.308define double @f17(double %a, double %b, i64 %i2, ptr %ptr) {309; CHECK-LABEL: f17:310; CHECK: cgf %r2, 0(%r3)311; CHECK-NEXT: bhr %r14312; CHECK: ldr %f0, %f2313; CHECK: br %r14314 %unext = load i32, ptr %ptr315 %i1 = sext i32 %unext to i64316 %cond = icmp slt i64 %i1, %i2317 %res = select i1 %cond, double %a, double %b318 ret double %res319}320