Ulrich Weigand | c3ec80f | 2018-04-30 17:54:28 +0000 | [diff] [blame] | 1 | ; Test 32-bit subtractions of constants to memory. |
| 2 | ; |
| 3 | ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s |
| 4 | |
| 5 | declare i32 @foo() |
| 6 | |
| 7 | ; Check subtraction of 1. |
| 8 | define zeroext i1 @f1(i32 *%ptr) { |
| 9 | ; CHECK-LABEL: f1: |
| 10 | ; CHECK: asi 0(%r2), -1 |
| 11 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 12 | ; CHECK: afi [[REG]], 1342177280 |
| 13 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 14 | ; CHECK: br %r14 |
| 15 | %a = load i32, i32 *%ptr |
| 16 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 17 | %val = extractvalue {i32, i1} %t, 0 |
| 18 | %obit = extractvalue {i32, i1} %t, 1 |
| 19 | store i32 %val, i32 *%ptr |
| 20 | ret i1 %obit |
| 21 | } |
| 22 | |
| 23 | ; Check the high end of the constant range. |
| 24 | define zeroext i1 @f2(i32 *%ptr) { |
| 25 | ; CHECK-LABEL: f2: |
| 26 | ; CHECK: asi 0(%r2), -128 |
| 27 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 28 | ; CHECK: afi [[REG]], 1342177280 |
| 29 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 30 | ; CHECK: br %r14 |
| 31 | %a = load i32, i32 *%ptr |
| 32 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 128) |
| 33 | %val = extractvalue {i32, i1} %t, 0 |
| 34 | %obit = extractvalue {i32, i1} %t, 1 |
| 35 | store i32 %val, i32 *%ptr |
| 36 | ret i1 %obit |
| 37 | } |
| 38 | |
| 39 | ; Check the next constant up, which must use an subtraction and a store. |
| 40 | define zeroext i1 @f3(i32 %dummy, i32 *%ptr) { |
| 41 | ; CHECK-LABEL: f3: |
| 42 | ; CHECK: l [[VAL:%r[0-5]]], 0(%r3) |
| 43 | ; CHECK: ahi [[VAL]], -129 |
| 44 | ; CHECK-DAG: st [[VAL]], 0(%r3) |
| 45 | ; CHECK-DAG: ipm [[REG:%r[0-5]]] |
| 46 | ; CHECK-DAG: afi [[REG]], 1342177280 |
| 47 | ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 |
| 48 | ; CHECK: br %r14 |
| 49 | %a = load i32, i32 *%ptr |
| 50 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 129) |
| 51 | %val = extractvalue {i32, i1} %t, 0 |
| 52 | %obit = extractvalue {i32, i1} %t, 1 |
| 53 | store i32 %val, i32 *%ptr |
| 54 | ret i1 %obit |
| 55 | } |
| 56 | |
| 57 | ; Check the low end of the constant range. |
| 58 | define zeroext i1 @f4(i32 *%ptr) { |
| 59 | ; CHECK-LABEL: f4: |
| 60 | ; CHECK: asi 0(%r2), 127 |
| 61 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 62 | ; CHECK: afi [[REG]], 1342177280 |
| 63 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 64 | ; CHECK: br %r14 |
| 65 | %a = load i32, i32 *%ptr |
| 66 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 -127) |
| 67 | %val = extractvalue {i32, i1} %t, 0 |
| 68 | %obit = extractvalue {i32, i1} %t, 1 |
| 69 | store i32 %val, i32 *%ptr |
| 70 | ret i1 %obit |
| 71 | } |
| 72 | |
| 73 | ; Check the next value down, with the same comment as f3. |
| 74 | define zeroext i1 @f5(i32 %dummy, i32 *%ptr) { |
| 75 | ; CHECK-LABEL: f5: |
| 76 | ; CHECK: l [[VAL:%r[0-5]]], 0(%r3) |
| 77 | ; CHECK: ahi [[VAL]], 128 |
| 78 | ; CHECK-DAG: st [[VAL]], 0(%r3) |
| 79 | ; CHECK-DAG: ipm [[REG:%r[0-5]]] |
| 80 | ; CHECK-DAG: afi [[REG]], 1342177280 |
| 81 | ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 |
| 82 | ; CHECK: br %r14 |
| 83 | %a = load i32, i32 *%ptr |
| 84 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 -128) |
| 85 | %val = extractvalue {i32, i1} %t, 0 |
| 86 | %obit = extractvalue {i32, i1} %t, 1 |
| 87 | store i32 %val, i32 *%ptr |
| 88 | ret i1 %obit |
| 89 | } |
| 90 | |
| 91 | ; Check the high end of the aligned ASI range. |
| 92 | define zeroext i1 @f6(i32 *%base) { |
| 93 | ; CHECK-LABEL: f6: |
| 94 | ; CHECK: asi 524284(%r2), -1 |
| 95 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 96 | ; CHECK: afi [[REG]], 1342177280 |
| 97 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 98 | ; CHECK: br %r14 |
| 99 | %ptr = getelementptr i32, i32 *%base, i64 131071 |
| 100 | %a = load i32, i32 *%ptr |
| 101 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 102 | %val = extractvalue {i32, i1} %t, 0 |
| 103 | %obit = extractvalue {i32, i1} %t, 1 |
| 104 | store i32 %val, i32 *%ptr |
| 105 | ret i1 %obit |
| 106 | } |
| 107 | |
| 108 | ; Check the next word up, which must use separate address logic. |
| 109 | ; Other sequences besides this one would be OK. |
| 110 | define zeroext i1 @f7(i32 *%base) { |
| 111 | ; CHECK-LABEL: f7: |
| 112 | ; CHECK: agfi %r2, 524288 |
| 113 | ; CHECK: asi 0(%r2), -1 |
| 114 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 115 | ; CHECK: afi [[REG]], 1342177280 |
| 116 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 117 | ; CHECK: br %r14 |
| 118 | %ptr = getelementptr i32, i32 *%base, i64 131072 |
| 119 | %a = load i32, i32 *%ptr |
| 120 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 121 | %val = extractvalue {i32, i1} %t, 0 |
| 122 | %obit = extractvalue {i32, i1} %t, 1 |
| 123 | store i32 %val, i32 *%ptr |
| 124 | ret i1 %obit |
| 125 | } |
| 126 | |
| 127 | ; Check the low end of the ASI range. |
| 128 | define zeroext i1 @f8(i32 *%base) { |
| 129 | ; CHECK-LABEL: f8: |
| 130 | ; CHECK: asi -524288(%r2), -1 |
| 131 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 132 | ; CHECK: afi [[REG]], 1342177280 |
| 133 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 134 | ; CHECK: br %r14 |
| 135 | %ptr = getelementptr i32, i32 *%base, i64 -131072 |
| 136 | %a = load i32, i32 *%ptr |
| 137 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 138 | %val = extractvalue {i32, i1} %t, 0 |
| 139 | %obit = extractvalue {i32, i1} %t, 1 |
| 140 | store i32 %val, i32 *%ptr |
| 141 | ret i1 %obit |
| 142 | } |
| 143 | |
| 144 | ; Check the next word down, which must use separate address logic. |
| 145 | ; Other sequences besides this one would be OK. |
| 146 | define zeroext i1 @f9(i32 *%base) { |
| 147 | ; CHECK-LABEL: f9: |
| 148 | ; CHECK: agfi %r2, -524292 |
| 149 | ; CHECK: asi 0(%r2), -1 |
| 150 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 151 | ; CHECK: afi [[REG]], 1342177280 |
| 152 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 153 | ; CHECK: br %r14 |
| 154 | %ptr = getelementptr i32, i32 *%base, i64 -131073 |
| 155 | %a = load i32, i32 *%ptr |
| 156 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 157 | %val = extractvalue {i32, i1} %t, 0 |
| 158 | %obit = extractvalue {i32, i1} %t, 1 |
| 159 | store i32 %val, i32 *%ptr |
| 160 | ret i1 %obit |
| 161 | } |
| 162 | |
| 163 | ; Check that ASI does not allow indices. |
| 164 | define zeroext i1 @f10(i64 %base, i64 %index) { |
| 165 | ; CHECK-LABEL: f10: |
| 166 | ; CHECK: agr %r2, %r3 |
| 167 | ; CHECK: asi 4(%r2), -1 |
| 168 | ; CHECK: ipm [[REG:%r[0-5]]] |
| 169 | ; CHECK: afi [[REG]], 1342177280 |
| 170 | ; CHECK: risbg %r2, [[REG]], 63, 191, 33 |
| 171 | ; CHECK: br %r14 |
| 172 | %add1 = add i64 %base, %index |
| 173 | %add2 = add i64 %add1, 4 |
| 174 | %ptr = inttoptr i64 %add2 to i32 * |
| 175 | %a = load i32, i32 *%ptr |
| 176 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 177 | %val = extractvalue {i32, i1} %t, 0 |
| 178 | %obit = extractvalue {i32, i1} %t, 1 |
| 179 | store i32 %val, i32 *%ptr |
| 180 | ret i1 %obit |
| 181 | } |
| 182 | |
| 183 | ; Check that subtracting 128 from a spilled value can use ASI. |
| 184 | define zeroext i1 @f11(i32 *%ptr, i32 %sel) { |
| 185 | ; CHECK-LABEL: f11: |
| 186 | ; CHECK: asi {{[0-9]+}}(%r15), -128 |
| 187 | ; CHECK: br %r14 |
| 188 | entry: |
| 189 | %val0 = load volatile i32, i32 *%ptr |
| 190 | %val1 = load volatile i32, i32 *%ptr |
| 191 | %val2 = load volatile i32, i32 *%ptr |
| 192 | %val3 = load volatile i32, i32 *%ptr |
| 193 | %val4 = load volatile i32, i32 *%ptr |
| 194 | %val5 = load volatile i32, i32 *%ptr |
| 195 | %val6 = load volatile i32, i32 *%ptr |
| 196 | %val7 = load volatile i32, i32 *%ptr |
| 197 | %val8 = load volatile i32, i32 *%ptr |
| 198 | %val9 = load volatile i32, i32 *%ptr |
| 199 | %val10 = load volatile i32, i32 *%ptr |
| 200 | %val11 = load volatile i32, i32 *%ptr |
| 201 | %val12 = load volatile i32, i32 *%ptr |
| 202 | %val13 = load volatile i32, i32 *%ptr |
| 203 | %val14 = load volatile i32, i32 *%ptr |
| 204 | %val15 = load volatile i32, i32 *%ptr |
| 205 | |
| 206 | %test = icmp ne i32 %sel, 0 |
| 207 | br i1 %test, label %add, label %store |
| 208 | |
| 209 | add: |
| 210 | %t0 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val0, i32 128) |
| 211 | %add0 = extractvalue {i32, i1} %t0, 0 |
| 212 | %obit0 = extractvalue {i32, i1} %t0, 1 |
| 213 | %t1 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val1, i32 128) |
| 214 | %add1 = extractvalue {i32, i1} %t1, 0 |
| 215 | %obit1 = extractvalue {i32, i1} %t1, 1 |
| 216 | %res1 = or i1 %obit0, %obit1 |
| 217 | %t2 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val2, i32 128) |
| 218 | %add2 = extractvalue {i32, i1} %t2, 0 |
| 219 | %obit2 = extractvalue {i32, i1} %t2, 1 |
| 220 | %res2 = or i1 %res1, %obit2 |
| 221 | %t3 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val3, i32 128) |
| 222 | %add3 = extractvalue {i32, i1} %t3, 0 |
| 223 | %obit3 = extractvalue {i32, i1} %t3, 1 |
| 224 | %res3 = or i1 %res2, %obit3 |
| 225 | %t4 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val4, i32 128) |
| 226 | %add4 = extractvalue {i32, i1} %t4, 0 |
| 227 | %obit4 = extractvalue {i32, i1} %t4, 1 |
| 228 | %res4 = or i1 %res3, %obit4 |
| 229 | %t5 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val5, i32 128) |
| 230 | %add5 = extractvalue {i32, i1} %t5, 0 |
| 231 | %obit5 = extractvalue {i32, i1} %t5, 1 |
| 232 | %res5 = or i1 %res4, %obit5 |
| 233 | %t6 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val6, i32 128) |
| 234 | %add6 = extractvalue {i32, i1} %t6, 0 |
| 235 | %obit6 = extractvalue {i32, i1} %t6, 1 |
| 236 | %res6 = or i1 %res5, %obit6 |
| 237 | %t7 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val7, i32 128) |
| 238 | %add7 = extractvalue {i32, i1} %t7, 0 |
| 239 | %obit7 = extractvalue {i32, i1} %t7, 1 |
| 240 | %res7 = or i1 %res6, %obit7 |
| 241 | %t8 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val8, i32 128) |
| 242 | %add8 = extractvalue {i32, i1} %t8, 0 |
| 243 | %obit8 = extractvalue {i32, i1} %t8, 1 |
| 244 | %res8 = or i1 %res7, %obit8 |
| 245 | %t9 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val9, i32 128) |
| 246 | %add9 = extractvalue {i32, i1} %t9, 0 |
| 247 | %obit9 = extractvalue {i32, i1} %t9, 1 |
| 248 | %res9 = or i1 %res8, %obit9 |
| 249 | %t10 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val10, i32 128) |
| 250 | %add10 = extractvalue {i32, i1} %t10, 0 |
| 251 | %obit10 = extractvalue {i32, i1} %t10, 1 |
| 252 | %res10 = or i1 %res9, %obit10 |
| 253 | %t11 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val11, i32 128) |
| 254 | %add11 = extractvalue {i32, i1} %t11, 0 |
| 255 | %obit11 = extractvalue {i32, i1} %t11, 1 |
| 256 | %res11 = or i1 %res10, %obit11 |
| 257 | %t12 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val12, i32 128) |
| 258 | %add12 = extractvalue {i32, i1} %t12, 0 |
| 259 | %obit12 = extractvalue {i32, i1} %t12, 1 |
| 260 | %res12 = or i1 %res11, %obit12 |
| 261 | %t13 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val13, i32 128) |
| 262 | %add13 = extractvalue {i32, i1} %t13, 0 |
| 263 | %obit13 = extractvalue {i32, i1} %t13, 1 |
| 264 | %res13 = or i1 %res12, %obit13 |
| 265 | %t14 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val14, i32 128) |
| 266 | %add14 = extractvalue {i32, i1} %t14, 0 |
| 267 | %obit14 = extractvalue {i32, i1} %t14, 1 |
| 268 | %res14 = or i1 %res13, %obit14 |
| 269 | %t15 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val15, i32 128) |
| 270 | %add15 = extractvalue {i32, i1} %t15, 0 |
| 271 | %obit15 = extractvalue {i32, i1} %t15, 1 |
| 272 | %res15 = or i1 %res14, %obit15 |
| 273 | |
| 274 | br label %store |
| 275 | |
| 276 | store: |
| 277 | %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ] |
| 278 | %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ] |
| 279 | %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ] |
| 280 | %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ] |
| 281 | %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ] |
| 282 | %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ] |
| 283 | %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ] |
| 284 | %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ] |
| 285 | %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ] |
| 286 | %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ] |
| 287 | %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ] |
| 288 | %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ] |
| 289 | %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ] |
| 290 | %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ] |
| 291 | %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ] |
| 292 | %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ] |
| 293 | %res = phi i1 [ 0, %entry ], [ %res15, %add ] |
| 294 | |
| 295 | store volatile i32 %new0, i32 *%ptr |
| 296 | store volatile i32 %new1, i32 *%ptr |
| 297 | store volatile i32 %new2, i32 *%ptr |
| 298 | store volatile i32 %new3, i32 *%ptr |
| 299 | store volatile i32 %new4, i32 *%ptr |
| 300 | store volatile i32 %new5, i32 *%ptr |
| 301 | store volatile i32 %new6, i32 *%ptr |
| 302 | store volatile i32 %new7, i32 *%ptr |
| 303 | store volatile i32 %new8, i32 *%ptr |
| 304 | store volatile i32 %new9, i32 *%ptr |
| 305 | store volatile i32 %new10, i32 *%ptr |
| 306 | store volatile i32 %new11, i32 *%ptr |
| 307 | store volatile i32 %new12, i32 *%ptr |
| 308 | store volatile i32 %new13, i32 *%ptr |
| 309 | store volatile i32 %new14, i32 *%ptr |
| 310 | store volatile i32 %new15, i32 *%ptr |
| 311 | |
| 312 | ret i1 %res |
| 313 | } |
| 314 | |
| 315 | ; Check that subtracting -127 from a spilled value can use ASI. |
| 316 | define zeroext i1 @f12(i32 *%ptr, i32 %sel) { |
| 317 | ; CHECK-LABEL: f12: |
| 318 | ; CHECK: asi {{[0-9]+}}(%r15), 127 |
| 319 | ; CHECK: br %r14 |
| 320 | entry: |
| 321 | %val0 = load volatile i32, i32 *%ptr |
| 322 | %val1 = load volatile i32, i32 *%ptr |
| 323 | %val2 = load volatile i32, i32 *%ptr |
| 324 | %val3 = load volatile i32, i32 *%ptr |
| 325 | %val4 = load volatile i32, i32 *%ptr |
| 326 | %val5 = load volatile i32, i32 *%ptr |
| 327 | %val6 = load volatile i32, i32 *%ptr |
| 328 | %val7 = load volatile i32, i32 *%ptr |
| 329 | %val8 = load volatile i32, i32 *%ptr |
| 330 | %val9 = load volatile i32, i32 *%ptr |
| 331 | %val10 = load volatile i32, i32 *%ptr |
| 332 | %val11 = load volatile i32, i32 *%ptr |
| 333 | %val12 = load volatile i32, i32 *%ptr |
| 334 | %val13 = load volatile i32, i32 *%ptr |
| 335 | %val14 = load volatile i32, i32 *%ptr |
| 336 | %val15 = load volatile i32, i32 *%ptr |
| 337 | |
| 338 | %test = icmp ne i32 %sel, 0 |
| 339 | br i1 %test, label %add, label %store |
| 340 | |
| 341 | add: |
| 342 | %t0 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val0, i32 -127) |
| 343 | %add0 = extractvalue {i32, i1} %t0, 0 |
| 344 | %obit0 = extractvalue {i32, i1} %t0, 1 |
| 345 | %t1 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val1, i32 -127) |
| 346 | %add1 = extractvalue {i32, i1} %t1, 0 |
| 347 | %obit1 = extractvalue {i32, i1} %t1, 1 |
| 348 | %res1 = or i1 %obit0, %obit1 |
| 349 | %t2 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val2, i32 -127) |
| 350 | %add2 = extractvalue {i32, i1} %t2, 0 |
| 351 | %obit2 = extractvalue {i32, i1} %t2, 1 |
| 352 | %res2 = or i1 %res1, %obit2 |
| 353 | %t3 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val3, i32 -127) |
| 354 | %add3 = extractvalue {i32, i1} %t3, 0 |
| 355 | %obit3 = extractvalue {i32, i1} %t3, 1 |
| 356 | %res3 = or i1 %res2, %obit3 |
| 357 | %t4 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val4, i32 -127) |
| 358 | %add4 = extractvalue {i32, i1} %t4, 0 |
| 359 | %obit4 = extractvalue {i32, i1} %t4, 1 |
| 360 | %res4 = or i1 %res3, %obit4 |
| 361 | %t5 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val5, i32 -127) |
| 362 | %add5 = extractvalue {i32, i1} %t5, 0 |
| 363 | %obit5 = extractvalue {i32, i1} %t5, 1 |
| 364 | %res5 = or i1 %res4, %obit5 |
| 365 | %t6 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val6, i32 -127) |
| 366 | %add6 = extractvalue {i32, i1} %t6, 0 |
| 367 | %obit6 = extractvalue {i32, i1} %t6, 1 |
| 368 | %res6 = or i1 %res5, %obit6 |
| 369 | %t7 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val7, i32 -127) |
| 370 | %add7 = extractvalue {i32, i1} %t7, 0 |
| 371 | %obit7 = extractvalue {i32, i1} %t7, 1 |
| 372 | %res7 = or i1 %res6, %obit7 |
| 373 | %t8 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val8, i32 -127) |
| 374 | %add8 = extractvalue {i32, i1} %t8, 0 |
| 375 | %obit8 = extractvalue {i32, i1} %t8, 1 |
| 376 | %res8 = or i1 %res7, %obit8 |
| 377 | %t9 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val9, i32 -127) |
| 378 | %add9 = extractvalue {i32, i1} %t9, 0 |
| 379 | %obit9 = extractvalue {i32, i1} %t9, 1 |
| 380 | %res9 = or i1 %res8, %obit9 |
| 381 | %t10 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val10, i32 -127) |
| 382 | %add10 = extractvalue {i32, i1} %t10, 0 |
| 383 | %obit10 = extractvalue {i32, i1} %t10, 1 |
| 384 | %res10 = or i1 %res9, %obit10 |
| 385 | %t11 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val11, i32 -127) |
| 386 | %add11 = extractvalue {i32, i1} %t11, 0 |
| 387 | %obit11 = extractvalue {i32, i1} %t11, 1 |
| 388 | %res11 = or i1 %res10, %obit11 |
| 389 | %t12 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val12, i32 -127) |
| 390 | %add12 = extractvalue {i32, i1} %t12, 0 |
| 391 | %obit12 = extractvalue {i32, i1} %t12, 1 |
| 392 | %res12 = or i1 %res11, %obit12 |
| 393 | %t13 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val13, i32 -127) |
| 394 | %add13 = extractvalue {i32, i1} %t13, 0 |
| 395 | %obit13 = extractvalue {i32, i1} %t13, 1 |
| 396 | %res13 = or i1 %res12, %obit13 |
| 397 | %t14 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val14, i32 -127) |
| 398 | %add14 = extractvalue {i32, i1} %t14, 0 |
| 399 | %obit14 = extractvalue {i32, i1} %t14, 1 |
| 400 | %res14 = or i1 %res13, %obit14 |
| 401 | %t15 = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %val15, i32 -127) |
| 402 | %add15 = extractvalue {i32, i1} %t15, 0 |
| 403 | %obit15 = extractvalue {i32, i1} %t15, 1 |
| 404 | %res15 = or i1 %res14, %obit15 |
| 405 | |
| 406 | br label %store |
| 407 | |
| 408 | store: |
| 409 | %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ] |
| 410 | %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ] |
| 411 | %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ] |
| 412 | %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ] |
| 413 | %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ] |
| 414 | %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ] |
| 415 | %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ] |
| 416 | %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ] |
| 417 | %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ] |
| 418 | %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ] |
| 419 | %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ] |
| 420 | %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ] |
| 421 | %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ] |
| 422 | %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ] |
| 423 | %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ] |
| 424 | %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ] |
| 425 | %res = phi i1 [ 0, %entry ], [ %res15, %add ] |
| 426 | |
| 427 | store volatile i32 %new0, i32 *%ptr |
| 428 | store volatile i32 %new1, i32 *%ptr |
| 429 | store volatile i32 %new2, i32 *%ptr |
| 430 | store volatile i32 %new3, i32 *%ptr |
| 431 | store volatile i32 %new4, i32 *%ptr |
| 432 | store volatile i32 %new5, i32 *%ptr |
| 433 | store volatile i32 %new6, i32 *%ptr |
| 434 | store volatile i32 %new7, i32 *%ptr |
| 435 | store volatile i32 %new8, i32 *%ptr |
| 436 | store volatile i32 %new9, i32 *%ptr |
| 437 | store volatile i32 %new10, i32 *%ptr |
| 438 | store volatile i32 %new11, i32 *%ptr |
| 439 | store volatile i32 %new12, i32 *%ptr |
| 440 | store volatile i32 %new13, i32 *%ptr |
| 441 | store volatile i32 %new14, i32 *%ptr |
| 442 | store volatile i32 %new15, i32 *%ptr |
| 443 | |
| 444 | ret i1 %res |
| 445 | } |
| 446 | |
| 447 | ; Check using the overflow result for a branch. |
| 448 | define void @f13(i32 *%ptr) { |
| 449 | ; CHECK-LABEL: f13: |
| 450 | ; CHECK: asi 0(%r2), -1 |
| 451 | ; CHECK: jgo foo@PLT |
| 452 | ; CHECK: br %r14 |
| 453 | %a = load i32, i32 *%ptr |
| 454 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 455 | %val = extractvalue {i32, i1} %t, 0 |
| 456 | %obit = extractvalue {i32, i1} %t, 1 |
| 457 | store i32 %val, i32 *%ptr |
| 458 | br i1 %obit, label %call, label %exit |
| 459 | |
| 460 | call: |
| 461 | tail call i32 @foo() |
| 462 | br label %exit |
| 463 | |
| 464 | exit: |
| 465 | ret void |
| 466 | } |
| 467 | |
| 468 | ; ... and the same with the inverted direction. |
| 469 | define void @f14(i32 *%ptr) { |
| 470 | ; CHECK-LABEL: f14: |
| 471 | ; CHECK: asi 0(%r2), -1 |
| 472 | ; CHECK: jgno foo@PLT |
| 473 | ; CHECK: br %r14 |
| 474 | %a = load i32, i32 *%ptr |
| 475 | %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 1) |
| 476 | %val = extractvalue {i32, i1} %t, 0 |
| 477 | %obit = extractvalue {i32, i1} %t, 1 |
| 478 | store i32 %val, i32 *%ptr |
| 479 | br i1 %obit, label %exit, label %call |
| 480 | |
| 481 | call: |
| 482 | tail call i32 @foo() |
| 483 | br label %exit |
| 484 | |
| 485 | exit: |
| 486 | ret void |
| 487 | } |
| 488 | |
| 489 | declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone |
| 490 | |