1; Test 32-bit addition in which the second operand is a sign-extended 2; i16 memory value. 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5 6declare i32 @foo() 7 8; Check the low end of the AH range. 9define zeroext i1 @f1(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 10; CHECK-LABEL: f1: 11; CHECK: ah %r3, 0(%r4) 12; CHECK-DAG: st %r3, 0(%r5) 13; CHECK-DAG: ipm [[REG:%r[0-5]]] 14; CHECK-DAG: afi [[REG]], 1342177280 15; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 16; CHECK: br %r14 17 %half = load i16, i16 *%src 18 %b = sext i16 %half to i32 19 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 20 %val = extractvalue {i32, i1} %t, 0 21 %obit = extractvalue {i32, i1} %t, 1 22 store i32 %val, i32 *%res 23 ret i1 %obit 24} 25 26; Check the high end of the aligned AH range. 27define zeroext i1 @f2(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 28; CHECK-LABEL: f2: 29; CHECK: ah %r3, 4094(%r4) 30; CHECK-DAG: st %r3, 0(%r5) 31; CHECK-DAG: ipm [[REG:%r[0-5]]] 32; CHECK-DAG: afi [[REG]], 1342177280 33; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 34; CHECK: br %r14 35 %ptr = getelementptr i16, i16 *%src, i64 2047 36 %half = load i16, i16 *%ptr 37 %b = sext i16 %half to i32 38 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 39 %val = extractvalue {i32, i1} %t, 0 40 %obit = extractvalue {i32, i1} %t, 1 41 store i32 %val, i32 *%res 42 ret i1 %obit 43} 44 45; Check the next halfword up, which should use AHY instead of AH. 46define zeroext i1 @f3(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 47; CHECK-LABEL: f3: 48; CHECK: ahy %r3, 4096(%r4) 49; CHECK-DAG: st %r3, 0(%r5) 50; CHECK-DAG: ipm [[REG:%r[0-5]]] 51; CHECK-DAG: afi [[REG]], 1342177280 52; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 53; CHECK: br %r14 54 %ptr = getelementptr i16, i16 *%src, i64 2048 55 %half = load i16, i16 *%ptr 56 %b = sext i16 %half to i32 57 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 58 %val = extractvalue {i32, i1} %t, 0 59 %obit = extractvalue {i32, i1} %t, 1 60 store i32 %val, i32 *%res 61 ret i1 %obit 62} 63 64; Check the high end of the aligned AHY range. 65define zeroext i1 @f4(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 66; CHECK-LABEL: f4: 67; CHECK: ahy %r3, 524286(%r4) 68; CHECK-DAG: st %r3, 0(%r5) 69; CHECK-DAG: ipm [[REG:%r[0-5]]] 70; CHECK-DAG: afi [[REG]], 1342177280 71; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 72; CHECK: br %r14 73 %ptr = getelementptr i16, i16 *%src, i64 262143 74 %half = load i16, i16 *%ptr 75 %b = sext i16 %half to i32 76 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 77 %val = extractvalue {i32, i1} %t, 0 78 %obit = extractvalue {i32, i1} %t, 1 79 store i32 %val, i32 *%res 80 ret i1 %obit 81} 82 83; Check the next halfword up, which needs separate address logic. 84; Other sequences besides this one would be OK. 85define zeroext i1 @f5(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 86; CHECK-LABEL: f5: 87; CHECK: agfi %r4, 524288 88; CHECK: ah %r3, 0(%r4) 89; CHECK-DAG: st %r3, 0(%r5) 90; CHECK-DAG: ipm [[REG:%r[0-5]]] 91; CHECK-DAG: afi [[REG]], 1342177280 92; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 93; CHECK: br %r14 94 %ptr = getelementptr i16, i16 *%src, i64 262144 95 %half = load i16, i16 *%ptr 96 %b = sext i16 %half to i32 97 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 98 %val = extractvalue {i32, i1} %t, 0 99 %obit = extractvalue {i32, i1} %t, 1 100 store i32 %val, i32 *%res 101 ret i1 %obit 102} 103 104; Check the high end of the negative aligned AHY range. 105define zeroext i1 @f6(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 106; CHECK-LABEL: f6: 107; CHECK: ahy %r3, -2(%r4) 108; CHECK-DAG: st %r3, 0(%r5) 109; CHECK-DAG: ipm [[REG:%r[0-5]]] 110; CHECK-DAG: afi [[REG]], 1342177280 111; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 112; CHECK: br %r14 113 %ptr = getelementptr i16, i16 *%src, i64 -1 114 %half = load i16, i16 *%ptr 115 %b = sext i16 %half to i32 116 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 117 %val = extractvalue {i32, i1} %t, 0 118 %obit = extractvalue {i32, i1} %t, 1 119 store i32 %val, i32 *%res 120 ret i1 %obit 121} 122 123; Check the low end of the AHY range. 124define zeroext i1 @f7(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 125; CHECK-LABEL: f7: 126; CHECK: ahy %r3, -524288(%r4) 127; CHECK-DAG: st %r3, 0(%r5) 128; CHECK-DAG: ipm [[REG:%r[0-5]]] 129; CHECK-DAG: afi [[REG]], 1342177280 130; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 131; CHECK: br %r14 132 %ptr = getelementptr i16, i16 *%src, i64 -262144 133 %half = load i16, i16 *%ptr 134 %b = sext i16 %half to i32 135 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 136 %val = extractvalue {i32, i1} %t, 0 137 %obit = extractvalue {i32, i1} %t, 1 138 store i32 %val, i32 *%res 139 ret i1 %obit 140} 141 142; Check the next halfword down, which needs separate address logic. 143; Other sequences besides this one would be OK. 144define zeroext i1 @f8(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 145; CHECK-LABEL: f8: 146; CHECK: agfi %r4, -524290 147; CHECK: ah %r3, 0(%r4) 148; CHECK-DAG: st %r3, 0(%r5) 149; CHECK-DAG: ipm [[REG:%r[0-5]]] 150; CHECK-DAG: afi [[REG]], 1342177280 151; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 152; CHECK: br %r14 153 %ptr = getelementptr i16, i16 *%src, i64 -262145 154 %half = load i16, i16 *%ptr 155 %b = sext i16 %half to i32 156 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 157 %val = extractvalue {i32, i1} %t, 0 158 %obit = extractvalue {i32, i1} %t, 1 159 store i32 %val, i32 *%res 160 ret i1 %obit 161} 162 163; Check that AH allows an index. 164define zeroext i1 @f9(i64 %src, i64 %index, i32 %a, i32 *%res) { 165; CHECK-LABEL: f9: 166; CHECK: ah %r4, 4094({{%r3,%r2|%r2,%r3}}) 167; CHECK-DAG: st %r4, 0(%r5) 168; CHECK-DAG: ipm [[REG:%r[0-5]]] 169; CHECK-DAG: afi [[REG]], 1342177280 170; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 171; CHECK: br %r14 172 %add1 = add i64 %src, %index 173 %add2 = add i64 %add1, 4094 174 %ptr = inttoptr i64 %add2 to i16 * 175 %half = load i16, i16 *%ptr 176 %b = sext i16 %half to i32 177 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 178 %val = extractvalue {i32, i1} %t, 0 179 %obit = extractvalue {i32, i1} %t, 1 180 store i32 %val, i32 *%res 181 ret i1 %obit 182} 183 184; Check that AHY allows an index. 185define zeroext i1 @f10(i64 %src, i64 %index, i32 %a, i32 *%res) { 186; CHECK-LABEL: f10: 187; CHECK: ahy %r4, 4096({{%r3,%r2|%r2,%r3}}) 188; CHECK-DAG: st %r4, 0(%r5) 189; CHECK-DAG: ipm [[REG:%r[0-5]]] 190; CHECK-DAG: afi [[REG]], 1342177280 191; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 192; CHECK: br %r14 193 %add1 = add i64 %src, %index 194 %add2 = add i64 %add1, 4096 195 %ptr = inttoptr i64 %add2 to i16 * 196 %half = load i16, i16 *%ptr 197 %b = sext i16 %half to i32 198 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 199 %val = extractvalue {i32, i1} %t, 0 200 %obit = extractvalue {i32, i1} %t, 1 201 store i32 %val, i32 *%res 202 ret i1 %obit 203} 204 205; Check using the overflow result for a branch. 206define void @f11(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 207; CHECK-LABEL: f11: 208; CHECK: ah %r3, 0(%r4) 209; CHECK: st %r3, 0(%r5) 210; CHECK: jgo foo@PLT 211; CHECK: br %r14 212 %half = load i16, i16 *%src 213 %b = sext i16 %half to i32 214 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 215 %val = extractvalue {i32, i1} %t, 0 216 %obit = extractvalue {i32, i1} %t, 1 217 store i32 %val, i32 *%res 218 br i1 %obit, label %call, label %exit 219 220call: 221 tail call i32 @foo() 222 br label %exit 223 224exit: 225 ret void 226} 227 228; ... and the same with the inverted direction. 229define void @f12(i32 %dummy, i32 %a, i16 *%src, i32 *%res) { 230; CHECK-LABEL: f12: 231; CHECK: ah %r3, 0(%r4) 232; CHECK: st %r3, 0(%r5) 233; CHECK: jgno foo@PLT 234; CHECK: br %r14 235 %half = load i16, i16 *%src 236 %b = sext i16 %half to i32 237 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 238 %val = extractvalue {i32, i1} %t, 0 239 %obit = extractvalue {i32, i1} %t, 1 240 store i32 %val, i32 *%res 241 br i1 %obit, label %exit, label %call 242 243call: 244 tail call i32 @foo() 245 br label %exit 246 247exit: 248 ret void 249} 250 251 252declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 253 254