brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 4830269 Raw
270 lines · plain
1; Test 64-bit subtraction in which the second operand is variable.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare i64 @foo()6 7; Check SGR.8define zeroext i1 @f1(i64 %dummy, i64 %a, i64 %b, ptr %res) {9; CHECK-LABEL: f1:10; CHECK: sgr %r3, %r411; CHECK-DAG: stg %r3, 0(%r5)12; CHECK-DAG: ipm [[REG:%r[0-5]]]13; CHECK-DAG: afi [[REG]], 134217728014; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3315; CHECK: br %r1416  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)17  %val = extractvalue {i64, i1} %t, 018  %obit = extractvalue {i64, i1} %t, 119  store i64 %val, ptr %res20  ret i1 %obit21}22 23; Check using the overflow result for a branch.24define void @f2(i64 %dummy, i64 %a, i64 %b, ptr %res) {25; CHECK-LABEL: f2:26; CHECK: sgr %r3, %r427; CHECK: stg %r3, 0(%r5)28; CHECK: jgo foo@PLT29; CHECK: br %r1430  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)31  %val = extractvalue {i64, i1} %t, 032  %obit = extractvalue {i64, i1} %t, 133  store i64 %val, ptr %res34  br i1 %obit, label %call, label %exit35 36call:37  tail call i64 @foo()38  br label %exit39 40exit:41  ret void42}43 44; ... and the same with the inverted direction.45define void @f3(i64 %dummy, i64 %a, i64 %b, ptr %res) {46; CHECK-LABEL: f3:47; CHECK: sgr %r3, %r448; CHECK: stg %r3, 0(%r5)49; CHECK: jgno foo@PLT50; CHECK: br %r1451  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)52  %val = extractvalue {i64, i1} %t, 053  %obit = extractvalue {i64, i1} %t, 154  store i64 %val, ptr %res55  br i1 %obit, label %exit, label %call56 57call:58  tail call i64 @foo()59  br label %exit60 61exit:62  ret void63}64 65; Check SG with no displacement.66define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %src, ptr %res) {67; CHECK-LABEL: f4:68; CHECK: sg %r3, 0(%r4)69; CHECK-DAG: stg %r3, 0(%r5)70; CHECK-DAG: ipm [[REG:%r[0-5]]]71; CHECK-DAG: afi [[REG]], 134217728072; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3373; CHECK: br %r1474  %b = load i64, ptr %src75  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)76  %val = extractvalue {i64, i1} %t, 077  %obit = extractvalue {i64, i1} %t, 178  store i64 %val, ptr %res79  ret i1 %obit80}81 82; Check the high end of the aligned SG range.83define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %src, ptr %res) {84; CHECK-LABEL: f5:85; CHECK: sg %r3, 524280(%r4)86; CHECK-DAG: stg %r3, 0(%r5)87; CHECK-DAG: ipm [[REG:%r[0-5]]]88; CHECK-DAG: afi [[REG]], 134217728089; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3390; CHECK: br %r1491  %ptr = getelementptr i64, ptr %src, i64 6553592  %b = load i64, ptr %ptr93  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)94  %val = extractvalue {i64, i1} %t, 095  %obit = extractvalue {i64, i1} %t, 196  store i64 %val, ptr %res97  ret i1 %obit98}99 100; Check the next doubleword up, which needs separate address logic.101; Other sequences besides this one would be OK.102define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %src, ptr %res) {103; CHECK-LABEL: f6:104; CHECK: agfi %r4, 524288105; CHECK: sg %r3, 0(%r4)106; CHECK-DAG: stg %r3, 0(%r5)107; CHECK-DAG: ipm [[REG:%r[0-5]]]108; CHECK-DAG: afi [[REG]], 1342177280109; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33110; CHECK: br %r14111  %ptr = getelementptr i64, ptr %src, i64 65536112  %b = load i64, ptr %ptr113  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)114  %val = extractvalue {i64, i1} %t, 0115  %obit = extractvalue {i64, i1} %t, 1116  store i64 %val, ptr %res117  ret i1 %obit118}119 120; Check the high end of the negative aligned SG range.121define zeroext i1 @f7(i64 %dummy, i64 %a, ptr %src, ptr %res) {122; CHECK-LABEL: f7:123; CHECK: sg %r3, -8(%r4)124; CHECK-DAG: stg %r3, 0(%r5)125; CHECK-DAG: ipm [[REG:%r[0-5]]]126; CHECK-DAG: afi [[REG]], 1342177280127; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33128; CHECK: br %r14129  %ptr = getelementptr i64, ptr %src, i64 -1130  %b = load i64, ptr %ptr131  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)132  %val = extractvalue {i64, i1} %t, 0133  %obit = extractvalue {i64, i1} %t, 1134  store i64 %val, ptr %res135  ret i1 %obit136}137 138; Check the low end of the SG range.139define zeroext i1 @f8(i64 %dummy, i64 %a, ptr %src, ptr %res) {140; CHECK-LABEL: f8:141; CHECK: sg %r3, -524288(%r4)142; CHECK-DAG: stg %r3, 0(%r5)143; CHECK-DAG: ipm [[REG:%r[0-5]]]144; CHECK-DAG: afi [[REG]], 1342177280145; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33146; CHECK: br %r14147  %ptr = getelementptr i64, ptr %src, i64 -65536148  %b = load i64, ptr %ptr149  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)150  %val = extractvalue {i64, i1} %t, 0151  %obit = extractvalue {i64, i1} %t, 1152  store i64 %val, ptr %res153  ret i1 %obit154}155 156; Check the next word down, which needs separate address logic.157; Other sequences besides this one would be OK.158define zeroext i1 @f9(i64 %dummy, i64 %a, ptr %src, ptr %res) {159; CHECK-LABEL: f9:160; CHECK: agfi %r4, -524296161; CHECK: sg %r3, 0(%r4)162; CHECK-DAG: stg %r3, 0(%r5)163; CHECK-DAG: ipm [[REG:%r[0-5]]]164; CHECK-DAG: afi [[REG]], 1342177280165; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33166; CHECK: br %r14167  %ptr = getelementptr i64, ptr %src, i64 -65537168  %b = load i64, ptr %ptr169  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)170  %val = extractvalue {i64, i1} %t, 0171  %obit = extractvalue {i64, i1} %t, 1172  store i64 %val, ptr %res173  ret i1 %obit174}175 176; Check that SG allows an index.177define zeroext i1 @f10(i64 %src, i64 %index, i64 %a, ptr %res) {178; CHECK-LABEL: f10:179; CHECK: sg %r4, 524280({{%r3,%r2|%r2,%r3}})180; CHECK-DAG: stg %r4, 0(%r5)181; CHECK-DAG: ipm [[REG:%r[0-5]]]182; CHECK-DAG: afi [[REG]], 1342177280183; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33184; CHECK: br %r14185  %add1 = add i64 %src, %index186  %add2 = add i64 %add1, 524280187  %ptr = inttoptr i64 %add2 to ptr188  %b = load i64, ptr %ptr189  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)190  %val = extractvalue {i64, i1} %t, 0191  %obit = extractvalue {i64, i1} %t, 1192  store i64 %val, ptr %res193  ret i1 %obit194}195 196; Check that subtractions of spilled values can use SG rather than SGR.197define zeroext i1 @f11(ptr %ptr0) {198; CHECK-LABEL: f11:199; CHECK: brasl %r14, foo@PLT200; CHECK: sg %r2, 16{{[04]}}(%r15)201; CHECK: br %r14202  %ptr1 = getelementptr i64, ptr %ptr0, i64 2203  %ptr2 = getelementptr i64, ptr %ptr0, i64 4204  %ptr3 = getelementptr i64, ptr %ptr0, i64 6205  %ptr4 = getelementptr i64, ptr %ptr0, i64 8206  %ptr5 = getelementptr i64, ptr %ptr0, i64 10207  %ptr6 = getelementptr i64, ptr %ptr0, i64 12208  %ptr7 = getelementptr i64, ptr %ptr0, i64 14209  %ptr8 = getelementptr i64, ptr %ptr0, i64 16210  %ptr9 = getelementptr i64, ptr %ptr0, i64 18211 212  %val0 = load i64, ptr %ptr0213  %val1 = load i64, ptr %ptr1214  %val2 = load i64, ptr %ptr2215  %val3 = load i64, ptr %ptr3216  %val4 = load i64, ptr %ptr4217  %val5 = load i64, ptr %ptr5218  %val6 = load i64, ptr %ptr6219  %val7 = load i64, ptr %ptr7220  %val8 = load i64, ptr %ptr8221  %val9 = load i64, ptr %ptr9222 223  %ret = call i64 @foo()224 225  %t0 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %ret, i64 %val0)226  %add0 = extractvalue {i64, i1} %t0, 0227  %obit0 = extractvalue {i64, i1} %t0, 1228  %t1 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add0, i64 %val1)229  %add1 = extractvalue {i64, i1} %t1, 0230  %obit1 = extractvalue {i64, i1} %t1, 1231  %res1 = or i1 %obit0, %obit1232  %t2 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add1, i64 %val2)233  %add2 = extractvalue {i64, i1} %t2, 0234  %obit2 = extractvalue {i64, i1} %t2, 1235  %res2 = or i1 %res1, %obit2236  %t3 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add2, i64 %val3)237  %add3 = extractvalue {i64, i1} %t3, 0238  %obit3 = extractvalue {i64, i1} %t3, 1239  %res3 = or i1 %res2, %obit3240  %t4 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add3, i64 %val4)241  %add4 = extractvalue {i64, i1} %t4, 0242  %obit4 = extractvalue {i64, i1} %t4, 1243  %res4 = or i1 %res3, %obit4244  %t5 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add4, i64 %val5)245  %add5 = extractvalue {i64, i1} %t5, 0246  %obit5 = extractvalue {i64, i1} %t5, 1247  %res5 = or i1 %res4, %obit5248  %t6 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add5, i64 %val6)249  %add6 = extractvalue {i64, i1} %t6, 0250  %obit6 = extractvalue {i64, i1} %t6, 1251  %res6 = or i1 %res5, %obit6252  %t7 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add6, i64 %val7)253  %add7 = extractvalue {i64, i1} %t7, 0254  %obit7 = extractvalue {i64, i1} %t7, 1255  %res7 = or i1 %res6, %obit7256  %t8 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add7, i64 %val8)257  %add8 = extractvalue {i64, i1} %t8, 0258  %obit8 = extractvalue {i64, i1} %t8, 1259  %res8 = or i1 %res7, %obit8260  %t9 = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %add8, i64 %val9)261  %add9 = extractvalue {i64, i1} %t9, 0262  %obit9 = extractvalue {i64, i1} %t9, 1263  %res9 = or i1 %res8, %obit9264 265  ret i1 %res9266}267 268declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone269 270