481 lines · plain
1; Test 32-bit additions of constants to memory.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare i32 @foo()6 7; Check addition of 1.8define zeroext i1 @f1(ptr %ptr) {9; CHECK-LABEL: f1:10; CHECK: alsi 0(%r2), 111; CHECK: ipm [[REG:%r[0-5]]]12; CHECK: risbg %r2, [[REG]], 63, 191, 3513; CHECK: br %r1414 %a = load i32, ptr %ptr15 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)16 %val = extractvalue {i32, i1} %t, 017 %obit = extractvalue {i32, i1} %t, 118 store i32 %val, ptr %ptr19 ret i1 %obit20}21 22; Check the high end of the constant range.23define zeroext i1 @f2(ptr %ptr) {24; CHECK-LABEL: f2:25; CHECK: alsi 0(%r2), 12726; CHECK: ipm [[REG:%r[0-5]]]27; CHECK: risbg %r2, [[REG]], 63, 191, 3528; CHECK: br %r1429 %a = load i32, ptr %ptr30 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 127)31 %val = extractvalue {i32, i1} %t, 032 %obit = extractvalue {i32, i1} %t, 133 store i32 %val, ptr %ptr34 ret i1 %obit35}36 37; Check the next constant up, which must use an addition and a store.38define zeroext i1 @f3(i32 %dummy, ptr %ptr) {39; CHECK-LABEL: f3:40; CHECK: l [[VAL:%r[0-5]]], 0(%r3)41; CHECK: alfi [[VAL]], 12842; CHECK-DAG: st [[VAL]], 0(%r3)43; CHECK-DAG: ipm [[REG:%r[0-5]]]44; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3545; CHECK: br %r1446 %a = load i32, ptr %ptr47 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 128)48 %val = extractvalue {i32, i1} %t, 049 %obit = extractvalue {i32, i1} %t, 150 store i32 %val, ptr %ptr51 ret i1 %obit52}53 54; Check the low end of the constant range.55define zeroext i1 @f4(ptr %ptr) {56; CHECK-LABEL: f4:57; CHECK: alsi 0(%r2), -12858; CHECK: ipm [[REG:%r[0-5]]]59; CHECK: risbg %r2, [[REG]], 63, 191, 3560; CHECK: br %r1461 %a = load i32, ptr %ptr62 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -128)63 %val = extractvalue {i32, i1} %t, 064 %obit = extractvalue {i32, i1} %t, 165 store i32 %val, ptr %ptr66 ret i1 %obit67}68 69; Check the next value down, with the same comment as f3.70define zeroext i1 @f5(i32 %dummy, ptr %ptr) {71; CHECK-LABEL: f5:72; CHECK: l [[VAL:%r[0-5]]], 0(%r3)73; CHECK: alfi [[VAL]], 429496716774; CHECK-DAG: st [[VAL]], 0(%r3)75; CHECK-DAG: ipm [[REG:%r[0-5]]]76; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 3577; CHECK: br %r1478 %a = load i32, ptr %ptr79 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -129)80 %val = extractvalue {i32, i1} %t, 081 %obit = extractvalue {i32, i1} %t, 182 store i32 %val, ptr %ptr83 ret i1 %obit84}85 86; Check the high end of the aligned ALSI range.87define zeroext i1 @f6(ptr %base) {88; CHECK-LABEL: f6:89; CHECK: alsi 524284(%r2), 190; CHECK: ipm [[REG:%r[0-5]]]91; CHECK: risbg %r2, [[REG]], 63, 191, 3592; CHECK: br %r1493 %ptr = getelementptr i32, ptr %base, i64 13107194 %a = load i32, ptr %ptr95 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)96 %val = extractvalue {i32, i1} %t, 097 %obit = extractvalue {i32, i1} %t, 198 store i32 %val, ptr %ptr99 ret i1 %obit100}101 102; Check the next word up, which must use separate address logic.103; Other sequences besides this one would be OK.104define zeroext i1 @f7(ptr %base) {105; CHECK-LABEL: f7:106; CHECK: agfi %r2, 524288107; CHECK: alsi 0(%r2), 1108; CHECK: ipm [[REG:%r[0-5]]]109; CHECK: risbg %r2, [[REG]], 63, 191, 35110; CHECK: br %r14111 %ptr = getelementptr i32, ptr %base, i64 131072112 %a = load i32, ptr %ptr113 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)114 %val = extractvalue {i32, i1} %t, 0115 %obit = extractvalue {i32, i1} %t, 1116 store i32 %val, ptr %ptr117 ret i1 %obit118}119 120; Check the low end of the ALSI range.121define zeroext i1 @f8(ptr %base) {122; CHECK-LABEL: f8:123; CHECK: alsi -524288(%r2), 1124; CHECK: ipm [[REG:%r[0-5]]]125; CHECK: risbg %r2, [[REG]], 63, 191, 35126; CHECK: br %r14127 %ptr = getelementptr i32, ptr %base, i64 -131072128 %a = load i32, ptr %ptr129 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)130 %val = extractvalue {i32, i1} %t, 0131 %obit = extractvalue {i32, i1} %t, 1132 store i32 %val, ptr %ptr133 ret i1 %obit134}135 136; Check the next word down, which must use separate address logic.137; Other sequences besides this one would be OK.138define zeroext i1 @f9(ptr %base) {139; CHECK-LABEL: f9:140; CHECK: agfi %r2, -524292141; CHECK: alsi 0(%r2), 1142; CHECK: ipm [[REG:%r[0-5]]]143; CHECK: risbg %r2, [[REG]], 63, 191, 35144; CHECK: br %r14145 %ptr = getelementptr i32, ptr %base, i64 -131073146 %a = load i32, ptr %ptr147 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)148 %val = extractvalue {i32, i1} %t, 0149 %obit = extractvalue {i32, i1} %t, 1150 store i32 %val, ptr %ptr151 ret i1 %obit152}153 154; Check that ALSI does not allow indices.155define zeroext i1 @f10(i64 %base, i64 %index) {156; CHECK-LABEL: f10:157; CHECK: agr %r2, %r3158; CHECK: alsi 4(%r2), 1159; CHECK: ipm [[REG:%r[0-5]]]160; CHECK: risbg %r2, [[REG]], 63, 191, 35161; CHECK: br %r14162 %add1 = add i64 %base, %index163 %add2 = add i64 %add1, 4164 %ptr = inttoptr i64 %add2 to ptr165 %a = load i32, ptr %ptr166 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)167 %val = extractvalue {i32, i1} %t, 0168 %obit = extractvalue {i32, i1} %t, 1169 store i32 %val, ptr %ptr170 ret i1 %obit171}172 173; Check that adding 127 to a spilled value can use ALSI.174define zeroext i1 @f11(ptr %ptr, i32 %sel) {175; CHECK-LABEL: f11:176; CHECK: alsi {{[0-9]+}}(%r15), 127177; CHECK: br %r14178entry:179 %val0 = load volatile i32, ptr %ptr180 %val1 = load volatile i32, ptr %ptr181 %val2 = load volatile i32, ptr %ptr182 %val3 = load volatile i32, ptr %ptr183 %val4 = load volatile i32, ptr %ptr184 %val5 = load volatile i32, ptr %ptr185 %val6 = load volatile i32, ptr %ptr186 %val7 = load volatile i32, ptr %ptr187 %val8 = load volatile i32, ptr %ptr188 %val9 = load volatile i32, ptr %ptr189 %val10 = load volatile i32, ptr %ptr190 %val11 = load volatile i32, ptr %ptr191 %val12 = load volatile i32, ptr %ptr192 %val13 = load volatile i32, ptr %ptr193 %val14 = load volatile i32, ptr %ptr194 %val15 = load volatile i32, ptr %ptr195 196 %test = icmp ne i32 %sel, 0197 br i1 %test, label %add, label %store198 199add:200 %t0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val0, i32 127)201 %add0 = extractvalue {i32, i1} %t0, 0202 %obit0 = extractvalue {i32, i1} %t0, 1203 %t1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val1, i32 127)204 %add1 = extractvalue {i32, i1} %t1, 0205 %obit1 = extractvalue {i32, i1} %t1, 1206 %res1 = or i1 %obit0, %obit1207 %t2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val2, i32 127)208 %add2 = extractvalue {i32, i1} %t2, 0209 %obit2 = extractvalue {i32, i1} %t2, 1210 %res2 = or i1 %res1, %obit2211 %t3 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val3, i32 127)212 %add3 = extractvalue {i32, i1} %t3, 0213 %obit3 = extractvalue {i32, i1} %t3, 1214 %res3 = or i1 %res2, %obit3215 %t4 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val4, i32 127)216 %add4 = extractvalue {i32, i1} %t4, 0217 %obit4 = extractvalue {i32, i1} %t4, 1218 %res4 = or i1 %res3, %obit4219 %t5 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val5, i32 127)220 %add5 = extractvalue {i32, i1} %t5, 0221 %obit5 = extractvalue {i32, i1} %t5, 1222 %res5 = or i1 %res4, %obit5223 %t6 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val6, i32 127)224 %add6 = extractvalue {i32, i1} %t6, 0225 %obit6 = extractvalue {i32, i1} %t6, 1226 %res6 = or i1 %res5, %obit6227 %t7 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val7, i32 127)228 %add7 = extractvalue {i32, i1} %t7, 0229 %obit7 = extractvalue {i32, i1} %t7, 1230 %res7 = or i1 %res6, %obit7231 %t8 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val8, i32 127)232 %add8 = extractvalue {i32, i1} %t8, 0233 %obit8 = extractvalue {i32, i1} %t8, 1234 %res8 = or i1 %res7, %obit8235 %t9 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val9, i32 127)236 %add9 = extractvalue {i32, i1} %t9, 0237 %obit9 = extractvalue {i32, i1} %t9, 1238 %res9 = or i1 %res8, %obit9239 %t10 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val10, i32 127)240 %add10 = extractvalue {i32, i1} %t10, 0241 %obit10 = extractvalue {i32, i1} %t10, 1242 %res10 = or i1 %res9, %obit10243 %t11 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val11, i32 127)244 %add11 = extractvalue {i32, i1} %t11, 0245 %obit11 = extractvalue {i32, i1} %t11, 1246 %res11 = or i1 %res10, %obit11247 %t12 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val12, i32 127)248 %add12 = extractvalue {i32, i1} %t12, 0249 %obit12 = extractvalue {i32, i1} %t12, 1250 %res12 = or i1 %res11, %obit12251 %t13 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val13, i32 127)252 %add13 = extractvalue {i32, i1} %t13, 0253 %obit13 = extractvalue {i32, i1} %t13, 1254 %res13 = or i1 %res12, %obit13255 %t14 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val14, i32 127)256 %add14 = extractvalue {i32, i1} %t14, 0257 %obit14 = extractvalue {i32, i1} %t14, 1258 %res14 = or i1 %res13, %obit14259 %t15 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val15, i32 127)260 %add15 = extractvalue {i32, i1} %t15, 0261 %obit15 = extractvalue {i32, i1} %t15, 1262 %res15 = or i1 %res14, %obit15263 264 br label %store265 266store:267 %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]268 %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]269 %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]270 %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]271 %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]272 %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]273 %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]274 %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]275 %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]276 %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]277 %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]278 %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]279 %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]280 %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]281 %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]282 %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]283 %res = phi i1 [ 0, %entry ], [ %res15, %add ]284 285 store volatile i32 %new0, ptr %ptr286 store volatile i32 %new1, ptr %ptr287 store volatile i32 %new2, ptr %ptr288 store volatile i32 %new3, ptr %ptr289 store volatile i32 %new4, ptr %ptr290 store volatile i32 %new5, ptr %ptr291 store volatile i32 %new6, ptr %ptr292 store volatile i32 %new7, ptr %ptr293 store volatile i32 %new8, ptr %ptr294 store volatile i32 %new9, ptr %ptr295 store volatile i32 %new10, ptr %ptr296 store volatile i32 %new11, ptr %ptr297 store volatile i32 %new12, ptr %ptr298 store volatile i32 %new13, ptr %ptr299 store volatile i32 %new14, ptr %ptr300 store volatile i32 %new15, ptr %ptr301 302 ret i1 %res303}304 305; Check that adding -128 to a spilled value can use ALSI.306define zeroext i1 @f12(ptr %ptr, i32 %sel) {307; CHECK-LABEL: f12:308; CHECK: alsi {{[0-9]+}}(%r15), -128309; CHECK: br %r14310entry:311 %val0 = load volatile i32, ptr %ptr312 %val1 = load volatile i32, ptr %ptr313 %val2 = load volatile i32, ptr %ptr314 %val3 = load volatile i32, ptr %ptr315 %val4 = load volatile i32, ptr %ptr316 %val5 = load volatile i32, ptr %ptr317 %val6 = load volatile i32, ptr %ptr318 %val7 = load volatile i32, ptr %ptr319 %val8 = load volatile i32, ptr %ptr320 %val9 = load volatile i32, ptr %ptr321 %val10 = load volatile i32, ptr %ptr322 %val11 = load volatile i32, ptr %ptr323 %val12 = load volatile i32, ptr %ptr324 %val13 = load volatile i32, ptr %ptr325 %val14 = load volatile i32, ptr %ptr326 %val15 = load volatile i32, ptr %ptr327 328 %test = icmp ne i32 %sel, 0329 br i1 %test, label %add, label %store330 331add:332 %t0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val0, i32 -128)333 %add0 = extractvalue {i32, i1} %t0, 0334 %obit0 = extractvalue {i32, i1} %t0, 1335 %t1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val1, i32 -128)336 %add1 = extractvalue {i32, i1} %t1, 0337 %obit1 = extractvalue {i32, i1} %t1, 1338 %res1 = or i1 %obit0, %obit1339 %t2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val2, i32 -128)340 %add2 = extractvalue {i32, i1} %t2, 0341 %obit2 = extractvalue {i32, i1} %t2, 1342 %res2 = or i1 %res1, %obit2343 %t3 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val3, i32 -128)344 %add3 = extractvalue {i32, i1} %t3, 0345 %obit3 = extractvalue {i32, i1} %t3, 1346 %res3 = or i1 %res2, %obit3347 %t4 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val4, i32 -128)348 %add4 = extractvalue {i32, i1} %t4, 0349 %obit4 = extractvalue {i32, i1} %t4, 1350 %res4 = or i1 %res3, %obit4351 %t5 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val5, i32 -128)352 %add5 = extractvalue {i32, i1} %t5, 0353 %obit5 = extractvalue {i32, i1} %t5, 1354 %res5 = or i1 %res4, %obit5355 %t6 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val6, i32 -128)356 %add6 = extractvalue {i32, i1} %t6, 0357 %obit6 = extractvalue {i32, i1} %t6, 1358 %res6 = or i1 %res5, %obit6359 %t7 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val7, i32 -128)360 %add7 = extractvalue {i32, i1} %t7, 0361 %obit7 = extractvalue {i32, i1} %t7, 1362 %res7 = or i1 %res6, %obit7363 %t8 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val8, i32 -128)364 %add8 = extractvalue {i32, i1} %t8, 0365 %obit8 = extractvalue {i32, i1} %t8, 1366 %res8 = or i1 %res7, %obit8367 %t9 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val9, i32 -128)368 %add9 = extractvalue {i32, i1} %t9, 0369 %obit9 = extractvalue {i32, i1} %t9, 1370 %res9 = or i1 %res8, %obit9371 %t10 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val10, i32 -128)372 %add10 = extractvalue {i32, i1} %t10, 0373 %obit10 = extractvalue {i32, i1} %t10, 1374 %res10 = or i1 %res9, %obit10375 %t11 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val11, i32 -128)376 %add11 = extractvalue {i32, i1} %t11, 0377 %obit11 = extractvalue {i32, i1} %t11, 1378 %res11 = or i1 %res10, %obit11379 %t12 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val12, i32 -128)380 %add12 = extractvalue {i32, i1} %t12, 0381 %obit12 = extractvalue {i32, i1} %t12, 1382 %res12 = or i1 %res11, %obit12383 %t13 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val13, i32 -128)384 %add13 = extractvalue {i32, i1} %t13, 0385 %obit13 = extractvalue {i32, i1} %t13, 1386 %res13 = or i1 %res12, %obit13387 %t14 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val14, i32 -128)388 %add14 = extractvalue {i32, i1} %t14, 0389 %obit14 = extractvalue {i32, i1} %t14, 1390 %res14 = or i1 %res13, %obit14391 %t15 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val15, i32 -128)392 %add15 = extractvalue {i32, i1} %t15, 0393 %obit15 = extractvalue {i32, i1} %t15, 1394 %res15 = or i1 %res14, %obit15395 396 br label %store397 398store:399 %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]400 %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]401 %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]402 %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]403 %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]404 %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]405 %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]406 %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]407 %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]408 %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]409 %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]410 %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]411 %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]412 %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]413 %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]414 %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]415 %res = phi i1 [ 0, %entry ], [ %res15, %add ]416 417 store volatile i32 %new0, ptr %ptr418 store volatile i32 %new1, ptr %ptr419 store volatile i32 %new2, ptr %ptr420 store volatile i32 %new3, ptr %ptr421 store volatile i32 %new4, ptr %ptr422 store volatile i32 %new5, ptr %ptr423 store volatile i32 %new6, ptr %ptr424 store volatile i32 %new7, ptr %ptr425 store volatile i32 %new8, ptr %ptr426 store volatile i32 %new9, ptr %ptr427 store volatile i32 %new10, ptr %ptr428 store volatile i32 %new11, ptr %ptr429 store volatile i32 %new12, ptr %ptr430 store volatile i32 %new13, ptr %ptr431 store volatile i32 %new14, ptr %ptr432 store volatile i32 %new15, ptr %ptr433 434 ret i1 %res435}436 437; Check using the overflow result for a branch.438define void @f13(ptr %ptr) {439; CHECK-LABEL: f13:440; CHECK: alsi 0(%r2), 1441; CHECK: jgnle foo@PLT442; CHECK: br %r14443 %a = load i32, ptr %ptr444 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)445 %val = extractvalue {i32, i1} %t, 0446 %obit = extractvalue {i32, i1} %t, 1447 store i32 %val, ptr %ptr448 br i1 %obit, label %call, label %exit449 450call:451 tail call i32 @foo()452 br label %exit453 454exit:455 ret void456}457 458; ... and the same with the inverted direction.459define void @f14(ptr %ptr) {460; CHECK-LABEL: f14:461; CHECK: alsi 0(%r2), 1462; CHECK: jgle foo@PLT463; CHECK: br %r14464 %a = load i32, ptr %ptr465 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)466 %val = extractvalue {i32, i1} %t, 0467 %obit = extractvalue {i32, i1} %t, 1468 store i32 %val, ptr %ptr469 br i1 %obit, label %exit, label %call470 471call:472 tail call i32 @foo()473 br label %exit474 475exit:476 ret void477}478 479declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone480 481