330 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; Test 64-bit addition in which the second operand is variable.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s5 6declare i64 @foo()7 8; Check ALGR.9define zeroext i1 @f1(i64 %dummy, i64 %a, i64 %b, ptr %res) {10; CHECK-LABEL: f1:11; CHECK: # %bb.0:12; CHECK-NEXT: algr %r3, %r413; CHECK-NEXT: ipm %r014; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3515; CHECK-NEXT: stg %r3, 0(%r5)16; CHECK-NEXT: br %r1417 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)18 %val = extractvalue {i64, i1} %t, 019 %obit = extractvalue {i64, i1} %t, 120 store i64 %val, ptr %res21 ret i1 %obit22}23 24; Check using the overflow result for a branch.25define void @f2(i64 %dummy, i64 %a, i64 %b, ptr %res) {26; CHECK-LABEL: f2:27; CHECK: # %bb.0:28; CHECK-NEXT: algr %r3, %r429; CHECK-NEXT: stg %r3, 0(%r5)30; CHECK-NEXT: jgnle foo@PLT31; CHECK-NEXT: .LBB1_1: # %exit32; CHECK-NEXT: br %r1433 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)34 %val = extractvalue {i64, i1} %t, 035 %obit = extractvalue {i64, i1} %t, 136 store i64 %val, ptr %res37 br i1 %obit, label %call, label %exit38 39call:40 tail call i64 @foo()41 br label %exit42 43exit:44 ret void45}46 47; ... and the same with the inverted direction.48define void @f3(i64 %dummy, i64 %a, i64 %b, ptr %res) {49; CHECK-LABEL: f3:50; CHECK: # %bb.0:51; CHECK-NEXT: algr %r3, %r452; CHECK-NEXT: stg %r3, 0(%r5)53; CHECK-NEXT: jgle foo@PLT54; CHECK-NEXT: .LBB2_1: # %exit55; CHECK-NEXT: br %r1456 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)57 %val = extractvalue {i64, i1} %t, 058 %obit = extractvalue {i64, i1} %t, 159 store i64 %val, ptr %res60 br i1 %obit, label %exit, label %call61 62call:63 tail call i64 @foo()64 br label %exit65 66exit:67 ret void68}69 70; Check ALG with no displacement.71define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %src, ptr %res) {72; CHECK-LABEL: f4:73; CHECK: # %bb.0:74; CHECK-NEXT: alg %r3, 0(%r4)75; CHECK-NEXT: ipm %r076; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3577; CHECK-NEXT: stg %r3, 0(%r5)78; CHECK-NEXT: br %r1479 %b = load i64, ptr %src80 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)81 %val = extractvalue {i64, i1} %t, 082 %obit = extractvalue {i64, i1} %t, 183 store i64 %val, ptr %res84 ret i1 %obit85}86 87; Check the high end of the aligned ALG range.88define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %src, ptr %res) {89; CHECK-LABEL: f5:90; CHECK: # %bb.0:91; CHECK-NEXT: alg %r3, 524280(%r4)92; CHECK-NEXT: ipm %r093; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3594; CHECK-NEXT: stg %r3, 0(%r5)95; CHECK-NEXT: br %r1496 %ptr = getelementptr i64, ptr %src, i64 6553597 %b = load i64, ptr %ptr98 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)99 %val = extractvalue {i64, i1} %t, 0100 %obit = extractvalue {i64, i1} %t, 1101 store i64 %val, ptr %res102 ret i1 %obit103}104 105; Check the next doubleword up, which needs separate address logic.106; Other sequences besides this one would be OK.107define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %src, ptr %res) {108; CHECK-LABEL: f6:109; CHECK: # %bb.0:110; CHECK-NEXT: agfi %r4, 524288111; CHECK-NEXT: alg %r3, 0(%r4)112; CHECK-NEXT: ipm %r0113; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35114; CHECK-NEXT: stg %r3, 0(%r5)115; CHECK-NEXT: br %r14116 %ptr = getelementptr i64, ptr %src, i64 65536117 %b = load i64, ptr %ptr118 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)119 %val = extractvalue {i64, i1} %t, 0120 %obit = extractvalue {i64, i1} %t, 1121 store i64 %val, ptr %res122 ret i1 %obit123}124 125; Check the high end of the negative aligned ALG range.126define zeroext i1 @f7(i64 %dummy, i64 %a, ptr %src, ptr %res) {127; CHECK-LABEL: f7:128; CHECK: # %bb.0:129; CHECK-NEXT: alg %r3, -8(%r4)130; CHECK-NEXT: ipm %r0131; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35132; CHECK-NEXT: stg %r3, 0(%r5)133; CHECK-NEXT: br %r14134 %ptr = getelementptr i64, ptr %src, i64 -1135 %b = load i64, ptr %ptr136 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)137 %val = extractvalue {i64, i1} %t, 0138 %obit = extractvalue {i64, i1} %t, 1139 store i64 %val, ptr %res140 ret i1 %obit141}142 143; Check the low end of the ALG range.144define zeroext i1 @f8(i64 %dummy, i64 %a, ptr %src, ptr %res) {145; CHECK-LABEL: f8:146; CHECK: # %bb.0:147; CHECK-NEXT: alg %r3, -524288(%r4)148; CHECK-NEXT: ipm %r0149; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35150; CHECK-NEXT: stg %r3, 0(%r5)151; CHECK-NEXT: br %r14152 %ptr = getelementptr i64, ptr %src, i64 -65536153 %b = load i64, ptr %ptr154 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)155 %val = extractvalue {i64, i1} %t, 0156 %obit = extractvalue {i64, i1} %t, 1157 store i64 %val, ptr %res158 ret i1 %obit159}160 161; Check the next doubleword down, which needs separate address logic.162; Other sequences besides this one would be OK.163define zeroext i1 @f9(i64 %dummy, i64 %a, ptr %src, ptr %res) {164; CHECK-LABEL: f9:165; CHECK: # %bb.0:166; CHECK-NEXT: agfi %r4, -524296167; CHECK-NEXT: alg %r3, 0(%r4)168; CHECK-NEXT: ipm %r0169; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35170; CHECK-NEXT: stg %r3, 0(%r5)171; CHECK-NEXT: br %r14172 %ptr = getelementptr i64, ptr %src, i64 -65537173 %b = load i64, ptr %ptr174 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)175 %val = extractvalue {i64, i1} %t, 0176 %obit = extractvalue {i64, i1} %t, 1177 store i64 %val, ptr %res178 ret i1 %obit179}180 181; Check that ALG allows an index.182define zeroext i1 @f10(i64 %src, i64 %index, i64 %a, ptr %res) {183; CHECK-LABEL: f10:184; CHECK: # %bb.0:185; CHECK-NEXT: alg %r4, 524280(%r3,%r2)186; CHECK-NEXT: ipm %r0187; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35188; CHECK-NEXT: stg %r4, 0(%r5)189; CHECK-NEXT: br %r14190 %add1 = add i64 %src, %index191 %add2 = add i64 %add1, 524280192 %ptr = inttoptr i64 %add2 to ptr193 %b = load i64, ptr %ptr194 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)195 %val = extractvalue {i64, i1} %t, 0196 %obit = extractvalue {i64, i1} %t, 1197 store i64 %val, ptr %res198 ret i1 %obit199}200 201; Check that additions of spilled values can use ALG rather than ALGR.202define zeroext i1 @f11(ptr %ptr0) {203; CHECK-LABEL: f11:204; CHECK: # %bb.0:205; CHECK-NEXT: stmg %r6, %r15, 48(%r15)206; CHECK-NEXT: .cfi_offset %r6, -112207; CHECK-NEXT: .cfi_offset %r7, -104208; CHECK-NEXT: .cfi_offset %r8, -96209; CHECK-NEXT: .cfi_offset %r9, -88210; CHECK-NEXT: .cfi_offset %r10, -80211; CHECK-NEXT: .cfi_offset %r11, -72212; CHECK-NEXT: .cfi_offset %r12, -64213; CHECK-NEXT: .cfi_offset %r13, -56214; CHECK-NEXT: .cfi_offset %r14, -48215; CHECK-NEXT: .cfi_offset %r15, -40216; CHECK-NEXT: aghi %r15, -176217; CHECK-NEXT: .cfi_def_cfa_offset 336218; CHECK-NEXT: lg %r7, 0(%r2)219; CHECK-NEXT: lg %r6, 16(%r2)220; CHECK-NEXT: lg %r13, 32(%r2)221; CHECK-NEXT: lg %r12, 48(%r2)222; CHECK-NEXT: lg %r8, 64(%r2)223; CHECK-NEXT: lg %r9, 80(%r2)224; CHECK-NEXT: lg %r10, 96(%r2)225; CHECK-NEXT: lg %r11, 112(%r2)226; CHECK-NEXT: mvc 160(8,%r15), 128(%r2) # 8-byte Folded Spill227; CHECK-NEXT: mvc 168(8,%r15), 144(%r2) # 8-byte Folded Spill228; CHECK-NEXT: brasl %r14, foo@PLT229; CHECK-NEXT: algr %r2, %r7230; CHECK-NEXT: ipm %r0231; CHECK-NEXT: risbg %r0, %r0, 63, 191, 35232; CHECK-NEXT: algr %r2, %r6233; CHECK-NEXT: ipm %r1234; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35235; CHECK-NEXT: algr %r2, %r13236; CHECK-NEXT: ipm %r1237; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35238; CHECK-NEXT: algr %r2, %r12239; CHECK-NEXT: ipm %r1240; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35241; CHECK-NEXT: algr %r2, %r8242; CHECK-NEXT: ipm %r1243; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35244; CHECK-NEXT: algr %r2, %r9245; CHECK-NEXT: ipm %r1246; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35247; CHECK-NEXT: algr %r2, %r10248; CHECK-NEXT: ipm %r1249; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35250; CHECK-NEXT: algr %r2, %r11251; CHECK-NEXT: ipm %r1252; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35253; CHECK-NEXT: alg %r2, 160(%r15) # 8-byte Folded Reload254; CHECK-NEXT: ipm %r1255; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35256; CHECK-NEXT: alg %r2, 168(%r15) # 8-byte Folded Reload257; CHECK-NEXT: ipm %r1258; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35259; CHECK-NEXT: risbg %r2, %r0, 63, 191, 0260; CHECK-NEXT: lmg %r6, %r15, 224(%r15)261; CHECK-NEXT: br %r14262 %ptr1 = getelementptr i64, ptr %ptr0, i64 2263 %ptr2 = getelementptr i64, ptr %ptr0, i64 4264 %ptr3 = getelementptr i64, ptr %ptr0, i64 6265 %ptr4 = getelementptr i64, ptr %ptr0, i64 8266 %ptr5 = getelementptr i64, ptr %ptr0, i64 10267 %ptr6 = getelementptr i64, ptr %ptr0, i64 12268 %ptr7 = getelementptr i64, ptr %ptr0, i64 14269 %ptr8 = getelementptr i64, ptr %ptr0, i64 16270 %ptr9 = getelementptr i64, ptr %ptr0, i64 18271 272 %val0 = load i64, ptr %ptr0273 %val1 = load i64, ptr %ptr1274 %val2 = load i64, ptr %ptr2275 %val3 = load i64, ptr %ptr3276 %val4 = load i64, ptr %ptr4277 %val5 = load i64, ptr %ptr5278 %val6 = load i64, ptr %ptr6279 %val7 = load i64, ptr %ptr7280 %val8 = load i64, ptr %ptr8281 %val9 = load i64, ptr %ptr9282 283 %ret = call i64 @foo()284 285 %t0 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %ret, i64 %val0)286 %add0 = extractvalue {i64, i1} %t0, 0287 %obit0 = extractvalue {i64, i1} %t0, 1288 %t1 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add0, i64 %val1)289 %add1 = extractvalue {i64, i1} %t1, 0290 %obit1 = extractvalue {i64, i1} %t1, 1291 %res1 = or i1 %obit0, %obit1292 %t2 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add1, i64 %val2)293 %add2 = extractvalue {i64, i1} %t2, 0294 %obit2 = extractvalue {i64, i1} %t2, 1295 %res2 = or i1 %res1, %obit2296 %t3 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add2, i64 %val3)297 %add3 = extractvalue {i64, i1} %t3, 0298 %obit3 = extractvalue {i64, i1} %t3, 1299 %res3 = or i1 %res2, %obit3300 %t4 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add3, i64 %val4)301 %add4 = extractvalue {i64, i1} %t4, 0302 %obit4 = extractvalue {i64, i1} %t4, 1303 %res4 = or i1 %res3, %obit4304 %t5 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add4, i64 %val5)305 %add5 = extractvalue {i64, i1} %t5, 0306 %obit5 = extractvalue {i64, i1} %t5, 1307 %res5 = or i1 %res4, %obit5308 %t6 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add5, i64 %val6)309 %add6 = extractvalue {i64, i1} %t6, 0310 %obit6 = extractvalue {i64, i1} %t6, 1311 %res6 = or i1 %res5, %obit6312 %t7 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add6, i64 %val7)313 %add7 = extractvalue {i64, i1} %t7, 0314 %obit7 = extractvalue {i64, i1} %t7, 1315 %res7 = or i1 %res6, %obit7316 %t8 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add7, i64 %val8)317 %add8 = extractvalue {i64, i1} %t8, 0318 %obit8 = extractvalue {i64, i1} %t8, 1319 %res8 = or i1 %res7, %obit8320 %t9 = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %add8, i64 %val9)321 %add9 = extractvalue {i64, i1} %t9, 0322 %obit9 = extractvalue {i64, i1} %t9, 1323 %res9 = or i1 %res8, %obit9324 325 ret i1 %res9326}327 328declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone329 330