brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.5 KiB · ec36065 Raw
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