1 ; Test that compares are omitted if CC already has the right value 2 ; (z10 version). 3 ; 4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -no-integrated-as \ 5 ; RUN: -verify-machineinstrs| FileCheck %s 6 7 declare void @foo() 8 9 ; Addition provides enough for equality comparisons with zero. First teest 10 ; the EQ case. 11 define i32 @f1(i32 %a, i32 %b, i32 *%dest) { 12 ; CHECK-LABEL: f1: 13 ; CHECK: afi %r2, 1000000 14 ; CHECK-NEXT: ber %r14 15 ; CHECK: br %r14 16 entry: 17 %res = add i32 %a, 1000000 18 %cmp = icmp eq i32 %res, 0 19 br i1 %cmp, label %exit, label %store 20 21 store: 22 store i32 %b, i32 *%dest 23 br label %exit 24 25 exit: 26 ret i32 %res 27 } 28 29 ; ...and again with NE. 30 define i32 @f2(i32 %a, i32 %b, i32 *%dest) { 31 ; CHECK-LABEL: f2: 32 ; CHECK: afi %r2, 1000000 33 ; CHECK-NEXT: bner %r14 34 ; CHECK: br %r14 35 entry: 36 %res = add i32 %a, 1000000 37 %cmp = icmp ne i32 %res, 0 38 br i1 %cmp, label %exit, label %store 39 40 store: 41 store i32 %b, i32 *%dest 42 br label %exit 43 44 exit: 45 ret i32 %res 46 } 47 48 ; SLT requires a comparison. 49 define i32 @f3(i32 %a, i32 %b, i32 *%dest) { 50 ; CHECK-LABEL: f3: 51 ; CHECK: afi %r2, 1000000 52 ; CHECK-NEXT: cibl %r2, 0, 0(%r14) 53 ; CHECK: br %r14 54 entry: 55 %res = add i32 %a, 1000000 56 %cmp = icmp slt i32 %res, 0 57 br i1 %cmp, label %exit, label %store 58 59 store: 60 store i32 %b, i32 *%dest 61 br label %exit 62 63 exit: 64 ret i32 %res 65 } 66 67 ; ...SLE too. 68 define i32 @f4(i32 %a, i32 %b, i32 *%dest) { 69 ; CHECK-LABEL: f4: 70 ; CHECK: afi %r2, 1000000 71 ; CHECK-NEXT: cible %r2, 0, 0(%r14) 72 ; CHECK: br %r14 73 entry: 74 %res = add i32 %a, 1000000 75 %cmp = icmp sle i32 %res, 0 76 br i1 %cmp, label %exit, label %store 77 78 store: 79 store i32 %b, i32 *%dest 80 br label %exit 81 82 exit: 83 ret i32 %res 84 } 85 86 ; ...SGT too. 87 define i32 @f5(i32 %a, i32 %b, i32 *%dest) { 88 ; CHECK-LABEL: f5: 89 ; CHECK: afi %r2, 1000000 90 ; CHECK-NEXT: cibh %r2, 0, 0(%r14) 91 ; CHECK: br %r14 92 entry: 93 %res = add i32 %a, 1000000 94 %cmp = icmp sgt i32 %res, 0 95 br i1 %cmp, label %exit, label %store 96 97 store: 98 store i32 %b, i32 *%dest 99 br label %exit 100 101 exit: 102 ret i32 %res 103 } 104 105 ; ...SGE too. 106 define i32 @f6(i32 %a, i32 %b, i32 *%dest) { 107 ; CHECK-LABEL: f6: 108 ; CHECK: afi %r2, 1000000 109 ; CHECK-NEXT: cibhe %r2, 0, 0(%r14) 110 ; CHECK: br %r14 111 entry: 112 %res = add i32 %a, 1000000 113 %cmp = icmp sge i32 %res, 0 114 br i1 %cmp, label %exit, label %store 115 116 store: 117 store i32 %b, i32 *%dest 118 br label %exit 119 120 exit: 121 ret i32 %res 122 } 123 124 ; Subtraction also provides enough for equality comparisons with zero. 125 define i32 @f7(i32 %a, i32 %b, i32 *%dest) { 126 ; CHECK-LABEL: f7: 127 ; CHECK: s %r2, 0(%r4) 128 ; CHECK-NEXT: bner %r14 129 ; CHECK: br %r14 130 entry: 131 %cur = load i32 , i32 *%dest 132 %res = sub i32 %a, %cur 133 %cmp = icmp ne i32 %res, 0 134 br i1 %cmp, label %exit, label %store 135 136 store: 137 store i32 %b, i32 *%dest 138 br label %exit 139 140 exit: 141 ret i32 %res 142 } 143 144 ; ...but not for ordered comparisons. 145 define i32 @f8(i32 %a, i32 %b, i32 *%dest) { 146 ; CHECK-LABEL: f8: 147 ; CHECK: s %r2, 0(%r4) 148 ; CHECK-NEXT: cibl %r2, 0, 0(%r14) 149 ; CHECK: br %r14 150 entry: 151 %cur = load i32 , i32 *%dest 152 %res = sub i32 %a, %cur 153 %cmp = icmp slt i32 %res, 0 154 br i1 %cmp, label %exit, label %store 155 156 store: 157 store i32 %b, i32 *%dest 158 br label %exit 159 160 exit: 161 ret i32 %res 162 } 163 164 ; Logic register-register instructions also provide enough for equality 165 ; comparisons with zero. 166 define i32 @f9(i32 %a, i32 %b, i32 *%dest) { 167 ; CHECK-LABEL: f9: 168 ; CHECK: nr %r2, %r3 169 ; CHECK-NEXT: blr %r14 170 ; CHECK: br %r14 171 entry: 172 %res = and i32 %a, %b 173 %cmp = icmp ne i32 %res, 0 174 br i1 %cmp, label %exit, label %store 175 176 store: 177 store i32 %b, i32 *%dest 178 br label %exit 179 180 exit: 181 ret i32 %res 182 } 183 184 ; ...but not for ordered comparisons. 185 define i32 @f10(i32 %a, i32 %b, i32 *%dest) { 186 ; CHECK-LABEL: f10: 187 ; CHECK: nr %r2, %r3 188 ; CHECK-NEXT: cibl %r2, 0, 0(%r14) 189 ; CHECK: br %r14 190 entry: 191 %res = and i32 %a, %b 192 %cmp = icmp slt i32 %res, 0 193 br i1 %cmp, label %exit, label %store 194 195 store: 196 store i32 %b, i32 *%dest 197 br label %exit 198 199 exit: 200 ret i32 %res 201 } 202 203 ; Logic register-immediate instructions also provide enough for equality 204 ; comparisons with zero if the immediate covers the whole register. 205 define i32 @f11(i32 %a, i32 %b, i32 *%dest) { 206 ; CHECK-LABEL: f11: 207 ; CHECK: nilf %r2, 100000001 208 ; CHECK-NEXT: blr %r14 209 ; CHECK: br %r14 210 entry: 211 %res = and i32 %a, 100000001 212 %cmp = icmp ne i32 %res, 0 213 br i1 %cmp, label %exit, label %store 214 215 store: 216 store i32 %b, i32 *%dest 217 br label %exit 218 219 exit: 220 ret i32 %res 221 } 222 223 ; Partial logic register-immediate instructions do not provide simple 224 ; zero results. 225 define i32 @f12(i32 %a, i32 %b, i32 *%dest) { 226 ; CHECK-LABEL: f12: 227 ; CHECK: nill %r2, 65436 228 ; CHECK-NEXT: ciblh %r2, 0, 0(%r14) 229 ; CHECK: br %r14 230 entry: 231 %res = and i32 %a, -100 232 %cmp = icmp ne i32 %res, 0 233 br i1 %cmp, label %exit, label %store 234 235 store: 236 store i32 %b, i32 *%dest 237 br label %exit 238 239 exit: 240 ret i32 %res 241 } 242 243 ; SRA provides the same CC result as a comparison with zero. 244 define i32 @f13(i32 %a, i32 %b, i32 *%dest) { 245 ; CHECK-LABEL: f13: 246 ; CHECK: sra %r2, 0(%r3) 247 ; CHECK-NEXT: ber %r14 248 ; CHECK: br %r14 249 entry: 250 %res = ashr i32 %a, %b 251 %cmp = icmp eq i32 %res, 0 252 br i1 %cmp, label %exit, label %store 253 254 store: 255 store i32 %b, i32 *%dest 256 br label %exit 257 258 exit: 259 ret i32 %res 260 } 261 262 ; ...and again with NE. 263 define i32 @f14(i32 %a, i32 %b, i32 *%dest) { 264 ; CHECK-LABEL: f14: 265 ; CHECK: sra %r2, 0(%r3) 266 ; CHECK-NEXT: blhr %r14 267 ; CHECK: br %r14 268 entry: 269 %res = ashr i32 %a, %b 270 %cmp = icmp ne i32 %res, 0 271 br i1 %cmp, label %exit, label %store 272 273 store: 274 store i32 %b, i32 *%dest 275 br label %exit 276 277 exit: 278 ret i32 %res 279 } 280 281 ; ...and SLT. 282 define i32 @f15(i32 %a, i32 %b, i32 *%dest) { 283 ; CHECK-LABEL: f15: 284 ; CHECK: sra %r2, 0(%r3) 285 ; CHECK-NEXT: blr %r14 286 ; CHECK: br %r14 287 entry: 288 %res = ashr i32 %a, %b 289 %cmp = icmp slt i32 %res, 0 290 br i1 %cmp, label %exit, label %store 291 292 store: 293 store i32 %b, i32 *%dest 294 br label %exit 295 296 exit: 297 ret i32 %res 298 } 299 300 ; ...and SLE. 301 define i32 @f16(i32 %a, i32 %b, i32 *%dest) { 302 ; CHECK-LABEL: f16: 303 ; CHECK: sra %r2, 0(%r3) 304 ; CHECK-NEXT: bler %r14 305 ; CHECK: br %r14 306 entry: 307 %res = ashr i32 %a, %b 308 %cmp = icmp sle i32 %res, 0 309 br i1 %cmp, label %exit, label %store 310 311 store: 312 store i32 %b, i32 *%dest 313 br label %exit 314 315 exit: 316 ret i32 %res 317 } 318 319 ; ...and SGT. 320 define i32 @f17(i32 %a, i32 %b, i32 *%dest) { 321 ; CHECK-LABEL: f17: 322 ; CHECK: sra %r2, 0(%r3) 323 ; CHECK-NEXT: bhr %r14 324 ; CHECK: br %r14 325 entry: 326 %res = ashr i32 %a, %b 327 %cmp = icmp sgt i32 %res, 0 328 br i1 %cmp, label %exit, label %store 329 330 store: 331 store i32 %b, i32 *%dest 332 br label %exit 333 334 exit: 335 ret i32 %res 336 } 337 338 ; ...and SGE. 339 define i32 @f18(i32 %a, i32 %b, i32 *%dest) { 340 ; CHECK-LABEL: f18: 341 ; CHECK: sra %r2, 0(%r3) 342 ; CHECK-NEXT: bher %r14 343 ; CHECK: br %r14 344 entry: 345 %res = ashr i32 %a, %b 346 %cmp = icmp sge i32 %res, 0 347 br i1 %cmp, label %exit, label %store 348 349 store: 350 store i32 %b, i32 *%dest 351 br label %exit 352 353 exit: 354 ret i32 %res 355 } 356 357 ; RISBG provides the same result as a comparison against zero. 358 ; Test the EQ case. 359 define i64 @f19(i64 %a, i64 %b, i64 *%dest) { 360 ; CHECK-LABEL: f19: 361 ; CHECK: risbg %r2, %r3, 0, 190, 0 362 ; CHECK-NEXT: ber %r14 363 ; CHECK: br %r14 364 entry: 365 %res = and i64 %b, -2 366 %cmp = icmp eq i64 %res, 0 367 br i1 %cmp, label %exit, label %store 368 369 store: 370 store i64 %b, i64 *%dest 371 br label %exit 372 373 exit: 374 ret i64 %res 375 } 376 377 ; ...and the SLT case. 378 define i64 @f20(i64 %a, i64 %b, i64 *%dest) { 379 ; CHECK-LABEL: f20: 380 ; CHECK: risbg %r2, %r3, 0, 190, 0 381 ; CHECK-NEXT: blr %r14 382 ; CHECK: br %r14 383 entry: 384 %res = and i64 %b, -2 385 %cmp = icmp slt i64 %res, 0 386 br i1 %cmp, label %exit, label %store 387 388 store: 389 store i64 %b, i64 *%dest 390 br label %exit 391 392 exit: 393 ret i64 %res 394 } 395 396 ; Test a case where the register we're testing is set by a non-CC-clobbering 397 ; instruction. 398 define i32 @f21(i32 %a, i32 %b, i32 *%dest) { 399 ; CHECK-LABEL: f21: 400 ; CHECK: afi %r2, 1000000 401 ; CHECK-NEXT: #APP 402 ; CHECK-NEXT: blah %r2 403 ; CHECK-NEXT: #NO_APP 404 ; CHECK-NEXT: cibe %r2, 0, 0(%r14) 405 ; CHECK: br %r14 406 entry: 407 %add = add i32 %a, 1000000 408 %res = call i32 asm "blah $0", "=r,0" (i32 %add) 409 %cmp = icmp eq i32 %res, 0 410 br i1 %cmp, label %exit, label %store 411 412 store: 413 store i32 %b, i32 *%dest 414 br label %exit 415 416 exit: 417 ret i32 %res 418 } 419 420 ; ...and again with a CC-clobbering instruction. 421 define i32 @f22(i32 %a, i32 %b, i32 *%dest) { 422 ; CHECK-LABEL: f22: 423 ; CHECK: afi %r2, 1000000 424 ; CHECK-NEXT: #APP 425 ; CHECK-NEXT: blah %r2 426 ; CHECK-NEXT: #NO_APP 427 ; CHECK-NEXT: cibe %r2, 0, 0(%r14) 428 ; CHECK: br %r14 429 entry: 430 %add = add i32 %a, 1000000 431 %res = call i32 asm "blah $0", "=r,0,~{cc}" (i32 %add) 432 %cmp = icmp eq i32 %res, 0 433 br i1 %cmp, label %exit, label %store 434 435 store: 436 store i32 %b, i32 *%dest 437 br label %exit 438 439 exit: 440 ret i32 %res 441 } 442 443 ; Check that stores do not interfere. 444 define i32 @f23(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) { 445 ; CHECK-LABEL: f23: 446 ; CHECK: afi %r2, 1000000 447 ; CHECK-NEXT: st %r2, 0(%r4) 448 ; CHECK-NEXT: bner %r14 449 ; CHECK: br %r14 450 entry: 451 %res = add i32 %a, 1000000 452 store i32 %res, i32 *%dest1 453 %cmp = icmp ne i32 %res, 0 454 br i1 %cmp, label %exit, label %store 455 456 store: 457 store i32 %b, i32 *%dest2 458 br label %exit 459 460 exit: 461 ret i32 %res 462 } 463 464 ; Check that calls do interfere. 465 define void @f24(i32 *%ptr) { 466 ; CHECK-LABEL: f24: 467 ; CHECK: afi [[REG:%r[0-9]+]], 1000000 468 ; CHECK-NEXT: brasl %r14, foo@PLT 469 ; CHECK-NEXT: cijlh [[REG]], 0, .L{{.*}} 470 ; CHECK: br %r14 471 entry: 472 %val = load i32 , i32 *%ptr 473 %xor = xor i32 %val, 1 474 %add = add i32 %xor, 1000000 475 call void @foo() 476 %cmp = icmp ne i32 %add, 0 477 br i1 %cmp, label %exit, label %store 478 479 store: 480 store i32 %add, i32 *%ptr 481 br label %exit 482 483 exit: 484 ret void 485 } 486 487 ; Check that inline asms don't interfere if they don't clobber CC. 488 define void @f25(i32 %a, i32 *%ptr) { 489 ; CHECK-LABEL: f25: 490 ; CHECK: afi %r2, 1000000 491 ; CHECK-NEXT: #APP 492 ; CHECK-NEXT: blah 493 ; CHECK-NEXT: #NO_APP 494 ; CHECK-NEXT: bner %r14 495 ; CHECK: br %r14 496 entry: 497 %add = add i32 %a, 1000000 498 call void asm sideeffect "blah", "r"(i32 %add) 499 %cmp = icmp ne i32 %add, 0 500 br i1 %cmp, label %exit, label %store 501 502 store: 503 store i32 %add, i32 *%ptr 504 br label %exit 505 506 exit: 507 ret void 508 } 509 510 ; ...but do interfere if they do clobber CC. 511 define void @f26(i32 %a, i32 *%ptr) { 512 ; CHECK-LABEL: f26: 513 ; CHECK: afi %r2, 1000000 514 ; CHECK-NEXT: #APP 515 ; CHECK-NEXT: blah 516 ; CHECK-NEXT: #NO_APP 517 ; CHECK-NEXT: ciblh %r2, 0, 0(%r14) 518 ; CHECK: br %r14 519 entry: 520 %add = add i32 %a, 1000000 521 call void asm sideeffect "blah", "r,~{cc}"(i32 %add) 522 %cmp = icmp ne i32 %add, 0 523 br i1 %cmp, label %exit, label %store 524 525 store: 526 store i32 %add, i32 *%ptr 527 br label %exit 528 529 exit: 530 ret void 531 } 532 533 ; Test a case where CC is set based on a different register from the 534 ; compare input. 535 define i32 @f27(i32 %a, i32 %b, i32 *%dest1, i32 *%dest2) { 536 ; CHECK-LABEL: f27: 537 ; CHECK: afi %r2, 1000000 538 ; CHECK-NEXT: sr %r3, %r2 539 ; CHECK-NEXT: st %r3, 0(%r4) 540 ; CHECK-NEXT: cibe %r2, 0, 0(%r14) 541 ; CHECK: br %r14 542 entry: 543 %add = add i32 %a, 1000000 544 %sub = sub i32 %b, %add 545 store i32 %sub, i32 *%dest1 546 %cmp = icmp eq i32 %add, 0 547 br i1 %cmp, label %exit, label %store 548 549 store: 550 store i32 %sub, i32 *%dest2 551 br label %exit 552 553 exit: 554 ret i32 %add 555 } 556 557 ; Make sure that we don't confuse a base register for a destination. 558 define void @f28(i64 %a, i64 *%dest) { 559 ; CHECK-LABEL: f28: 560 ; CHECK: xi 0(%r2), 15 561 ; CHECK: cgibe %r2, 0, 0(%r14) 562 ; CHECK: br %r14 563 entry: 564 %ptr = inttoptr i64 %a to i8 * 565 %val = load i8 , i8 *%ptr 566 %xor = xor i8 %val, 15 567 store i8 %xor, i8 *%ptr 568 %cmp = icmp eq i64 %a, 0 569 br i1 %cmp, label %exit, label %store 570 571 store: 572 store i64 %a, i64 *%dest 573 br label %exit 574 575 exit: 576 ret void 577 } 578 579 ; Test that L gets converted to LT where useful. 580 define i32 @f29(i64 %base, i64 %index, i32 *%dest) { 581 ; CHECK-LABEL: f29: 582 ; CHECK: lt %r2, 0({{%r2,%r3|%r3,%r2}}) 583 ; CHECK-NEXT: bler %r14 584 ; CHECK: br %r14 585 entry: 586 %add = add i64 %base, %index 587 %ptr = inttoptr i64 %add to i32 * 588 %res = load i32 , i32 *%ptr 589 %cmp = icmp sle i32 %res, 0 590 br i1 %cmp, label %exit, label %store 591 592 store: 593 store i32 %res, i32 *%dest 594 br label %exit 595 596 exit: 597 ret i32 %res 598 } 599 600 ; Test that LY gets converted to LT where useful. 601 define i32 @f30(i64 %base, i64 %index, i32 *%dest) { 602 ; CHECK-LABEL: f30: 603 ; CHECK: lt %r2, 100000({{%r2,%r3|%r3,%r2}}) 604 ; CHECK-NEXT: bler %r14 605 ; CHECK: br %r14 606 entry: 607 %add1 = add i64 %base, %index 608 %add2 = add i64 %add1, 100000 609 %ptr = inttoptr i64 %add2 to i32 * 610 %res = load i32 , i32 *%ptr 611 %cmp = icmp sle i32 %res, 0 612 br i1 %cmp, label %exit, label %store 613 614 store: 615 store i32 %res, i32 *%dest 616 br label %exit 617 618 exit: 619 ret i32 %res 620 } 621 622 ; Test that LG gets converted to LTG where useful. 623 define i64 @f31(i64 %base, i64 %index, i64 *%dest) { 624 ; CHECK-LABEL: f31: 625 ; CHECK: ltg %r2, 0({{%r2,%r3|%r3,%r2}}) 626 ; CHECK-NEXT: bher %r14 627 ; CHECK: br %r14 628 entry: 629 %add = add i64 %base, %index 630 %ptr = inttoptr i64 %add to i64 * 631 %res = load i64 , i64 *%ptr 632 %cmp = icmp sge i64 %res, 0 633 br i1 %cmp, label %exit, label %store 634 635 store: 636 store i64 %res, i64 *%dest 637 br label %exit 638 639 exit: 640 ret i64 %res 641 } 642 643 ; Test that LGF gets converted to LTGF where useful. 644 define i64 @f32(i64 %base, i64 %index, i64 *%dest) { 645 ; CHECK-LABEL: f32: 646 ; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}}) 647 ; CHECK-NEXT: bhr %r14 648 ; CHECK: br %r14 649 entry: 650 %add = add i64 %base, %index 651 %ptr = inttoptr i64 %add to i32 * 652 %val = load i32 , i32 *%ptr 653 %res = sext i32 %val to i64 654 %cmp = icmp sgt i64 %res, 0 655 br i1 %cmp, label %exit, label %store 656 657 store: 658 store i64 %res, i64 *%dest 659 br label %exit 660 661 exit: 662 ret i64 %res 663 } 664 665 ; Test that LR gets converted to LTR where useful. 666 define i32 @f33(i32 %dummy, i32 %val, i32 *%dest) { 667 ; CHECK-LABEL: f33: 668 ; CHECK: ltr %r2, %r3 669 ; CHECK-NEXT: #APP 670 ; CHECK-NEXT: blah %r2 671 ; CHECK-NEXT: #NO_APP 672 ; CHECK-NEXT: blr %r14 673 ; CHECK: br %r14 674 entry: 675 call void asm sideeffect "blah $0", "{r2}"(i32 %val) 676 %cmp = icmp slt i32 %val, 0 677 br i1 %cmp, label %exit, label %store 678 679 store: 680 store i32 %val, i32 *%dest 681 br label %exit 682 683 exit: 684 ret i32 %val 685 } 686 687 ; Test that LGR gets converted to LTGR where useful. 688 define i64 @f34(i64 %dummy, i64 %val, i64 *%dest) { 689 ; CHECK-LABEL: f34: 690 ; CHECK: ltgr %r2, %r3 691 ; CHECK-NEXT: #APP 692 ; CHECK-NEXT: blah %r2 693 ; CHECK-NEXT: #NO_APP 694 ; CHECK-NEXT: bhr %r14 695 ; CHECK: br %r14 696 entry: 697 call void asm sideeffect "blah $0", "{r2}"(i64 %val) 698 %cmp = icmp sgt i64 %val, 0 699 br i1 %cmp, label %exit, label %store 700 701 store: 702 store i64 %val, i64 *%dest 703 br label %exit 704 705 exit: 706 ret i64 %val 707 } 708 709 ; Test that LGFR gets converted to LTGFR where useful. 710 define i64 @f35(i64 %dummy, i32 %val, i64 *%dest) { 711 ; CHECK-LABEL: f35: 712 ; CHECK: ltgfr %r2, %r3 713 ; CHECK-NEXT: #APP 714 ; CHECK-NEXT: blah %r2 715 ; CHECK-NEXT: #NO_APP 716 ; CHECK-NEXT: bhr %r14 717 ; CHECK: br %r14 718 entry: 719 %ext = sext i32 %val to i64 720 call void asm sideeffect "blah $0", "{r2}"(i64 %ext) 721 %cmp = icmp sgt i64 %ext, 0 722 br i1 %cmp, label %exit, label %store 723 724 store: 725 store i64 %ext, i64 *%dest 726 br label %exit 727 728 exit: 729 ret i64 %ext 730 } 731 732 ; Test a case where it is the source rather than destination of LR that 733 ; we need. 734 define i32 @f36(i32 %val, i32 %dummy, i32 *%dest) { 735 ; CHECK-LABEL: f36: 736 ; CHECK: ltr %r3, %r2 737 ; CHECK-NEXT: #APP 738 ; CHECK-NEXT: blah %r3 739 ; CHECK-NEXT: #NO_APP 740 ; CHECK-NEXT: blr %r14 741 ; CHECK: br %r14 742 entry: 743 call void asm sideeffect "blah $0", "{r3}"(i32 %val) 744 %cmp = icmp slt i32 %val, 0 745 br i1 %cmp, label %exit, label %store 746 747 store: 748 store i32 %val, i32 *%dest 749 br label %exit 750 751 exit: 752 ret i32 %val 753 } 754 755 ; Test a case where it is the source rather than destination of LGR that 756 ; we need. 757 define i64 @f37(i64 %val, i64 %dummy, i64 *%dest) { 758 ; CHECK-LABEL: f37: 759 ; CHECK: ltgr %r3, %r2 760 ; CHECK-NEXT: #APP 761 ; CHECK-NEXT: blah %r3 762 ; CHECK-NEXT: #NO_APP 763 ; CHECK-NEXT: blr %r14 764 ; CHECK: br %r14 765 entry: 766 call void asm sideeffect "blah $0", "{r3}"(i64 %val) 767 %cmp = icmp slt i64 %val, 0 768 br i1 %cmp, label %exit, label %store 769 770 store: 771 store i64 %val, i64 *%dest 772 br label %exit 773 774 exit: 775 ret i64 %val 776 } 777 778 ; Test a case where it is the source rather than destination of LGFR that 779 ; we need. 780 define i32 @f38(i32 %val, i64 %dummy, i32 *%dest) { 781 ; CHECK-LABEL: f38: 782 ; CHECK: ltgfr %r3, %r2 783 ; CHECK-NEXT: #APP 784 ; CHECK-NEXT: blah %r3 785 ; CHECK-NEXT: #NO_APP 786 ; CHECK-NEXT: blr %r14 787 ; CHECK: br %r14 788 entry: 789 %ext = sext i32 %val to i64 790 call void asm sideeffect "blah $0", "{r3}"(i64 %ext) 791 %cmp = icmp slt i32 %val, 0 792 br i1 %cmp, label %exit, label %store 793 794 store: 795 store i32 %val, i32 *%dest 796 br label %exit 797 798 exit: 799 ret i32 %val 800 } 801 802 ; Test f35 for in-register extensions. 803 define i64 @f39(i64 %dummy, i64 %a, i64 *%dest) { 804 ; CHECK-LABEL: f39: 805 ; CHECK: ltgfr %r2, %r3 806 ; CHECK-NEXT: #APP 807 ; CHECK-NEXT: blah %r2 808 ; CHECK-NEXT: #NO_APP 809 ; CHECK-NEXT: bhr %r14 810 ; CHECK: br %r14 811 entry: 812 %val = trunc i64 %a to i32 813 %ext = sext i32 %val to i64 814 call void asm sideeffect "blah $0", "{r2}"(i64 %ext) 815 %cmp = icmp sgt i64 %ext, 0 816 br i1 %cmp, label %exit, label %store 817 818 store: 819 store i64 %ext, i64 *%dest 820 br label %exit 821 822 exit: 823 ret i64 %ext 824 } 825 826 ; ...and again with what InstCombine would produce for f40. 827 define i64 @f40(i64 %dummy, i64 %a, i64 *%dest) { 828 ; CHECK-LABEL: f40: 829 ; CHECK: ltgfr %r2, %r3 830 ; CHECK-NEXT: #APP 831 ; CHECK-NEXT: blah %r2 832 ; CHECK-NEXT: #NO_APP 833 ; CHECK-NEXT: bhr %r14 834 ; CHECK: br %r14 835 entry: 836 %shl = shl i64 %a, 32 837 %ext = ashr i64 %shl, 32 838 call void asm sideeffect "blah $0", "{r2}"(i64 %ext) 839 %cmp = icmp sgt i64 %shl, 0 840 br i1 %cmp, label %exit, label %store 841 842 store: 843 store i64 %ext, i64 *%dest 844 br label %exit 845 846 exit: 847 ret i64 %ext 848 } 849 850 ; Try a form of f7 in which the subtraction operands are compared directly. 851 define i32 @f41(i32 %a, i32 %b, i32 *%dest) { 852 ; CHECK-LABEL: f41: 853 ; CHECK: s %r2, 0(%r4) 854 ; CHECK-NEXT: bner %r14 855 ; CHECK: br %r14 856 entry: 857 %cur = load i32 , i32 *%dest 858 %res = sub i32 %a, %cur 859 %cmp = icmp ne i32 %a, %cur 860 br i1 %cmp, label %exit, label %store 861 862 store: 863 store i32 %b, i32 *%dest 864 br label %exit 865 866 exit: 867 ret i32 %res 868 } 869 870 ; A version of f32 that tests the unextended value. 871 define i64 @f42(i64 %base, i64 %index, i64 *%dest) { 872 ; CHECK-LABEL: f42: 873 ; CHECK: ltgf %r2, 0({{%r2,%r3|%r3,%r2}}) 874 ; CHECK-NEXT: bhr %r14 875 ; CHECK: br %r14 876 entry: 877 %add = add i64 %base, %index 878 %ptr = inttoptr i64 %add to i32 * 879 %val = load i32 , i32 *%ptr 880 %res = sext i32 %val to i64 881 %cmp = icmp sgt i32 %val, 0 882 br i1 %cmp, label %exit, label %store 883 884 store: 885 store i64 %res, i64 *%dest 886 br label %exit 887 888 exit: 889 ret i64 %res 890 } 891