1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 2; Test 64-bit addition in which the second operand is constant and in which 3; three-operand forms are available. 4; 5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 6 7declare i64 @foo() 8 9; Check subtraction of 1. 10define zeroext i1 @f1(i64 %dummy, i64 %a, ptr %res) { 11; CHECK-LABEL: f1: 12; CHECK: # %bb.0: 13; CHECK-NEXT: alghsik %r0, %r3, -1 14; CHECK-NEXT: stg %r0, 0(%r4) 15; CHECK-NEXT: ipm %r1 16; CHECK-NEXT: afi %r1, -536870912 17; CHECK-NEXT: risbg %r2, %r1, 63, 191, 33 18; CHECK-NEXT: br %r14 19 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1) 20 %val = extractvalue {i64, i1} %t, 0 21 %obit = extractvalue {i64, i1} %t, 1 22 store i64 %val, ptr %res 23 ret i1 %obit 24} 25 26; Check the high end of the ALGHSIK range. 27define zeroext i1 @f2(i64 %dummy, i64 %a, ptr %res) { 28; CHECK-LABEL: f2: 29; CHECK: # %bb.0: 30; CHECK-NEXT: alghsik %r0, %r3, -32768 31; CHECK-NEXT: stg %r0, 0(%r4) 32; CHECK-NEXT: ipm %r1 33; CHECK-NEXT: afi %r1, -536870912 34; CHECK-NEXT: risbg %r2, %r1, 63, 191, 33 35; CHECK-NEXT: br %r14 36 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 32768) 37 %val = extractvalue {i64, i1} %t, 0 38 %obit = extractvalue {i64, i1} %t, 1 39 store i64 %val, ptr %res 40 ret i1 %obit 41} 42 43; Check the next value up, which must use SLGFI instead. 44define zeroext i1 @f3(i64 %dummy, i64 %a, ptr %res) { 45; CHECK-LABEL: f3: 46; CHECK: # %bb.0: 47; CHECK-NEXT: slgfi %r3, 32769 48; CHECK-NEXT: stg %r3, 0(%r4) 49; CHECK-NEXT: ipm %r0 50; CHECK-NEXT: afi %r0, -536870912 51; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33 52; CHECK-NEXT: br %r14 53 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 32769) 54 %val = extractvalue {i64, i1} %t, 0 55 %obit = extractvalue {i64, i1} %t, 1 56 store i64 %val, ptr %res 57 ret i1 %obit 58} 59 60; Check the high end of the negative ALGHSIK range. 61define zeroext i1 @f4(i64 %dummy, i64 %a, ptr %res) { 62; CHECK-LABEL: f4: 63; CHECK: # %bb.0: 64; CHECK-NEXT: alghsik %r0, %r3, 1 65; CHECK-NEXT: stg %r0, 0(%r4) 66; CHECK-NEXT: ipm %r1 67; CHECK-NEXT: afi %r1, -536870912 68; CHECK-NEXT: risbg %r2, %r1, 63, 191, 33 69; CHECK-NEXT: br %r14 70 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -1) 71 %val = extractvalue {i64, i1} %t, 0 72 %obit = extractvalue {i64, i1} %t, 1 73 store i64 %val, ptr %res 74 ret i1 %obit 75} 76 77; Check the low end of the ALGHSIK range. 78define zeroext i1 @f5(i64 %dummy, i64 %a, ptr %res) { 79; CHECK-LABEL: f5: 80; CHECK: # %bb.0: 81; CHECK-NEXT: alghsik %r0, %r3, 32767 82; CHECK-NEXT: stg %r0, 0(%r4) 83; CHECK-NEXT: ipm %r1 84; CHECK-NEXT: afi %r1, -536870912 85; CHECK-NEXT: risbg %r2, %r1, 63, 191, 33 86; CHECK-NEXT: br %r14 87 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -32767) 88 %val = extractvalue {i64, i1} %t, 0 89 %obit = extractvalue {i64, i1} %t, 1 90 store i64 %val, ptr %res 91 ret i1 %obit 92} 93 94; Test the next value down, which cannot use either ALGHSIK or SLGFI. 95define zeroext i1 @f6(i64 %dummy, i64 %a, ptr %res) { 96; CHECK-LABEL: f6: 97; CHECK: # %bb.0: 98; CHECK-NEXT: lghi %r0, -32768 99; CHECK-NEXT: slgr %r3, %r0 100; CHECK-NEXT: ipm %r0 101; CHECK-NEXT: afi %r0, -536870912 102; CHECK-NEXT: risbg %r2, %r0, 63, 191, 33 103; CHECK-NEXT: stg %r3, 0(%r4) 104; CHECK-NEXT: br %r14 105 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 -32768) 106 %val = extractvalue {i64, i1} %t, 0 107 %obit = extractvalue {i64, i1} %t, 1 108 store i64 %val, ptr %res 109 ret i1 %obit 110} 111 112; Check using the overflow result for a branch. 113define void @f7(i64 %dummy, i64 %a, ptr %res) { 114; CHECK-LABEL: f7: 115; CHECK: # %bb.0: 116; CHECK-NEXT: alghsik %r0, %r3, -1 117; CHECK-NEXT: stg %r0, 0(%r4) 118; CHECK-NEXT: jgle foo@PLT 119; CHECK-NEXT: .LBB6_1: # %exit 120; CHECK-NEXT: br %r14 121 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1) 122 %val = extractvalue {i64, i1} %t, 0 123 %obit = extractvalue {i64, i1} %t, 1 124 store i64 %val, ptr %res 125 br i1 %obit, label %call, label %exit 126 127call: 128 tail call i64 @foo() 129 br label %exit 130 131exit: 132 ret void 133} 134 135; ... and the same with the inverted direction. 136define void @f8(i64 %dummy, i64 %a, ptr %res) { 137; CHECK-LABEL: f8: 138; CHECK: # %bb.0: 139; CHECK-NEXT: alghsik %r0, %r3, -1 140; CHECK-NEXT: stg %r0, 0(%r4) 141; CHECK-NEXT: jgnle foo@PLT 142; CHECK-NEXT: .LBB7_1: # %exit 143; CHECK-NEXT: br %r14 144 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 1) 145 %val = extractvalue {i64, i1} %t, 0 146 %obit = extractvalue {i64, i1} %t, 1 147 store i64 %val, ptr %res 148 br i1 %obit, label %exit, label %call 149 150call: 151 tail call i64 @foo() 152 br label %exit 153 154exit: 155 ret void 156} 157 158 159declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 160 161