386 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; Test 32-bit addition in which the second operand is variable.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s5 6declare i32 @foo()7 8; Check ALR.9define zeroext i1 @f1(i32 %dummy, i32 %a, i32 %b, ptr %res) {10; CHECK-LABEL: f1:11; CHECK: # %bb.0:12; CHECK-NEXT: alr %r3, %r413; CHECK-NEXT: ipm %r014; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3515; CHECK-NEXT: st %r3, 0(%r5)16; CHECK-NEXT: br %r1417 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)18 %val = extractvalue {i32, i1} %t, 019 %obit = extractvalue {i32, i1} %t, 120 store i32 %val, ptr %res21 ret i1 %obit22}23 24; Check using the overflow result for a branch.25define void @f2(i32 %dummy, i32 %a, i32 %b, ptr %res) {26; CHECK-LABEL: f2:27; CHECK: # %bb.0:28; CHECK-NEXT: alr %r3, %r429; CHECK-NEXT: st %r3, 0(%r5)30; CHECK-NEXT: jgnle foo@PLT31; CHECK-NEXT: .LBB1_1: # %exit32; CHECK-NEXT: br %r1433 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)34 %val = extractvalue {i32, i1} %t, 035 %obit = extractvalue {i32, i1} %t, 136 store i32 %val, ptr %res37 br i1 %obit, label %call, label %exit38 39call:40 tail call i32 @foo()41 br label %exit42 43exit:44 ret void45}46 47; ... and the same with the inverted direction.48define void @f3(i32 %dummy, i32 %a, i32 %b, ptr %res) {49; CHECK-LABEL: f3:50; CHECK: # %bb.0:51; CHECK-NEXT: alr %r3, %r452; CHECK-NEXT: st %r3, 0(%r5)53; CHECK-NEXT: jgle foo@PLT54; CHECK-NEXT: .LBB2_1: # %exit55; CHECK-NEXT: br %r1456 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)57 %val = extractvalue {i32, i1} %t, 058 %obit = extractvalue {i32, i1} %t, 159 store i32 %val, ptr %res60 br i1 %obit, label %exit, label %call61 62call:63 tail call i32 @foo()64 br label %exit65 66exit:67 ret void68}69 70; Check the low end of the AL range.71define zeroext i1 @f4(i32 %dummy, i32 %a, ptr %src, ptr %res) {72; CHECK-LABEL: f4:73; CHECK: # %bb.0:74; CHECK-NEXT: al %r3, 0(%r4)75; CHECK-NEXT: ipm %r076; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3577; CHECK-NEXT: st %r3, 0(%r5)78; CHECK-NEXT: br %r1479 %b = load i32, ptr %src80 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)81 %val = extractvalue {i32, i1} %t, 082 %obit = extractvalue {i32, i1} %t, 183 store i32 %val, ptr %res84 ret i1 %obit85}86 87; Check the high end of the aligned AL range.88define zeroext i1 @f5(i32 %dummy, i32 %a, ptr %src, ptr %res) {89; CHECK-LABEL: f5:90; CHECK: # %bb.0:91; CHECK-NEXT: al %r3, 4092(%r4)92; CHECK-NEXT: ipm %r093; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3594; CHECK-NEXT: st %r3, 0(%r5)95; CHECK-NEXT: br %r1496 %ptr = getelementptr i32, ptr %src, i64 102397 %b = load i32, ptr %ptr98 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)99 %val = extractvalue {i32, i1} %t, 0100 %obit = extractvalue {i32, i1} %t, 1101 store i32 %val, ptr %res102 ret i1 %obit103}104 105; Check the next word up, which should use ALY instead of AL.106define zeroext i1 @f6(i32 %dummy, i32 %a, ptr %src, ptr %res) {107; CHECK-LABEL: f6:108; CHECK: # %bb.0:109; CHECK-NEXT: aly %r3, 4096(%r4)110; CHECK-NEXT: ipm %r0111; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35112; CHECK-NEXT: st %r3, 0(%r5)113; CHECK-NEXT: br %r14114 %ptr = getelementptr i32, ptr %src, i64 1024115 %b = load i32, ptr %ptr116 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)117 %val = extractvalue {i32, i1} %t, 0118 %obit = extractvalue {i32, i1} %t, 1119 store i32 %val, ptr %res120 ret i1 %obit121}122 123; Check the high end of the aligned ALY range.124define zeroext i1 @f7(i32 %dummy, i32 %a, ptr %src, ptr %res) {125; CHECK-LABEL: f7:126; CHECK: # %bb.0:127; CHECK-NEXT: aly %r3, 524284(%r4)128; CHECK-NEXT: ipm %r0129; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35130; CHECK-NEXT: st %r3, 0(%r5)131; CHECK-NEXT: br %r14132 %ptr = getelementptr i32, ptr %src, i64 131071133 %b = load i32, ptr %ptr134 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)135 %val = extractvalue {i32, i1} %t, 0136 %obit = extractvalue {i32, i1} %t, 1137 store i32 %val, ptr %res138 ret i1 %obit139}140 141; Check the next word up, which needs separate address logic.142; Other sequences besides this one would be OK.143define zeroext i1 @f8(i32 %dummy, i32 %a, ptr %src, ptr %res) {144; CHECK-LABEL: f8:145; CHECK: # %bb.0:146; CHECK-NEXT: agfi %r4, 524288147; CHECK-NEXT: al %r3, 0(%r4)148; CHECK-NEXT: ipm %r0149; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35150; CHECK-NEXT: st %r3, 0(%r5)151; CHECK-NEXT: br %r14152 %ptr = getelementptr i32, ptr %src, i64 131072153 %b = load i32, ptr %ptr154 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)155 %val = extractvalue {i32, i1} %t, 0156 %obit = extractvalue {i32, i1} %t, 1157 store i32 %val, ptr %res158 ret i1 %obit159}160 161; Check the high end of the negative aligned ALY range.162define zeroext i1 @f9(i32 %dummy, i32 %a, ptr %src, ptr %res) {163; CHECK-LABEL: f9:164; CHECK: # %bb.0:165; CHECK-NEXT: aly %r3, -4(%r4)166; CHECK-NEXT: ipm %r0167; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35168; CHECK-NEXT: st %r3, 0(%r5)169; CHECK-NEXT: br %r14170 %ptr = getelementptr i32, ptr %src, i64 -1171 %b = load i32, ptr %ptr172 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)173 %val = extractvalue {i32, i1} %t, 0174 %obit = extractvalue {i32, i1} %t, 1175 store i32 %val, ptr %res176 ret i1 %obit177}178 179; Check the low end of the ALY range.180define zeroext i1 @f10(i32 %dummy, i32 %a, ptr %src, ptr %res) {181; CHECK-LABEL: f10:182; CHECK: # %bb.0:183; CHECK-NEXT: aly %r3, -524288(%r4)184; CHECK-NEXT: ipm %r0185; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35186; CHECK-NEXT: st %r3, 0(%r5)187; CHECK-NEXT: br %r14188 %ptr = getelementptr i32, ptr %src, i64 -131072189 %b = load i32, ptr %ptr190 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)191 %val = extractvalue {i32, i1} %t, 0192 %obit = extractvalue {i32, i1} %t, 1193 store i32 %val, ptr %res194 ret i1 %obit195}196 197; Check the next word down, which needs separate address logic.198; Other sequences besides this one would be OK.199define zeroext i1 @f11(i32 %dummy, i32 %a, ptr %src, ptr %res) {200; CHECK-LABEL: f11:201; CHECK: # %bb.0:202; CHECK-NEXT: agfi %r4, -524292203; CHECK-NEXT: al %r3, 0(%r4)204; CHECK-NEXT: ipm %r0205; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35206; CHECK-NEXT: st %r3, 0(%r5)207; CHECK-NEXT: br %r14208 %ptr = getelementptr i32, ptr %src, i64 -131073209 %b = load i32, ptr %ptr210 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)211 %val = extractvalue {i32, i1} %t, 0212 %obit = extractvalue {i32, i1} %t, 1213 store i32 %val, ptr %res214 ret i1 %obit215}216 217; Check that AL allows an index.218define zeroext i1 @f12(i64 %src, i64 %index, i32 %a, ptr %res) {219; CHECK-LABEL: f12:220; CHECK: # %bb.0:221; CHECK-NEXT: al %r4, 4092(%r3,%r2)222; CHECK-NEXT: ipm %r0223; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35224; CHECK-NEXT: st %r4, 0(%r5)225; CHECK-NEXT: br %r14226 %add1 = add i64 %src, %index227 %add2 = add i64 %add1, 4092228 %ptr = inttoptr i64 %add2 to ptr229 %b = load i32, ptr %ptr230 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)231 %val = extractvalue {i32, i1} %t, 0232 %obit = extractvalue {i32, i1} %t, 1233 store i32 %val, ptr %res234 ret i1 %obit235}236 237; Check that ALY allows an index.238define zeroext i1 @f13(i64 %src, i64 %index, i32 %a, ptr %res) {239; CHECK-LABEL: f13:240; CHECK: # %bb.0:241; CHECK-NEXT: aly %r4, 4096(%r3,%r2)242; CHECK-NEXT: ipm %r0243; CHECK-NEXT: risbg %r2, %r0, 63, 191, 35244; CHECK-NEXT: st %r4, 0(%r5)245; CHECK-NEXT: br %r14246 %add1 = add i64 %src, %index247 %add2 = add i64 %add1, 4096248 %ptr = inttoptr i64 %add2 to ptr249 %b = load i32, ptr %ptr250 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)251 %val = extractvalue {i32, i1} %t, 0252 %obit = extractvalue {i32, i1} %t, 1253 store i32 %val, ptr %res254 ret i1 %obit255}256 257; Check that additions of spilled values can use AL rather than ALR.258define zeroext i1 @f14(ptr %ptr0) {259; CHECK-LABEL: f14:260; CHECK: # %bb.0:261; CHECK-NEXT: stmg %r6, %r15, 48(%r15)262; CHECK-NEXT: .cfi_offset %r6, -112263; CHECK-NEXT: .cfi_offset %r7, -104264; CHECK-NEXT: .cfi_offset %r8, -96265; CHECK-NEXT: .cfi_offset %r9, -88266; CHECK-NEXT: .cfi_offset %r10, -80267; CHECK-NEXT: .cfi_offset %r11, -72268; CHECK-NEXT: .cfi_offset %r12, -64269; CHECK-NEXT: .cfi_offset %r13, -56270; CHECK-NEXT: .cfi_offset %r14, -48271; CHECK-NEXT: .cfi_offset %r15, -40272; CHECK-NEXT: aghi %r15, -168273; CHECK-NEXT: .cfi_def_cfa_offset 328274; CHECK-NEXT: l %r7, 0(%r2)275; CHECK-NEXT: l %r6, 8(%r2)276; CHECK-NEXT: l %r13, 16(%r2)277; CHECK-NEXT: l %r12, 24(%r2)278; CHECK-NEXT: l %r8, 32(%r2)279; CHECK-NEXT: l %r9, 40(%r2)280; CHECK-NEXT: l %r10, 48(%r2)281; CHECK-NEXT: l %r11, 56(%r2)282; CHECK-NEXT: mvc 160(4,%r15), 64(%r2) # 4-byte Folded Spill283; CHECK-NEXT: mvc 164(4,%r15), 72(%r2) # 4-byte Folded Spill284; CHECK-NEXT: brasl %r14, foo@PLT285; CHECK-NEXT: alr %r2, %r7286; CHECK-NEXT: ipm %r0287; CHECK-NEXT: risbg %r0, %r0, 63, 191, 35288; CHECK-NEXT: alr %r2, %r6289; CHECK-NEXT: ipm %r1290; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35291; CHECK-NEXT: alr %r2, %r13292; CHECK-NEXT: ipm %r1293; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35294; CHECK-NEXT: alr %r2, %r12295; CHECK-NEXT: ipm %r1296; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35297; CHECK-NEXT: alr %r2, %r8298; CHECK-NEXT: ipm %r1299; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35300; CHECK-NEXT: alr %r2, %r9301; CHECK-NEXT: ipm %r1302; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35303; CHECK-NEXT: alr %r2, %r10304; CHECK-NEXT: ipm %r1305; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35306; CHECK-NEXT: alr %r2, %r11307; CHECK-NEXT: ipm %r1308; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35309; CHECK-NEXT: al %r2, 160(%r15) # 4-byte Folded Reload310; CHECK-NEXT: ipm %r1311; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35312; CHECK-NEXT: al %r2, 164(%r15) # 4-byte Folded Reload313; CHECK-NEXT: ipm %r1314; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 35315; CHECK-NEXT: risbg %r2, %r0, 63, 191, 0316; CHECK-NEXT: lmg %r6, %r15, 216(%r15)317; CHECK-NEXT: br %r14318 %ptr1 = getelementptr i32, ptr %ptr0, i64 2319 %ptr2 = getelementptr i32, ptr %ptr0, i64 4320 %ptr3 = getelementptr i32, ptr %ptr0, i64 6321 %ptr4 = getelementptr i32, ptr %ptr0, i64 8322 %ptr5 = getelementptr i32, ptr %ptr0, i64 10323 %ptr6 = getelementptr i32, ptr %ptr0, i64 12324 %ptr7 = getelementptr i32, ptr %ptr0, i64 14325 %ptr8 = getelementptr i32, ptr %ptr0, i64 16326 %ptr9 = getelementptr i32, ptr %ptr0, i64 18327 328 %val0 = load i32, ptr %ptr0329 %val1 = load i32, ptr %ptr1330 %val2 = load i32, ptr %ptr2331 %val3 = load i32, ptr %ptr3332 %val4 = load i32, ptr %ptr4333 %val5 = load i32, ptr %ptr5334 %val6 = load i32, ptr %ptr6335 %val7 = load i32, ptr %ptr7336 %val8 = load i32, ptr %ptr8337 %val9 = load i32, ptr %ptr9338 339 %ret = call i32 @foo()340 341 %t0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %ret, i32 %val0)342 %add0 = extractvalue {i32, i1} %t0, 0343 %obit0 = extractvalue {i32, i1} %t0, 1344 %t1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add0, i32 %val1)345 %add1 = extractvalue {i32, i1} %t1, 0346 %obit1 = extractvalue {i32, i1} %t1, 1347 %res1 = or i1 %obit0, %obit1348 %t2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add1, i32 %val2)349 %add2 = extractvalue {i32, i1} %t2, 0350 %obit2 = extractvalue {i32, i1} %t2, 1351 %res2 = or i1 %res1, %obit2352 %t3 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add2, i32 %val3)353 %add3 = extractvalue {i32, i1} %t3, 0354 %obit3 = extractvalue {i32, i1} %t3, 1355 %res3 = or i1 %res2, %obit3356 %t4 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add3, i32 %val4)357 %add4 = extractvalue {i32, i1} %t4, 0358 %obit4 = extractvalue {i32, i1} %t4, 1359 %res4 = or i1 %res3, %obit4360 %t5 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add4, i32 %val5)361 %add5 = extractvalue {i32, i1} %t5, 0362 %obit5 = extractvalue {i32, i1} %t5, 1363 %res5 = or i1 %res4, %obit5364 %t6 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add5, i32 %val6)365 %add6 = extractvalue {i32, i1} %t6, 0366 %obit6 = extractvalue {i32, i1} %t6, 1367 %res6 = or i1 %res5, %obit6368 %t7 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add6, i32 %val7)369 %add7 = extractvalue {i32, i1} %t7, 0370 %obit7 = extractvalue {i32, i1} %t7, 1371 %res7 = or i1 %res6, %obit7372 %t8 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add7, i32 %val8)373 %add8 = extractvalue {i32, i1} %t8, 0374 %obit8 = extractvalue {i32, i1} %t8, 1375 %res8 = or i1 %res7, %obit8376 %t9 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %add8, i32 %val9)377 %add9 = extractvalue {i32, i1} %t9, 0378 %obit9 = extractvalue {i32, i1} %t9, 1379 %res9 = or i1 %res8, %obit9380 381 ret i1 %res9382}383 384declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone385 386