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