215 lines · plain
1; Test 64-bit subtraction in which the second operand is constant.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s5 6declare i32 @foo()7 8; Check subtractions of 1.9define zeroext i1 @f1(i64 %dummy, i64 %a, ptr %res) {10; CHECK-LABEL: f1:11; CHECK: aghi %r3, -112; CHECK-DAG: stg %r3, 0(%r4)13; CHECK-DAG: ipm [[REG:%r[0-5]]]14; CHECK-DAG: afi [[REG]], 134217728015; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3316; CHECK: br %r1417 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)18 %val = extractvalue {i64, i1} %t, 019 %obit = extractvalue {i64, i1} %t, 120 store i64 %val, ptr %res21 ret i1 %obit22 23}24 25; Check the high end of the SGHI range.26define zeroext i1 @f2(i64 %dummy, i64 %a, ptr %res) {27; CHECK-LABEL: f2:28; CHECK: aghi %r3, -3276829; CHECK-DAG: stg %r3, 0(%r4)30; CHECK-DAG: ipm [[REG:%r[0-5]]]31; CHECK-DAG: afi [[REG]], 134217728032; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3333; CHECK: br %r1434 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 32768)35 %val = extractvalue {i64, i1} %t, 036 %obit = extractvalue {i64, i1} %t, 137 store i64 %val, ptr %res38 ret i1 %obit39}40 41; Check the next value up, which must use SGFI instead.42define zeroext i1 @f3(i64 %dummy, i64 %a, ptr %res) {43; CHECK-LABEL: f3:44; CHECK: agfi %r3, -3276945; CHECK-DAG: stg %r3, 0(%r4)46; CHECK-DAG: ipm [[REG:%r[0-5]]]47; CHECK-DAG: afi [[REG]], 134217728048; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3349; CHECK: br %r1450 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 32769)51 %val = extractvalue {i64, i1} %t, 052 %obit = extractvalue {i64, i1} %t, 153 store i64 %val, ptr %res54 ret i1 %obit55}56 57; Check the high end of the SGFI range.58define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %res) {59; CHECK-LABEL: f4:60; CHECK: agfi %r3, -214748364861; CHECK-DAG: stg %r3, 0(%r4)62; CHECK-DAG: ipm [[REG:%r[0-5]]]63; CHECK-DAG: afi [[REG]], 134217728064; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3365; CHECK: br %r1466 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 2147483648)67 %val = extractvalue {i64, i1} %t, 068 %obit = extractvalue {i64, i1} %t, 169 store i64 %val, ptr %res70 ret i1 %obit71}72 73; Check the next value up, which must be loaded into a register first.74define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %res) {75; CHECK-LABEL: f5:76; CHECK: llilf [[REG1:%r[0-9]+]], 214748364977; CHECK: sgr %r3, [[REG1]]78; CHECK-DAG: stg %r3, 0(%r4)79; CHECK-DAG: ipm [[REG:%r[0-5]]]80; CHECK-DAG: afi [[REG]], 134217728081; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3382; CHECK: br %r1483 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 2147483649)84 %val = extractvalue {i64, i1} %t, 085 %obit = extractvalue {i64, i1} %t, 186 store i64 %val, ptr %res87 ret i1 %obit88}89 90; Check the high end of the negative SGHI range.91define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %res) {92; CHECK-LABEL: f6:93; CHECK: aghi %r3, 194; CHECK-DAG: stg %r3, 0(%r4)95; CHECK-DAG: ipm [[REG:%r[0-5]]]96; CHECK-DAG: afi [[REG]], 134217728097; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3398; CHECK: br %r1499 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -1)100 %val = extractvalue {i64, i1} %t, 0101 %obit = extractvalue {i64, i1} %t, 1102 store i64 %val, ptr %res103 ret i1 %obit104}105 106; Check the low end of the SGHI range.107define zeroext i1 @f7(i64 %dummy, i64 %a, ptr %res) {108; CHECK-LABEL: f7:109; CHECK: aghi %r3, 32767110; CHECK-DAG: stg %r3, 0(%r4)111; CHECK-DAG: ipm [[REG:%r[0-5]]]112; CHECK-DAG: afi [[REG]], 1342177280113; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33114; CHECK: br %r14115 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -32767)116 %val = extractvalue {i64, i1} %t, 0117 %obit = extractvalue {i64, i1} %t, 1118 store i64 %val, ptr %res119 ret i1 %obit120}121 122; Check the next value down, which must use SGFI instead.123define zeroext i1 @f8(i64 %dummy, i64 %a, ptr %res) {124; CHECK-LABEL: f8:125; CHECK: agfi %r3, 32768126; CHECK-DAG: stg %r3, 0(%r4)127; CHECK-DAG: ipm [[REG:%r[0-5]]]128; CHECK-DAG: afi [[REG]], 1342177280129; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33130; CHECK: br %r14131 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -32768)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 SGFI range.139define zeroext i1 @f9(i64 %dummy, i64 %a, ptr %res) {140; CHECK-LABEL: f9:141; CHECK: agfi %r3, 2147483647142; CHECK-DAG: stg %r3, 0(%r4)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 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -2147483647)148 %val = extractvalue {i64, i1} %t, 0149 %obit = extractvalue {i64, i1} %t, 1150 store i64 %val, ptr %res151 ret i1 %obit152}153 154; Check the next value down, which must use register subtraction instead.155define zeroext i1 @f10(i64 %dummy, i64 %a, ptr %res) {156; CHECK-LABEL: f10:157; CHECK: llilh [[REG1:%r[0-9]+]], 32768158; CHECK: agr [[REG1]], %r3159; CHECK-DAG: stg [[REG1]], 0(%r4)160; CHECK-DAG: ipm [[REG:%r[0-5]]]161; CHECK-DAG: afi [[REG]], 1342177280162; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33163; CHECK: br %r14164 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -2147483648)165 %val = extractvalue {i64, i1} %t, 0166 %obit = extractvalue {i64, i1} %t, 1167 store i64 %val, ptr %res168 ret i1 %obit169}170 171; Check using the overflow result for a branch.172define void @f11(i64 %dummy, i64 %a, ptr %res) {173; CHECK-LABEL: f11:174; CHECK: aghi %r3, -1175; CHECK: stg %r3, 0(%r4)176; CHECK: {{jgo foo@PLT|bnor %r14}}177; CHECK: {{br %r14|jg foo@PLT}}178 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)179 %val = extractvalue {i64, i1} %t, 0180 %obit = extractvalue {i64, i1} %t, 1181 store i64 %val, ptr %res182 br i1 %obit, label %call, label %exit183 184call:185 tail call i32 @foo()186 br label %exit187 188exit:189 ret void190}191 192; ... and the same with the inverted direction.193define void @f12(i64 %dummy, i64 %a, ptr %res) {194; CHECK-LABEL: f12:195; CHECK: aghi %r3, -1196; CHECK: stg %r3, 0(%r4)197; CHECK: {{jgno foo@PLT|bor %r14}}198; CHECK: {{br %r14|jg foo@PLT}}199 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)200 %val = extractvalue {i64, i1} %t, 0201 %obit = extractvalue {i64, i1} %t, 1202 store i64 %val, ptr %res203 br i1 %obit, label %exit, label %call204 205call:206 tail call i32 @foo()207 br label %exit208 209exit:210 ret void211}212 213declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone214 215