407 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; Test 32-bit subtraction in which the second operand is variable.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s5 6declare i32 @foo()7 8; Check SLR.9define zeroext i1 @f1(i32 %dummy, i32 %a, i32 %b, ptr %res) {10; CHECK-LABEL: f1:11; CHECK: # %bb.0:12; CHECK-NEXT: slr %r3, %r413; CHECK-NEXT: ipm %r014; CHECK-NEXT: afi %r0, -53687091215; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3316; CHECK-NEXT: st %r3, 0(%r5)17; CHECK-NEXT: br %r1418 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)19 %val = extractvalue {i32, i1} %t, 020 %obit = extractvalue {i32, i1} %t, 121 store i32 %val, ptr %res22 ret i1 %obit23}24 25; Check using the overflow result for a branch.26define void @f2(i32 %dummy, i32 %a, i32 %b, ptr %res) {27; CHECK-LABEL: f2:28; CHECK: # %bb.0:29; CHECK-NEXT: slr %r3, %r430; CHECK-NEXT: st %r3, 0(%r5)31; CHECK-NEXT: jgle foo@PLT32; CHECK-NEXT: .LBB1_1: # %exit33; CHECK-NEXT: br %r1434 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)35 %val = extractvalue {i32, i1} %t, 036 %obit = extractvalue {i32, i1} %t, 137 store i32 %val, ptr %res38 br i1 %obit, label %call, label %exit39 40call:41 tail call i32 @foo()42 br label %exit43 44exit:45 ret void46}47 48; ... and the same with the inverted direction.49define void @f3(i32 %dummy, i32 %a, i32 %b, ptr %res) {50; CHECK-LABEL: f3:51; CHECK: # %bb.0:52; CHECK-NEXT: slr %r3, %r453; CHECK-NEXT: st %r3, 0(%r5)54; CHECK-NEXT: jgnle foo@PLT55; CHECK-NEXT: .LBB2_1: # %exit56; CHECK-NEXT: br %r1457 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)58 %val = extractvalue {i32, i1} %t, 059 %obit = extractvalue {i32, i1} %t, 160 store i32 %val, ptr %res61 br i1 %obit, label %exit, label %call62 63call:64 tail call i32 @foo()65 br label %exit66 67exit:68 ret void69}70 71; Check the low end of the SL range.72define zeroext i1 @f4(i32 %dummy, i32 %a, ptr %src, ptr %res) {73; CHECK-LABEL: f4:74; CHECK: # %bb.0:75; CHECK-NEXT: sl %r3, 0(%r4)76; CHECK-NEXT: ipm %r077; CHECK-NEXT: afi %r0, -53687091278; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3379; CHECK-NEXT: st %r3, 0(%r5)80; CHECK-NEXT: br %r1481 %b = load i32, ptr %src82 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)83 %val = extractvalue {i32, i1} %t, 084 %obit = extractvalue {i32, i1} %t, 185 store i32 %val, ptr %res86 ret i1 %obit87}88 89; Check the high end of the aligned SL range.90define zeroext i1 @f5(i32 %dummy, i32 %a, ptr %src, ptr %res) {91; CHECK-LABEL: f5:92; CHECK: # %bb.0:93; CHECK-NEXT: sl %r3, 4092(%r4)94; CHECK-NEXT: ipm %r095; CHECK-NEXT: afi %r0, -53687091296; CHECK-NEXT: risbg %r2, %r0, 63, 191, 3397; CHECK-NEXT: st %r3, 0(%r5)98; CHECK-NEXT: br %r1499 %ptr = getelementptr i32, ptr %src, i64 1023100 %b = load i32, ptr %ptr101 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)102 %val = extractvalue {i32, i1} %t, 0103 %obit = extractvalue {i32, i1} %t, 1104 store i32 %val, ptr %res105 ret i1 %obit106}107 108; Check the next word up, which should use SLY instead of SL.109define zeroext i1 @f6(i32 %dummy, i32 %a, ptr %src, ptr %res) {110; CHECK-LABEL: f6:111; CHECK: # %bb.0:112; CHECK-NEXT: sly %r3, 4096(%r4)113; CHECK-NEXT: ipm %r0114; CHECK-NEXT: afi %r0, -536870912115; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33116; CHECK-NEXT: st %r3, 0(%r5)117; CHECK-NEXT: br %r14118 %ptr = getelementptr i32, ptr %src, i64 1024119 %b = load i32, ptr %ptr120 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)121 %val = extractvalue {i32, i1} %t, 0122 %obit = extractvalue {i32, i1} %t, 1123 store i32 %val, ptr %res124 ret i1 %obit125}126 127; Check the high end of the aligned SLY range.128define zeroext i1 @f7(i32 %dummy, i32 %a, ptr %src, ptr %res) {129; CHECK-LABEL: f7:130; CHECK: # %bb.0:131; CHECK-NEXT: sly %r3, 524284(%r4)132; CHECK-NEXT: ipm %r0133; CHECK-NEXT: afi %r0, -536870912134; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33135; CHECK-NEXT: st %r3, 0(%r5)136; CHECK-NEXT: br %r14137 %ptr = getelementptr i32, ptr %src, i64 131071138 %b = load i32, ptr %ptr139 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)140 %val = extractvalue {i32, i1} %t, 0141 %obit = extractvalue {i32, i1} %t, 1142 store i32 %val, ptr %res143 ret i1 %obit144}145 146; Check the next word up, which needs separate address logic.147; Other sequences besides this one would be OK.148define zeroext i1 @f8(i32 %dummy, i32 %a, ptr %src, ptr %res) {149; CHECK-LABEL: f8:150; CHECK: # %bb.0:151; CHECK-NEXT: agfi %r4, 524288152; CHECK-NEXT: sl %r3, 0(%r4)153; CHECK-NEXT: ipm %r0154; CHECK-NEXT: afi %r0, -536870912155; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33156; CHECK-NEXT: st %r3, 0(%r5)157; CHECK-NEXT: br %r14158 %ptr = getelementptr i32, ptr %src, i64 131072159 %b = load i32, ptr %ptr160 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)161 %val = extractvalue {i32, i1} %t, 0162 %obit = extractvalue {i32, i1} %t, 1163 store i32 %val, ptr %res164 ret i1 %obit165}166 167; Check the high end of the negative aligned SLY range.168define zeroext i1 @f9(i32 %dummy, i32 %a, ptr %src, ptr %res) {169; CHECK-LABEL: f9:170; CHECK: # %bb.0:171; CHECK-NEXT: sly %r3, -4(%r4)172; CHECK-NEXT: ipm %r0173; CHECK-NEXT: afi %r0, -536870912174; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33175; CHECK-NEXT: st %r3, 0(%r5)176; CHECK-NEXT: br %r14177 %ptr = getelementptr i32, ptr %src, i64 -1178 %b = load i32, ptr %ptr179 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)180 %val = extractvalue {i32, i1} %t, 0181 %obit = extractvalue {i32, i1} %t, 1182 store i32 %val, ptr %res183 ret i1 %obit184}185 186; Check the low end of the SLY range.187define zeroext i1 @f10(i32 %dummy, i32 %a, ptr %src, ptr %res) {188; CHECK-LABEL: f10:189; CHECK: # %bb.0:190; CHECK-NEXT: sly %r3, -524288(%r4)191; CHECK-NEXT: ipm %r0192; CHECK-NEXT: afi %r0, -536870912193; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33194; CHECK-NEXT: st %r3, 0(%r5)195; CHECK-NEXT: br %r14196 %ptr = getelementptr i32, ptr %src, i64 -131072197 %b = load i32, ptr %ptr198 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)199 %val = extractvalue {i32, i1} %t, 0200 %obit = extractvalue {i32, i1} %t, 1201 store i32 %val, ptr %res202 ret i1 %obit203}204 205; Check the next word down, which needs separate address logic.206; Other sequences besides this one would be OK.207define zeroext i1 @f11(i32 %dummy, i32 %a, ptr %src, ptr %res) {208; CHECK-LABEL: f11:209; CHECK: # %bb.0:210; CHECK-NEXT: agfi %r4, -524292211; CHECK-NEXT: sl %r3, 0(%r4)212; CHECK-NEXT: ipm %r0213; CHECK-NEXT: afi %r0, -536870912214; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33215; CHECK-NEXT: st %r3, 0(%r5)216; CHECK-NEXT: br %r14217 %ptr = getelementptr i32, ptr %src, i64 -131073218 %b = load i32, ptr %ptr219 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)220 %val = extractvalue {i32, i1} %t, 0221 %obit = extractvalue {i32, i1} %t, 1222 store i32 %val, ptr %res223 ret i1 %obit224}225 226; Check that SL allows an index.227define zeroext i1 @f12(i64 %src, i64 %index, i32 %a, ptr %res) {228; CHECK-LABEL: f12:229; CHECK: # %bb.0:230; CHECK-NEXT: sl %r4, 4092(%r3,%r2)231; CHECK-NEXT: ipm %r0232; CHECK-NEXT: afi %r0, -536870912233; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33234; CHECK-NEXT: st %r4, 0(%r5)235; CHECK-NEXT: br %r14236 %add1 = add i64 %src, %index237 %add2 = add i64 %add1, 4092238 %ptr = inttoptr i64 %add2 to ptr239 %b = load i32, ptr %ptr240 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)241 %val = extractvalue {i32, i1} %t, 0242 %obit = extractvalue {i32, i1} %t, 1243 store i32 %val, ptr %res244 ret i1 %obit245}246 247; Check that SLY allows an index.248define zeroext i1 @f13(i64 %src, i64 %index, i32 %a, ptr %res) {249; CHECK-LABEL: f13:250; CHECK: # %bb.0:251; CHECK-NEXT: sly %r4, 4096(%r3,%r2)252; CHECK-NEXT: ipm %r0253; CHECK-NEXT: afi %r0, -536870912254; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33255; CHECK-NEXT: st %r4, 0(%r5)256; CHECK-NEXT: br %r14257 %add1 = add i64 %src, %index258 %add2 = add i64 %add1, 4096259 %ptr = inttoptr i64 %add2 to ptr260 %b = load i32, ptr %ptr261 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)262 %val = extractvalue {i32, i1} %t, 0263 %obit = extractvalue {i32, i1} %t, 1264 store i32 %val, ptr %res265 ret i1 %obit266}267 268; Check that subtractions of spilled values can use SL rather than SLR.269define zeroext i1 @f14(ptr %ptr0) {270; CHECK-LABEL: f14:271; CHECK: # %bb.0:272; CHECK-NEXT: stmg %r6, %r15, 48(%r15)273; CHECK-NEXT: .cfi_offset %r6, -112274; CHECK-NEXT: .cfi_offset %r7, -104275; CHECK-NEXT: .cfi_offset %r8, -96276; CHECK-NEXT: .cfi_offset %r9, -88277; CHECK-NEXT: .cfi_offset %r10, -80278; CHECK-NEXT: .cfi_offset %r11, -72279; CHECK-NEXT: .cfi_offset %r12, -64280; CHECK-NEXT: .cfi_offset %r13, -56281; CHECK-NEXT: .cfi_offset %r14, -48282; CHECK-NEXT: .cfi_offset %r15, -40283; CHECK-NEXT: aghi %r15, -168284; CHECK-NEXT: .cfi_def_cfa_offset 328285; CHECK-NEXT: l %r6, 0(%r2)286; CHECK-NEXT: l %r13, 8(%r2)287; CHECK-NEXT: l %r12, 16(%r2)288; CHECK-NEXT: l %r7, 24(%r2)289; CHECK-NEXT: l %r8, 32(%r2)290; CHECK-NEXT: l %r9, 40(%r2)291; CHECK-NEXT: l %r10, 48(%r2)292; CHECK-NEXT: l %r11, 56(%r2)293; CHECK-NEXT: mvc 160(4,%r15), 64(%r2) # 4-byte Folded Spill294; CHECK-NEXT: mvc 164(4,%r15), 72(%r2) # 4-byte Folded Spill295; CHECK-NEXT: brasl %r14, foo@PLT296; CHECK-NEXT: slr %r2, %r6297; CHECK-NEXT: ipm %r0298; CHECK-NEXT: afi %r0, -536870912299; CHECK-NEXT: srl %r0, 31300; CHECK-NEXT: slr %r2, %r13301; CHECK-NEXT: ipm %r1302; CHECK-NEXT: afi %r1, -536870912303; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33304; CHECK-NEXT: slr %r2, %r12305; CHECK-NEXT: ipm %r1306; CHECK-NEXT: afi %r1, -536870912307; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33308; CHECK-NEXT: slr %r2, %r7309; CHECK-NEXT: ipm %r1310; CHECK-NEXT: afi %r1, -536870912311; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33312; CHECK-NEXT: slr %r2, %r8313; CHECK-NEXT: ipm %r1314; CHECK-NEXT: afi %r1, -536870912315; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33316; CHECK-NEXT: slr %r2, %r9317; CHECK-NEXT: ipm %r1318; CHECK-NEXT: afi %r1, -536870912319; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33320; CHECK-NEXT: slr %r2, %r10321; CHECK-NEXT: ipm %r1322; CHECK-NEXT: afi %r1, -536870912323; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33324; CHECK-NEXT: slr %r2, %r11325; CHECK-NEXT: ipm %r1326; CHECK-NEXT: afi %r1, -536870912327; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33328; CHECK-NEXT: sl %r2, 160(%r15) # 4-byte Folded Reload329; CHECK-NEXT: ipm %r1330; CHECK-NEXT: afi %r1, -536870912331; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33332; CHECK-NEXT: sl %r2, 164(%r15) # 4-byte Folded Reload333; CHECK-NEXT: ipm %r1334; CHECK-NEXT: afi %r1, -536870912335; CHECK-NEXT: rosbg %r0, %r1, 63, 63, 33336; CHECK-NEXT: risbg %r2, %r0, 63, 191, 0337; CHECK-NEXT: lmg %r6, %r15, 216(%r15)338; CHECK-NEXT: br %r14339 %ptr1 = getelementptr i32, ptr %ptr0, i64 2340 %ptr2 = getelementptr i32, ptr %ptr0, i64 4341 %ptr3 = getelementptr i32, ptr %ptr0, i64 6342 %ptr4 = getelementptr i32, ptr %ptr0, i64 8343 %ptr5 = getelementptr i32, ptr %ptr0, i64 10344 %ptr6 = getelementptr i32, ptr %ptr0, i64 12345 %ptr7 = getelementptr i32, ptr %ptr0, i64 14346 %ptr8 = getelementptr i32, ptr %ptr0, i64 16347 %ptr9 = getelementptr i32, ptr %ptr0, i64 18348 349 %val0 = load i32, ptr %ptr0350 %val1 = load i32, ptr %ptr1351 %val2 = load i32, ptr %ptr2352 %val3 = load i32, ptr %ptr3353 %val4 = load i32, ptr %ptr4354 %val5 = load i32, ptr %ptr5355 %val6 = load i32, ptr %ptr6356 %val7 = load i32, ptr %ptr7357 %val8 = load i32, ptr %ptr8358 %val9 = load i32, ptr %ptr9359 360 %ret = call i32 @foo()361 362 %t0 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %ret, i32 %val0)363 %add0 = extractvalue {i32, i1} %t0, 0364 %obit0 = extractvalue {i32, i1} %t0, 1365 %t1 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add0, i32 %val1)366 %add1 = extractvalue {i32, i1} %t1, 0367 %obit1 = extractvalue {i32, i1} %t1, 1368 %res1 = or i1 %obit0, %obit1369 %t2 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add1, i32 %val2)370 %add2 = extractvalue {i32, i1} %t2, 0371 %obit2 = extractvalue {i32, i1} %t2, 1372 %res2 = or i1 %res1, %obit2373 %t3 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add2, i32 %val3)374 %add3 = extractvalue {i32, i1} %t3, 0375 %obit3 = extractvalue {i32, i1} %t3, 1376 %res3 = or i1 %res2, %obit3377 %t4 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add3, i32 %val4)378 %add4 = extractvalue {i32, i1} %t4, 0379 %obit4 = extractvalue {i32, i1} %t4, 1380 %res4 = or i1 %res3, %obit4381 %t5 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add4, i32 %val5)382 %add5 = extractvalue {i32, i1} %t5, 0383 %obit5 = extractvalue {i32, i1} %t5, 1384 %res5 = or i1 %res4, %obit5385 %t6 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add5, i32 %val6)386 %add6 = extractvalue {i32, i1} %t6, 0387 %obit6 = extractvalue {i32, i1} %t6, 1388 %res6 = or i1 %res5, %obit6389 %t7 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add6, i32 %val7)390 %add7 = extractvalue {i32, i1} %t7, 0391 %obit7 = extractvalue {i32, i1} %t7, 1392 %res7 = or i1 %res6, %obit7393 %t8 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add7, i32 %val8)394 %add8 = extractvalue {i32, i1} %t8, 0395 %obit8 = extractvalue {i32, i1} %t8, 1396 %res8 = or i1 %res7, %obit8397 %t9 = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %add8, i32 %val9)398 %add9 = extractvalue {i32, i1} %t9, 0399 %obit9 = extractvalue {i32, i1} %t9, 1400 %res9 = or i1 %res8, %obit9401 402 ret i1 %res9403}404 405declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone406 407