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