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 6 declare i64 @foo() 7 8 ; Check additions of 1. 9 define 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. 24 define 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. 39 define 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. 54 define 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. 69 define 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. 84 define 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. 97 define 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 109 call: 110 tail call i64 @foo() 111 br label %exit 112 113 exit: 114 ret void 115 } 116 117 ; ... and the same with the inverted direction. 118 define 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 130 call: 131 tail call i64 @foo() 132 br label %exit 133 134 exit: 135 ret void 136 } 137 138 139 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 140 141