348 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; Test 64-bit subtraction in which the second operand is variable.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s5 6declare i64 @foo()7 8; Check SLGR.9define zeroext i1 @f1(i64 %dummy, i64 %a, i64 %b, ptr %res) {10; CHECK-LABEL: f1:11; CHECK: # %bb.0:12; CHECK-NEXT: slgr %r3, %r413; CHECK-NEXT: ipm %r014; CHECK-NEXT: afi %r0, -53687091215; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3316; CHECK-NEXT: stg %r3, 0(%r5)17; CHECK-NEXT: br %r1418 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)19 %val = extractvalue {i64, i1} %t, 020 %obit = extractvalue {i64, i1} %t, 121 store i64 %val, ptr %res22 ret i1 %obit23}24 25; Check using the overflow result for a branch.26define void @f2(i64 %dummy, i64 %a, i64 %b, ptr %res) {27; CHECK-LABEL: f2:28; CHECK: # %bb.0:29; CHECK-NEXT: slgr %r3, %r430; CHECK-NEXT: stg %r3, 0(%r5)31; CHECK-NEXT: jgle foo@PLT32; CHECK-NEXT: .LBB1_1: # %exit33; CHECK-NEXT: br %r1434 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)35 %val = extractvalue {i64, i1} %t, 036 %obit = extractvalue {i64, i1} %t, 137 store i64 %val, ptr %res38 br i1 %obit, label %call, label %exit39 40call:41 tail call i64 @foo()42 br label %exit43 44exit:45 ret void46}47 48; ... and the same with the inverted direction.49define void @f3(i64 %dummy, i64 %a, i64 %b, ptr %res) {50; CHECK-LABEL: f3:51; CHECK: # %bb.0:52; CHECK-NEXT: slgr %r3, %r453; CHECK-NEXT: stg %r3, 0(%r5)54; CHECK-NEXT: jgnle foo@PLT55; CHECK-NEXT: .LBB2_1: # %exit56; CHECK-NEXT: br %r1457 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)58 %val = extractvalue {i64, i1} %t, 059 %obit = extractvalue {i64, i1} %t, 160 store i64 %val, ptr %res61 br i1 %obit, label %exit, label %call62 63call:64 tail call i64 @foo()65 br label %exit66 67exit:68 ret void69}70 71; Check SLG with no displacement.72define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %src, ptr %res) {73; CHECK-LABEL: f4:74; CHECK: # %bb.0:75; CHECK-NEXT: slg %r3, 0(%r4)76; CHECK-NEXT: ipm %r077; CHECK-NEXT: afi %r0, -53687091278; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3379; CHECK-NEXT: stg %r3, 0(%r5)80; CHECK-NEXT: br %r1481 %b = load i64, ptr %src82 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)83 %val = extractvalue {i64, i1} %t, 084 %obit = extractvalue {i64, i1} %t, 185 store i64 %val, ptr %res86 ret i1 %obit87}88 89; Check the high end of the aligned SLG range.90define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %src, ptr %res) {91; CHECK-LABEL: f5:92; CHECK: # %bb.0:93; CHECK-NEXT: slg %r3, 524280(%r4)94; CHECK-NEXT: ipm %r095; CHECK-NEXT: afi %r0, -53687091296; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3397; CHECK-NEXT: stg %r3, 0(%r5)98; CHECK-NEXT: br %r1499 %ptr = getelementptr i64, ptr %src, i64 65535100 %b = load i64, ptr %ptr101 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)102 %val = extractvalue {i64, i1} %t, 0103 %obit = extractvalue {i64, i1} %t, 1104 store i64 %val, ptr %res105 ret i1 %obit106}107 108; Check the next doubleword up, which needs separate address logic.109; Other sequences besides this one would be OK.110define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %src, ptr %res) {111; CHECK-LABEL: f6:112; CHECK: # %bb.0:113; CHECK-NEXT: agfi %r4, 524288114; CHECK-NEXT: slg %r3, 0(%r4)115; CHECK-NEXT: ipm %r0116; CHECK-NEXT: afi %r0, -536870912117; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33118; CHECK-NEXT: stg %r3, 0(%r5)119; CHECK-NEXT: br %r14120 %ptr = getelementptr i64, ptr %src, i64 65536121 %b = load i64, ptr %ptr122 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)123 %val = extractvalue {i64, i1} %t, 0124 %obit = extractvalue {i64, i1} %t, 1125 store i64 %val, ptr %res126 ret i1 %obit127}128 129; Check the high end of the negative aligned SLG range.130define zeroext i1 @f7(i64 %dummy, i64 %a, ptr %src, ptr %res) {131; CHECK-LABEL: f7:132; CHECK: # %bb.0:133; CHECK-NEXT: slg %r3, -8(%r4)134; CHECK-NEXT: ipm %r0135; CHECK-NEXT: afi %r0, -536870912136; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33137; CHECK-NEXT: stg %r3, 0(%r5)138; CHECK-NEXT: br %r14139 %ptr = getelementptr i64, ptr %src, i64 -1140 %b = load i64, ptr %ptr141 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)142 %val = extractvalue {i64, i1} %t, 0143 %obit = extractvalue {i64, i1} %t, 1144 store i64 %val, ptr %res145 ret i1 %obit146}147 148; Check the low end of the SLG range.149define zeroext i1 @f8(i64 %dummy, i64 %a, ptr %src, ptr %res) {150; CHECK-LABEL: f8:151; CHECK: # %bb.0:152; CHECK-NEXT: slg %r3, -524288(%r4)153; CHECK-NEXT: ipm %r0154; CHECK-NEXT: afi %r0, -536870912155; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33156; CHECK-NEXT: stg %r3, 0(%r5)157; CHECK-NEXT: br %r14158 %ptr = getelementptr i64, ptr %src, i64 -65536159 %b = load i64, ptr %ptr160 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)161 %val = extractvalue {i64, i1} %t, 0162 %obit = extractvalue {i64, i1} %t, 1163 store i64 %val, ptr %res164 ret i1 %obit165}166 167; Check the next doubleword down, which needs separate address logic.168; Other sequences besides this one would be OK.169define zeroext i1 @f9(i64 %dummy, i64 %a, ptr %src, ptr %res) {170; CHECK-LABEL: f9:171; CHECK: # %bb.0:172; CHECK-NEXT: agfi %r4, -524296173; CHECK-NEXT: slg %r3, 0(%r4)174; CHECK-NEXT: ipm %r0175; CHECK-NEXT: afi %r0, -536870912176; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33177; CHECK-NEXT: stg %r3, 0(%r5)178; CHECK-NEXT: br %r14179 %ptr = getelementptr i64, ptr %src, i64 -65537180 %b = load i64, ptr %ptr181 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)182 %val = extractvalue {i64, i1} %t, 0183 %obit = extractvalue {i64, i1} %t, 1184 store i64 %val, ptr %res185 ret i1 %obit186}187 188; Check that SLG allows an index.189define zeroext i1 @f10(i64 %src, i64 %index, i64 %a, ptr %res) {190; CHECK-LABEL: f10:191; CHECK: # %bb.0:192; CHECK-NEXT: slg %r4, 524280(%r3,%r2)193; CHECK-NEXT: ipm %r0194; CHECK-NEXT: afi %r0, -536870912195; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33196; CHECK-NEXT: stg %r4, 0(%r5)197; CHECK-NEXT: br %r14198 %add1 = add i64 %src, %index199 %add2 = add i64 %add1, 524280200 %ptr = inttoptr i64 %add2 to ptr201 %b = load i64, ptr %ptr202 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b)203 %val = extractvalue {i64, i1} %t, 0204 %obit = extractvalue {i64, i1} %t, 1205 store i64 %val, ptr %res206 ret i1 %obit207}208 209; Check that subtractions of spilled values can use SLG rather than SLGR.210define zeroext i1 @f11(ptr %ptr0) {211; CHECK-LABEL: f11:212; CHECK: # %bb.0:213; CHECK-NEXT: stmg %r6, %r15, 48(%r15)214; CHECK-NEXT: .cfi_offset %r6, -112215; CHECK-NEXT: .cfi_offset %r7, -104216; CHECK-NEXT: .cfi_offset %r8, -96217; CHECK-NEXT: .cfi_offset %r9, -88218; CHECK-NEXT: .cfi_offset %r10, -80219; CHECK-NEXT: .cfi_offset %r11, -72220; CHECK-NEXT: .cfi_offset %r12, -64221; CHECK-NEXT: .cfi_offset %r13, -56222; CHECK-NEXT: .cfi_offset %r14, -48223; CHECK-NEXT: .cfi_offset %r15, -40224; CHECK-NEXT: aghi %r15, -176225; CHECK-NEXT: .cfi_def_cfa_offset 336226; CHECK-NEXT: lg %r6, 0(%r2)227; CHECK-NEXT: lg %r13, 16(%r2)228; CHECK-NEXT: lg %r12, 32(%r2)229; CHECK-NEXT: lg %r7, 48(%r2)230; CHECK-NEXT: lg %r8, 64(%r2)231; CHECK-NEXT: lg %r9, 80(%r2)232; CHECK-NEXT: lg %r10, 96(%r2)233; CHECK-NEXT: lg %r11, 112(%r2)234; CHECK-NEXT: mvc 160(8,%r15), 128(%r2) # 8-byte Folded Spill235; CHECK-NEXT: mvc 168(8,%r15), 144(%r2) # 8-byte Folded Spill236; CHECK-NEXT: brasl %r14, foo@PLT237; CHECK-NEXT: slgr %r2, %r6238; CHECK-NEXT: ipm %r0239; CHECK-NEXT: afi %r0, -536870912240; CHECK-NEXT: srl %r0, 31241; CHECK-NEXT: slgr %r2, %r13242; CHECK-NEXT: ipm %r1243; CHECK-NEXT: afi %r1, -536870912244; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33245; CHECK-NEXT: slgr %r2, %r12246; CHECK-NEXT: ipm %r1247; CHECK-NEXT: afi %r1, -536870912248; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33249; CHECK-NEXT: slgr %r2, %r7250; CHECK-NEXT: ipm %r1251; CHECK-NEXT: afi %r1, -536870912252; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33253; CHECK-NEXT: slgr %r2, %r8254; CHECK-NEXT: ipm %r1255; CHECK-NEXT: afi %r1, -536870912256; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33257; CHECK-NEXT: slgr %r2, %r9258; CHECK-NEXT: ipm %r1259; CHECK-NEXT: afi %r1, -536870912260; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33261; CHECK-NEXT: slgr %r2, %r10262; CHECK-NEXT: ipm %r1263; CHECK-NEXT: afi %r1, -536870912264; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33265; CHECK-NEXT: slgr %r2, %r11266; CHECK-NEXT: ipm %r1267; CHECK-NEXT: afi %r1, -536870912268; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33269; CHECK-NEXT: slg %r2, 160(%r15) # 8-byte Folded Reload270; CHECK-NEXT: ipm %r1271; CHECK-NEXT: afi %r1, -536870912272; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33273; CHECK-NEXT: slg %r2, 168(%r15) # 8-byte Folded Reload274; CHECK-NEXT: ipm %r1275; CHECK-NEXT: afi %r1, -536870912276; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33277; CHECK-NEXT: risbg %r2, %r0, 63, 191, 0278; CHECK-NEXT: lmg %r6, %r15, 224(%r15)279; CHECK-NEXT: br %r14280 %ptr1 = getelementptr i64, ptr %ptr0, i64 2281 %ptr2 = getelementptr i64, ptr %ptr0, i64 4282 %ptr3 = getelementptr i64, ptr %ptr0, i64 6283 %ptr4 = getelementptr i64, ptr %ptr0, i64 8284 %ptr5 = getelementptr i64, ptr %ptr0, i64 10285 %ptr6 = getelementptr i64, ptr %ptr0, i64 12286 %ptr7 = getelementptr i64, ptr %ptr0, i64 14287 %ptr8 = getelementptr i64, ptr %ptr0, i64 16288 %ptr9 = getelementptr i64, ptr %ptr0, i64 18289 290 %val0 = load i64, ptr %ptr0291 %val1 = load i64, ptr %ptr1292 %val2 = load i64, ptr %ptr2293 %val3 = load i64, ptr %ptr3294 %val4 = load i64, ptr %ptr4295 %val5 = load i64, ptr %ptr5296 %val6 = load i64, ptr %ptr6297 %val7 = load i64, ptr %ptr7298 %val8 = load i64, ptr %ptr8299 %val9 = load i64, ptr %ptr9300 301 %ret = call i64 @foo()302 303 %t0 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %ret, i64 %val0)304 %add0 = extractvalue {i64, i1} %t0, 0305 %obit0 = extractvalue {i64, i1} %t0, 1306 %t1 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add0, i64 %val1)307 %add1 = extractvalue {i64, i1} %t1, 0308 %obit1 = extractvalue {i64, i1} %t1, 1309 %res1 = or i1 %obit0, %obit1310 %t2 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add1, i64 %val2)311 %add2 = extractvalue {i64, i1} %t2, 0312 %obit2 = extractvalue {i64, i1} %t2, 1313 %res2 = or i1 %res1, %obit2314 %t3 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add2, i64 %val3)315 %add3 = extractvalue {i64, i1} %t3, 0316 %obit3 = extractvalue {i64, i1} %t3, 1317 %res3 = or i1 %res2, %obit3318 %t4 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add3, i64 %val4)319 %add4 = extractvalue {i64, i1} %t4, 0320 %obit4 = extractvalue {i64, i1} %t4, 1321 %res4 = or i1 %res3, %obit4322 %t5 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add4, i64 %val5)323 %add5 = extractvalue {i64, i1} %t5, 0324 %obit5 = extractvalue {i64, i1} %t5, 1325 %res5 = or i1 %res4, %obit5326 %t6 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add5, i64 %val6)327 %add6 = extractvalue {i64, i1} %t6, 0328 %obit6 = extractvalue {i64, i1} %t6, 1329 %res6 = or i1 %res5, %obit6330 %t7 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add6, i64 %val7)331 %add7 = extractvalue {i64, i1} %t7, 0332 %obit7 = extractvalue {i64, i1} %t7, 1333 %res7 = or i1 %res6, %obit7334 %t8 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add7, i64 %val8)335 %add8 = extractvalue {i64, i1} %t8, 0336 %obit8 = extractvalue {i64, i1} %t8, 1337 %res8 = or i1 %res7, %obit8338 %t9 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %add8, i64 %val9)339 %add9 = extractvalue {i64, i1} %t9, 0340 %obit9 = extractvalue {i64, i1} %t9, 1341 %res9 = or i1 %res8, %obit9342 343 ret i1 %res9344}345 346declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone347 348