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 equality comparisons with zero. First teest 10; the EQ case. 11define 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 16entry: 17 %res = add i32 %a, 1000000 18 %cmp = icmp eq i32 %res, 0 19 br i1 %cmp, label %exit, label %store 20 21store: 22 store i32 %b, i32 *%dest 23 br label %exit 24 25exit: 26 ret i32 %res 27} 28 29; ...and again with NE. 30define 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 35entry: 36 %res = add i32 %a, 1000000 37 %cmp = icmp ne i32 %res, 0 38 br i1 %cmp, label %exit, label %store 39 40store: 41 store i32 %b, i32 *%dest 42 br label %exit 43 44exit: 45 ret i32 %res 46} 47 48; SLT requires a comparison. 49define 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 54entry: 55 %res = add i32 %a, 1000000 56 %cmp = icmp slt i32 %res, 0 57 br i1 %cmp, label %exit, label %store 58 59store: 60 store i32 %b, i32 *%dest 61 br label %exit 62 63exit: 64 ret i32 %res 65} 66 67; ...SLE too. 68define 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 73entry: 74 %res = add i32 %a, 1000000 75 %cmp = icmp sle i32 %res, 0 76 br i1 %cmp, label %exit, label %store 77 78store: 79 store i32 %b, i32 *%dest 80 br label %exit 81 82exit: 83 ret i32 %res 84} 85 86; ...SGT too. 87define 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 92entry: 93 %res = add i32 %a, 1000000 94 %cmp = icmp sgt i32 %res, 0 95 br i1 %cmp, label %exit, label %store 96 97store: 98 store i32 %b, i32 *%dest 99 br label %exit 100 101exit: 102 ret i32 %res 103} 104 105; ...SGE too. 106define 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 111entry: 112 %res = add i32 %a, 1000000 113 %cmp = icmp sge i32 %res, 0 114 br i1 %cmp, label %exit, label %store 115 116store: 117 store i32 %b, i32 *%dest 118 br label %exit 119 120exit: 121 ret i32 %res 122} 123 124; Subtraction also provides enough for equality comparisons with zero. 125define 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 130entry: 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 136store: 137 store i32 %b, i32 *%dest 138 br label %exit 139 140exit: 141 ret i32 %res 142} 143 144; ...but not for ordered comparisons. 145define 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 150entry: 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 156store: 157 store i32 %b, i32 *%dest 158 br label %exit 159 160exit: 161 ret i32 %res 162} 163 164; Logic register-register instructions also provide enough for equality 165; comparisons with zero. 166define 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 171entry: 172 %res = and i32 %a, %b 173 %cmp = icmp ne i32 %res, 0 174 br i1 %cmp, label %exit, label %store 175 176store: 177 store i32 %b, i32 *%dest 178 br label %exit 179 180exit: 181 ret i32 %res 182} 183 184; ...but not for ordered comparisons. 185define 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 190entry: 191 %res = and i32 %a, %b 192 %cmp = icmp slt i32 %res, 0 193 br i1 %cmp, label %exit, label %store 194 195store: 196 store i32 %b, i32 *%dest 197 br label %exit 198 199exit: 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. 205define 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 210entry: 211 %res = and i32 %a, 100000001 212 %cmp = icmp ne i32 %res, 0 213 br i1 %cmp, label %exit, label %store 214 215store: 216 store i32 %b, i32 *%dest 217 br label %exit 218 219exit: 220 ret i32 %res 221} 222 223; Partial logic register-immediate instructions do not provide simple 224; zero results. 225define 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 230entry: 231 %res = and i32 %a, -100 232 %cmp = icmp ne i32 %res, 0 233 br i1 %cmp, label %exit, label %store 234 235store: 236 store i32 %b, i32 *%dest 237 br label %exit 238 239exit: 240 ret i32 %res 241} 242 243; SRA provides the same CC result as a comparison with zero. 244define 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 249entry: 250 %res = ashr i32 %a, %b 251 %cmp = icmp eq i32 %res, 0 252 br i1 %cmp, label %exit, label %store 253 254store: 255 store i32 %b, i32 *%dest 256 br label %exit 257 258exit: 259 ret i32 %res 260} 261 262; ...and again with NE. 263define 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 268entry: 269 %res = ashr i32 %a, %b 270 %cmp = icmp ne i32 %res, 0 271 br i1 %cmp, label %exit, label %store 272 273store: 274 store i32 %b, i32 *%dest 275 br label %exit 276 277exit: 278 ret i32 %res 279} 280 281; ...and SLT. 282define 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 287entry: 288 %res = ashr i32 %a, %b 289 %cmp = icmp slt i32 %res, 0 290 br i1 %cmp, label %exit, label %store 291 292store: 293 store i32 %b, i32 *%dest 294 br label %exit 295 296exit: 297 ret i32 %res 298} 299 300; ...and SLE. 301define 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 306entry: 307 %res = ashr i32 %a, %b 308 %cmp = icmp sle i32 %res, 0 309 br i1 %cmp, label %exit, label %store 310 311store: 312 store i32 %b, i32 *%dest 313 br label %exit 314 315exit: 316 ret i32 %res 317} 318 319; ...and SGT. 320define 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 325entry: 326 %res = ashr i32 %a, %b 327 %cmp = icmp sgt i32 %res, 0 328 br i1 %cmp, label %exit, label %store 329 330store: 331 store i32 %b, i32 *%dest 332 br label %exit 333 334exit: 335 ret i32 %res 336} 337 338; ...and SGE. 339define 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 344entry: 345 %res = ashr i32 %a, %b 346 %cmp = icmp sge i32 %res, 0 347 br i1 %cmp, label %exit, label %store 348 349store: 350 store i32 %b, i32 *%dest 351 br label %exit 352 353exit: 354 ret i32 %res 355} 356 357; RISBG provides the same result as a comparison against zero. 358; Test the EQ case. 359define 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 364entry: 365 %res = and i64 %b, -2 366 %cmp = icmp eq i64 %res, 0 367 br i1 %cmp, label %exit, label %store 368 369store: 370 store i64 %b, i64 *%dest 371 br label %exit 372 373exit: 374 ret i64 %res 375} 376 377; ...and the SLT case. 378define 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 383entry: 384 %res = and i64 %b, -2 385 %cmp = icmp slt i64 %res, 0 386 br i1 %cmp, label %exit, label %store 387 388store: 389 store i64 %b, i64 *%dest 390 br label %exit 391 392exit: 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. 398define 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 406entry: 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 412store: 413 store i32 %b, i32 *%dest 414 br label %exit 415 416exit: 417 ret i32 %res 418} 419 420; ...and again with a CC-clobbering instruction. 421define 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 429entry: 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 435store: 436 store i32 %b, i32 *%dest 437 br label %exit 438 439exit: 440 ret i32 %res 441} 442 443; Check that stores do not interfere. 444define 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 450entry: 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 456store: 457 store i32 %b, i32 *%dest2 458 br label %exit 459 460exit: 461 ret i32 %res 462} 463 464; Check that calls do interfere. 465define 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 471entry: 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 479store: 480 store i32 %add, i32 *%ptr 481 br label %exit 482 483exit: 484 ret void 485} 486 487; Check that inline asms don't interfere if they don't clobber CC. 488define 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 496entry: 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 502store: 503 store i32 %add, i32 *%ptr 504 br label %exit 505 506exit: 507 ret void 508} 509 510; ...but do interfere if they do clobber CC. 511define 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 519entry: 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 525store: 526 store i32 %add, i32 *%ptr 527 br label %exit 528 529exit: 530 ret void 531} 532 533; Test a case where CC is set based on a different register from the 534; compare input. 535define 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 542entry: 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 549store: 550 store i32 %sub, i32 *%dest2 551 br label %exit 552 553exit: 554 ret i32 %add 555} 556 557; Make sure that we don't confuse a base register for a destination. 558define 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 563entry: 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 571store: 572 store i64 %a, i64 *%dest 573 br label %exit 574 575exit: 576 ret void 577} 578 579; Test that L gets converted to LT where useful. 580define 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 585entry: 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 592store: 593 store i32 %res, i32 *%dest 594 br label %exit 595 596exit: 597 ret i32 %res 598} 599 600; Test that LY gets converted to LT where useful. 601define 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 606entry: 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 614store: 615 store i32 %res, i32 *%dest 616 br label %exit 617 618exit: 619 ret i32 %res 620} 621 622; Test that LG gets converted to LTG where useful. 623define 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 628entry: 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 635store: 636 store i64 %res, i64 *%dest 637 br label %exit 638 639exit: 640 ret i64 %res 641} 642 643; Test that LGF gets converted to LTGF where useful. 644define 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 649entry: 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 657store: 658 store i64 %res, i64 *%dest 659 br label %exit 660 661exit: 662 ret i64 %res 663} 664 665; Test that LR gets converted to LTR where useful. 666define 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 674entry: 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 679store: 680 store i32 %val, i32 *%dest 681 br label %exit 682 683exit: 684 ret i32 %val 685} 686 687; Test that LGR gets converted to LTGR where useful. 688define 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 696entry: 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 701store: 702 store i64 %val, i64 *%dest 703 br label %exit 704 705exit: 706 ret i64 %val 707} 708 709; Test that LGFR gets converted to LTGFR where useful. 710define 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 718entry: 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 724store: 725 store i64 %ext, i64 *%dest 726 br label %exit 727 728exit: 729 ret i64 %ext 730} 731 732; Test a case where it is the source rather than destination of LR that 733; we need. 734define 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 742entry: 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 747store: 748 store i32 %val, i32 *%dest 749 br label %exit 750 751exit: 752 ret i32 %val 753} 754 755; Test a case where it is the source rather than destination of LGR that 756; we need. 757define 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 765entry: 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 770store: 771 store i64 %val, i64 *%dest 772 br label %exit 773 774exit: 775 ret i64 %val 776} 777 778; Test a case where it is the source rather than destination of LGFR that 779; we need. 780define 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 788entry: 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 794store: 795 store i32 %val, i32 *%dest 796 br label %exit 797 798exit: 799 ret i32 %val 800} 801 802; Test f35 for in-register extensions. 803define 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 811entry: 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 818store: 819 store i64 %ext, i64 *%dest 820 br label %exit 821 822exit: 823 ret i64 %ext 824} 825 826; ...and again with what InstCombine would produce for f40. 827define 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 835entry: 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 842store: 843 store i64 %ext, i64 *%dest 844 br label %exit 845 846exit: 847 ret i64 %ext 848} 849 850; Try a form of f7 in which the subtraction operands are compared directly. 851define 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 856entry: 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 862store: 863 store i32 %b, i32 *%dest 864 br label %exit 865 866exit: 867 ret i32 %res 868} 869 870; A version of f32 that tests the unextended value. 871define 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 876entry: 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 884store: 885 store i64 %res, i64 *%dest 886 br label %exit 887 888exit: 889 ret i64 %res 890} 891