brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · c040a50 Raw
326 lines · plain
1; Test 32-bit addition in which the second operand is variable.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare i32 @foo()6 7; Check AR.8define zeroext i1 @f1(i32 %dummy, i32 %a, i32 %b, ptr %res) {9; CHECK-LABEL: f1:10; CHECK: ar %r3, %r411; CHECK-DAG: st %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 {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)17  %val = extractvalue {i32, i1} %t, 018  %obit = extractvalue {i32, i1} %t, 119  store i32 %val, ptr %res20  ret i1 %obit21}22 23; Check using the overflow result for a branch.24define void @f2(i32 %dummy, i32 %a, i32 %b, ptr %res) {25; CHECK-LABEL: f2:26; CHECK: ar %r3, %r427; CHECK: st %r3, 0(%r5)28; CHECK: jgo foo@PLT29; CHECK: br %r1430  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)31  %val = extractvalue {i32, i1} %t, 032  %obit = extractvalue {i32, i1} %t, 133  store i32 %val, ptr %res34  br i1 %obit, label %call, label %exit35 36call:37  tail call i32 @foo()38  br label %exit39 40exit:41  ret void42}43 44; ... and the same with the inverted direction.45define void @f3(i32 %dummy, i32 %a, i32 %b, ptr %res) {46; CHECK-LABEL: f3:47; CHECK: ar %r3, %r448; CHECK: st %r3, 0(%r5)49; CHECK: jgno foo@PLT50; CHECK: br %r1451  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)52  %val = extractvalue {i32, i1} %t, 053  %obit = extractvalue {i32, i1} %t, 154  store i32 %val, ptr %res55  br i1 %obit, label %exit, label %call56 57call:58  tail call i32 @foo()59  br label %exit60 61exit:62  ret void63}64 65; Check the low end of the A range.66define zeroext i1 @f4(i32 %dummy, i32 %a, ptr %src, ptr %res) {67; CHECK-LABEL: f4:68; CHECK: a %r3, 0(%r4)69; CHECK-DAG: st %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 i32, ptr %src75  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)76  %val = extractvalue {i32, i1} %t, 077  %obit = extractvalue {i32, i1} %t, 178  store i32 %val, ptr %res79  ret i1 %obit80}81 82; Check the high end of the aligned A range.83define zeroext i1 @f5(i32 %dummy, i32 %a, ptr %src, ptr %res) {84; CHECK-LABEL: f5:85; CHECK: a %r3, 4092(%r4)86; CHECK-DAG: st %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 i32, ptr %src, i64 102392  %b = load i32, ptr %ptr93  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)94  %val = extractvalue {i32, i1} %t, 095  %obit = extractvalue {i32, i1} %t, 196  store i32 %val, ptr %res97  ret i1 %obit98}99 100; Check the next word up, which should use AY instead of A.101define zeroext i1 @f6(i32 %dummy, i32 %a, ptr %src, ptr %res) {102; CHECK-LABEL: f6:103; CHECK: ay %r3, 4096(%r4)104; CHECK-DAG: st %r3, 0(%r5)105; CHECK-DAG: ipm [[REG:%r[0-5]]]106; CHECK-DAG: afi [[REG]], 1342177280107; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33108; CHECK: br %r14109  %ptr = getelementptr i32, ptr %src, i64 1024110  %b = load i32, ptr %ptr111  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)112  %val = extractvalue {i32, i1} %t, 0113  %obit = extractvalue {i32, i1} %t, 1114  store i32 %val, ptr %res115  ret i1 %obit116}117 118; Check the high end of the aligned AY range.119define zeroext i1 @f7(i32 %dummy, i32 %a, ptr %src, ptr %res) {120; CHECK-LABEL: f7:121; CHECK: ay %r3, 524284(%r4)122; CHECK-DAG: st %r3, 0(%r5)123; CHECK-DAG: ipm [[REG:%r[0-5]]]124; CHECK-DAG: afi [[REG]], 1342177280125; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33126; CHECK: br %r14127  %ptr = getelementptr i32, ptr %src, i64 131071128  %b = load i32, ptr %ptr129  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)130  %val = extractvalue {i32, i1} %t, 0131  %obit = extractvalue {i32, i1} %t, 1132  store i32 %val, ptr %res133  ret i1 %obit134}135 136; Check the next word up, which needs separate address logic.137; Other sequences besides this one would be OK.138define zeroext i1 @f8(i32 %dummy, i32 %a, ptr %src, ptr %res) {139; CHECK-LABEL: f8:140; CHECK: agfi %r4, 524288141; CHECK: a %r3, 0(%r4)142; CHECK-DAG: st %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 i32, ptr %src, i64 131072148  %b = load i32, ptr %ptr149  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)150  %val = extractvalue {i32, i1} %t, 0151  %obit = extractvalue {i32, i1} %t, 1152  store i32 %val, ptr %res153  ret i1 %obit154}155 156; Check the high end of the negative aligned AY range.157define zeroext i1 @f9(i32 %dummy, i32 %a, ptr %src, ptr %res) {158; CHECK-LABEL: f9:159; CHECK: ay %r3, -4(%r4)160; CHECK-DAG: st %r3, 0(%r5)161; CHECK-DAG: ipm [[REG:%r[0-5]]]162; CHECK-DAG: afi [[REG]], 1342177280163; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33164; CHECK: br %r14165  %ptr = getelementptr i32, ptr %src, i64 -1166  %b = load i32, ptr %ptr167  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)168  %val = extractvalue {i32, i1} %t, 0169  %obit = extractvalue {i32, i1} %t, 1170  store i32 %val, ptr %res171  ret i1 %obit172}173 174; Check the low end of the AY range.175define zeroext i1 @f10(i32 %dummy, i32 %a, ptr %src, ptr %res) {176; CHECK-LABEL: f10:177; CHECK: ay %r3, -524288(%r4)178; CHECK-DAG: st %r3, 0(%r5)179; CHECK-DAG: ipm [[REG:%r[0-5]]]180; CHECK-DAG: afi [[REG]], 1342177280181; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33182; CHECK: br %r14183  %ptr = getelementptr i32, ptr %src, i64 -131072184  %b = load i32, ptr %ptr185  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)186  %val = extractvalue {i32, i1} %t, 0187  %obit = extractvalue {i32, i1} %t, 1188  store i32 %val, ptr %res189  ret i1 %obit190}191 192; Check the next word down, which needs separate address logic.193; Other sequences besides this one would be OK.194define zeroext i1 @f11(i32 %dummy, i32 %a, ptr %src, ptr %res) {195; CHECK-LABEL: f11:196; CHECK: agfi %r4, -524292197; CHECK: a %r3, 0(%r4)198; CHECK-DAG: st %r3, 0(%r5)199; CHECK-DAG: ipm [[REG:%r[0-5]]]200; CHECK-DAG: afi [[REG]], 1342177280201; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33202; CHECK: br %r14203  %ptr = getelementptr i32, ptr %src, i64 -131073204  %b = load i32, ptr %ptr205  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)206  %val = extractvalue {i32, i1} %t, 0207  %obit = extractvalue {i32, i1} %t, 1208  store i32 %val, ptr %res209  ret i1 %obit210}211 212; Check that A allows an index.213define zeroext i1 @f12(i64 %src, i64 %index, i32 %a, ptr %res) {214; CHECK-LABEL: f12:215; CHECK: a %r4, 4092({{%r3,%r2|%r2,%r3}})216; CHECK-DAG: st %r4, 0(%r5)217; CHECK-DAG: ipm [[REG:%r[0-5]]]218; CHECK-DAG: afi [[REG]], 1342177280219; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33220; CHECK: br %r14221  %add1 = add i64 %src, %index222  %add2 = add i64 %add1, 4092223  %ptr = inttoptr i64 %add2 to ptr224  %b = load i32, ptr %ptr225  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)226  %val = extractvalue {i32, i1} %t, 0227  %obit = extractvalue {i32, i1} %t, 1228  store i32 %val, ptr %res229  ret i1 %obit230}231 232; Check that AY allows an index.233define zeroext i1 @f13(i64 %src, i64 %index, i32 %a, ptr %res) {234; CHECK-LABEL: f13:235; CHECK: ay %r4, 4096({{%r3,%r2|%r2,%r3}})236; CHECK-DAG: st %r4, 0(%r5)237; CHECK-DAG: ipm [[REG:%r[0-5]]]238; CHECK-DAG: afi [[REG]], 1342177280239; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33240; CHECK: br %r14241  %add1 = add i64 %src, %index242  %add2 = add i64 %add1, 4096243  %ptr = inttoptr i64 %add2 to ptr244  %b = load i32, ptr %ptr245  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)246  %val = extractvalue {i32, i1} %t, 0247  %obit = extractvalue {i32, i1} %t, 1248  store i32 %val, ptr %res249  ret i1 %obit250}251 252; Check that additions of spilled values can use A rather than AR.253define zeroext i1 @f14(ptr %ptr0) {254; CHECK-LABEL: f14:255; CHECK: brasl %r14, foo@PLT256; CHECK: a %r2, 16{{[04]}}(%r15)257; CHECK: br %r14258  %ptr1 = getelementptr i32, ptr %ptr0, i64 2259  %ptr2 = getelementptr i32, ptr %ptr0, i64 4260  %ptr3 = getelementptr i32, ptr %ptr0, i64 6261  %ptr4 = getelementptr i32, ptr %ptr0, i64 8262  %ptr5 = getelementptr i32, ptr %ptr0, i64 10263  %ptr6 = getelementptr i32, ptr %ptr0, i64 12264  %ptr7 = getelementptr i32, ptr %ptr0, i64 14265  %ptr8 = getelementptr i32, ptr %ptr0, i64 16266  %ptr9 = getelementptr i32, ptr %ptr0, i64 18267 268  %val0 = load i32, ptr %ptr0269  %val1 = load i32, ptr %ptr1270  %val2 = load i32, ptr %ptr2271  %val3 = load i32, ptr %ptr3272  %val4 = load i32, ptr %ptr4273  %val5 = load i32, ptr %ptr5274  %val6 = load i32, ptr %ptr6275  %val7 = load i32, ptr %ptr7276  %val8 = load i32, ptr %ptr8277  %val9 = load i32, ptr %ptr9278 279  %ret = call i32 @foo()280 281  %t0 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %ret, i32 %val0)282  %add0 = extractvalue {i32, i1} %t0, 0283  %obit0 = extractvalue {i32, i1} %t0, 1284  %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add0, i32 %val1)285  %add1 = extractvalue {i32, i1} %t1, 0286  %obit1 = extractvalue {i32, i1} %t1, 1287  %res1 = or i1 %obit0, %obit1288  %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add1, i32 %val2)289  %add2 = extractvalue {i32, i1} %t2, 0290  %obit2 = extractvalue {i32, i1} %t2, 1291  %res2 = or i1 %res1, %obit2292  %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add2, i32 %val3)293  %add3 = extractvalue {i32, i1} %t3, 0294  %obit3 = extractvalue {i32, i1} %t3, 1295  %res3 = or i1 %res2, %obit3296  %t4 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add3, i32 %val4)297  %add4 = extractvalue {i32, i1} %t4, 0298  %obit4 = extractvalue {i32, i1} %t4, 1299  %res4 = or i1 %res3, %obit4300  %t5 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add4, i32 %val5)301  %add5 = extractvalue {i32, i1} %t5, 0302  %obit5 = extractvalue {i32, i1} %t5, 1303  %res5 = or i1 %res4, %obit5304  %t6 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add5, i32 %val6)305  %add6 = extractvalue {i32, i1} %t6, 0306  %obit6 = extractvalue {i32, i1} %t6, 1307  %res6 = or i1 %res5, %obit6308  %t7 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add6, i32 %val7)309  %add7 = extractvalue {i32, i1} %t7, 0310  %obit7 = extractvalue {i32, i1} %t7, 1311  %res7 = or i1 %res6, %obit7312  %t8 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add7, i32 %val8)313  %add8 = extractvalue {i32, i1} %t8, 0314  %obit8 = extractvalue {i32, i1} %t8, 1315  %res8 = or i1 %res7, %obit8316  %t9 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %add8, i32 %val9)317  %add9 = extractvalue {i32, i1} %t9, 0318  %obit9 = extractvalue {i32, i1} %t9, 1319  %res9 = or i1 %res8, %obit9320 321  ret i1 %res9322}323 324declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone325 326