1; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu | FileCheck %s 2; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s 3 4; Test cases for compare elimination in PPCMIPeephole pass 5 6define void @func1(i32 signext %a) { 7; We should have only one compare instruction 8; CHECK-LABEL: @func1 9; CHECK: cmp 10; CHECK-NOT: cmp 11; CHECK: blr 12entry: 13 %cmp = icmp eq i32 %a, 100 14 br i1 %cmp, label %if.then, label %if.else 15 16if.then: 17 tail call void @dummy1() 18 br label %if.end3 19 20if.else: 21 %cmp1 = icmp slt i32 %a, 100 22 br i1 %cmp1, label %if.then2, label %if.end3 23 24if.then2: 25 tail call void @dummy2() 26 br label %if.end3 27 28if.end3: 29 ret void 30} 31 32 33define void @func2(i32 signext %a) { 34; CHECK-LABEL: @func2 35; CHECK: cmp 36; CHECK-NOT: cmp 37; CHECK: blr 38entry: 39 %cmp = icmp slt i32 %a, 100 40 br i1 %cmp, label %if.then, label %if.else 41 42if.then: 43 tail call void @dummy1() 44 br label %if.end3 45 46if.else: 47 %cmp1 = icmp eq i32 %a, 100 48 br i1 %cmp1, label %if.end3, label %if.then2 49 50if.then2: 51 tail call void @dummy2() 52 br label %if.end3 53 54if.end3: 55 ret void 56} 57 58 59define void @func3(i32 signext %a) { 60; CHECK-LABEL: @func3 61; CHECK: cmp 62; CHECK-NOT: cmp 63; CHECK: blr 64entry: 65 %cmp = icmp sgt i32 %a, 100 66 br i1 %cmp, label %if.then, label %if.else 67 68if.then: 69 tail call void @dummy1() 70 br label %if.end3 71 72if.else: 73 %cmp1 = icmp eq i32 %a, 100 74 br i1 %cmp1, label %if.then2, label %if.end3 75 76if.then2: 77 tail call void @dummy2() 78 br label %if.end3 79 80if.end3: 81 ret void 82} 83 84 85define void @func4(i32 zeroext %a) { 86; CHECK-LABEL: @func4 87; CHECK: cmp 88; CHECK-NOT: cmp 89; CHECK: blr 90entry: 91 %cmp = icmp eq i32 %a, 100 92 br i1 %cmp, label %if.then, label %if.else 93 94if.then: 95 tail call void @dummy1() 96 br label %if.end3 97 98if.else: 99 %cmp1 = icmp ult i32 %a, 100 100 br i1 %cmp1, label %if.then2, label %if.end3 101 102if.then2: 103 tail call void @dummy2() 104 br label %if.end3 105 106if.end3: 107 ret void 108} 109 110 111define void @func5(i32 zeroext %a) { 112; CHECK-LABEL: @func5 113; CHECK: cmp 114; CHECK-NOT: cmp 115; CHECK: blr 116entry: 117 %cmp = icmp ult i32 %a, 100 118 br i1 %cmp, label %if.then, label %if.else 119 120if.then: 121 tail call void @dummy1() 122 br label %if.end3 123 124if.else: 125 %cmp1 = icmp eq i32 %a, 100 126 br i1 %cmp1, label %if.end3, label %if.then2 127 128if.then2: 129 tail call void @dummy2() 130 br label %if.end3 131 132if.end3: 133 ret void 134} 135 136 137define void @func6(i32 zeroext %a) { 138; CHECK-LABEL: @func6 139; CHECK: cmp 140; CHECK-NOT: cmp 141; CHECK: blr 142entry: 143 %cmp = icmp ugt i32 %a, 100 144 br i1 %cmp, label %if.then, label %if.else 145 146if.then: 147 tail call void @dummy1() 148 br label %if.end3 149 150if.else: 151 %cmp1 = icmp eq i32 %a, 100 152 br i1 %cmp1, label %if.then2, label %if.end3 153 154if.then2: 155 tail call void @dummy2() 156 br label %if.end3 157 158if.end3: 159 ret void 160} 161 162 163define void @func7(i64 %a) { 164; CHECK-LABEL: @func7 165; CHECK: cmp 166; CHECK-NOT: cmp 167; CHECK: blr 168entry: 169 %cmp = icmp eq i64 %a, 100 170 br i1 %cmp, label %if.then, label %if.else 171 172if.then: 173 tail call void @dummy1() 174 br label %if.end3 175 176if.else: 177 %cmp1 = icmp slt i64 %a, 100 178 br i1 %cmp1, label %if.then2, label %if.end3 179 180if.then2: 181 tail call void @dummy2() 182 br label %if.end3 183 184if.end3: 185 ret void 186} 187 188 189define void @func8(i64 %a) { 190; CHECK-LABEL: @func8 191; CHECK: cmp 192; CHECK-NOT: cmp 193; CHECK: blr 194entry: 195 %cmp = icmp slt i64 %a, 100 196 br i1 %cmp, label %if.then, label %if.else 197 198if.then: 199 tail call void @dummy1() 200 br label %if.end3 201 202if.else: 203 %cmp1 = icmp eq i64 %a, 100 204 br i1 %cmp1, label %if.end3, label %if.then2 205 206if.then2: 207 tail call void @dummy2() 208 br label %if.end3 209 210if.end3: 211 ret void 212} 213 214 215define void @func9(i64 %a) { 216; CHECK-LABEL: @func9 217; CHECK: cmp 218; CHECK-NOT: cmp 219; CHECK: blr 220entry: 221 %cmp = icmp sgt i64 %a, 100 222 br i1 %cmp, label %if.then, label %if.else 223 224if.then: 225 tail call void @dummy1() 226 br label %if.end3 227 228if.else: 229 %cmp1 = icmp eq i64 %a, 100 230 br i1 %cmp1, label %if.then2, label %if.end3 231 232if.then2: 233 tail call void @dummy2() 234 br label %if.end3 235 236if.end3: 237 ret void 238} 239 240 241define void @func10(i64 %a) { 242; CHECK-LABEL: @func10 243; CHECK: cmp 244; CHECK-NOT: cmp 245; CHECK: blr 246entry: 247 %cmp = icmp eq i64 %a, 100 248 br i1 %cmp, label %if.then, label %if.else 249 250if.then: 251 tail call void @dummy1() 252 br label %if.end3 253 254if.else: 255 %cmp1 = icmp ult i64 %a, 100 256 br i1 %cmp1, label %if.then2, label %if.end3 257 258if.then2: 259 tail call void @dummy2() 260 br label %if.end3 261 262if.end3: 263 ret void 264} 265 266 267define void @func11(i64 %a) { 268; CHECK-LABEL: @func11 269; CHECK: cmp 270; CHECK-NOT: cmp 271; CHECK: blr 272entry: 273 %cmp = icmp ult i64 %a, 100 274 br i1 %cmp, label %if.then, label %if.else 275 276if.then: 277 tail call void @dummy1() 278 br label %if.end3 279 280if.else: 281 %cmp1 = icmp eq i64 %a, 100 282 br i1 %cmp1, label %if.end3, label %if.then2 283 284if.then2: 285 tail call void @dummy2() 286 br label %if.end3 287 288if.end3: 289 ret void 290} 291 292 293define void @func12(i64 %a) { 294; CHECK-LABEL: @func12 295; CHECK: cmp 296; CHECK-NOT: cmp 297; CHECK: blr 298entry: 299 %cmp = icmp ugt i64 %a, 100 300 br i1 %cmp, label %if.then, label %if.else 301 302if.then: 303 tail call void @dummy1() 304 br label %if.end3 305 306if.else: 307 %cmp1 = icmp eq i64 %a, 100 308 br i1 %cmp1, label %if.then2, label %if.end3 309 310if.then2: 311 tail call void @dummy2() 312 br label %if.end3 313 314if.end3: 315 ret void 316} 317 318 319define void @func13(i32 signext %a, i32 signext %b) { 320; CHECK-LABEL: @func13 321; CHECK: cmp 322; CHECK-NOT: cmp 323; CHECK: blr 324entry: 325 %cmp = icmp eq i32 %a, %b 326 br i1 %cmp, label %if.then, label %if.else 327 328if.then: 329 tail call void @dummy1() 330 br label %if.end3 331 332if.else: 333 %cmp1 = icmp slt i32 %a, %b 334 br i1 %cmp1, label %if.then2, label %if.end3 335 336if.then2: 337 tail call void @dummy2() 338 br label %if.end3 339 340if.end3: 341 ret void 342} 343 344 345define void @func14(i32 signext %a, i32 signext %b) { 346; CHECK-LABEL: @func14 347; CHECK: cmp 348; CHECK-NOT: cmp 349; CHECK: blr 350entry: 351 %cmp = icmp slt i32 %a, %b 352 br i1 %cmp, label %if.then, label %if.else 353 354if.then: 355 tail call void @dummy1() 356 br label %if.end3 357 358if.else: 359 %cmp1 = icmp sgt i32 %a, %b 360 br i1 %cmp1, label %if.then2, label %if.end3 361 362if.then2: 363 tail call void @dummy2() 364 br label %if.end3 365 366if.end3: 367 ret void 368} 369 370 371define void @func15(i32 signext %a, i32 signext %b) { 372; CHECK-LABEL: @func15 373; CHECK: cmp 374; CHECK-NOT: cmp 375; CHECK: blr 376entry: 377 %cmp = icmp slt i32 %b, %a 378 br i1 %cmp, label %if.then, label %if.else 379 380if.then: 381 tail call void @dummy1() 382 br label %if.end3 383 384if.else: 385 %cmp1 = icmp eq i32 %a, %b 386 br i1 %cmp1, label %if.then2, label %if.end3 387 388if.then2: 389 tail call void @dummy2() 390 br label %if.end3 391 392if.end3: 393 ret void 394} 395 396 397define void @func16(i32 zeroext %a, i32 zeroext %b) { 398; CHECK-LABEL: @func16 399; CHECK: cmp 400; CHECK-NOT: cmp 401; CHECK: blr 402entry: 403 %cmp = icmp eq i32 %a, %b 404 br i1 %cmp, label %if.then, label %if.else 405 406if.then: 407 tail call void @dummy1() 408 br label %if.end3 409 410if.else: 411 %cmp1 = icmp ult i32 %a, %b 412 br i1 %cmp1, label %if.then2, label %if.end3 413 414if.then2: 415 tail call void @dummy2() 416 br label %if.end3 417 418if.end3: 419 ret void 420} 421 422 423define void @func17(i32 zeroext %a, i32 zeroext %b) { 424; CHECK-LABEL: @func17 425; CHECK: cmp 426; CHECK-NOT: cmp 427; CHECK: blr 428entry: 429 %cmp = icmp ult i32 %a, %b 430 br i1 %cmp, label %if.then, label %if.else 431 432if.then: 433 tail call void @dummy1() 434 br label %if.end3 435 436if.else: 437 %cmp1 = icmp ugt i32 %a, %b 438 br i1 %cmp1, label %if.then2, label %if.end3 439 440if.then2: 441 tail call void @dummy2() 442 br label %if.end3 443 444if.end3: 445 ret void 446} 447 448 449define void @func18(i32 zeroext %a, i32 zeroext %b) { 450; CHECK-LABEL: @func18 451; CHECK: cmp 452; CHECK-NOT: cmp 453; CHECK: blr 454entry: 455 %cmp = icmp ult i32 %b, %a 456 br i1 %cmp, label %if.then, label %if.else 457 458if.then: 459 tail call void @dummy1() 460 br label %if.end3 461 462if.else: 463 %cmp1 = icmp eq i32 %a, %b 464 br i1 %cmp1, label %if.then2, label %if.end3 465 466if.then2: 467 tail call void @dummy2() 468 br label %if.end3 469 470if.end3: 471 ret void 472} 473 474 475define void @func19(i64 %a, i64 %b) { 476; CHECK-LABEL: @func19 477; CHECK: cmp 478; CHECK-NOT: cmp 479; CHECK: blr 480entry: 481 %cmp = icmp eq i64 %a, %b 482 br i1 %cmp, label %if.then, label %if.else 483 484if.then: 485 tail call void @dummy1() 486 br label %if.end3 487 488if.else: 489 %cmp1 = icmp slt i64 %a, %b 490 br i1 %cmp1, label %if.then2, label %if.end3 491 492if.then2: 493 tail call void @dummy2() 494 br label %if.end3 495 496if.end3: 497 ret void 498} 499 500 501define void @func20(i64 %a, i64 %b) { 502; CHECK-LABEL: @func20 503; CHECK: cmp 504; CHECK-NOT: cmp 505; CHECK: blr 506entry: 507 %cmp = icmp slt i64 %a, %b 508 br i1 %cmp, label %if.then, label %if.else 509 510if.then: 511 tail call void @dummy1() 512 br label %if.end3 513 514if.else: 515 %cmp1 = icmp sgt i64 %a, %b 516 br i1 %cmp1, label %if.then2, label %if.end3 517 518if.then2: 519 tail call void @dummy2() 520 br label %if.end3 521 522if.end3: 523 ret void 524} 525 526 527define void @func21(i64 %a, i64 %b) { 528; CHECK-LABEL: @func21 529; CHECK: cmp 530; CHECK-NOT: cmp 531; CHECK: blr 532entry: 533 %cmp = icmp slt i64 %b, %a 534 br i1 %cmp, label %if.then, label %if.else 535 536if.then: 537 tail call void @dummy1() 538 br label %if.end3 539 540if.else: 541 %cmp1 = icmp eq i64 %a, %b 542 br i1 %cmp1, label %if.then2, label %if.end3 543 544if.then2: 545 tail call void @dummy2() 546 br label %if.end3 547 548if.end3: 549 ret void 550} 551 552 553define void @func22(i64 %a, i64 %b) { 554; CHECK-LABEL: @func22 555; CHECK: cmp 556; CHECK-NOT: cmp 557; CHECK: blr 558entry: 559 %cmp = icmp eq i64 %a, %b 560 br i1 %cmp, label %if.then, label %if.else 561 562if.then: 563 tail call void @dummy1() 564 br label %if.end3 565 566if.else: 567 %cmp1 = icmp ult i64 %a, %b 568 br i1 %cmp1, label %if.then2, label %if.end3 569 570if.then2: 571 tail call void @dummy2() 572 br label %if.end3 573 574if.end3: 575 ret void 576} 577 578 579define void @func23(i64 %a, i64 %b) { 580; CHECK-LABEL: @func23 581; CHECK: cmp 582; CHECK-NOT: cmp 583; CHECK: blr 584entry: 585 %cmp = icmp ult i64 %a, %b 586 br i1 %cmp, label %if.then, label %if.else 587 588if.then: 589 tail call void @dummy1() 590 br label %if.end3 591 592if.else: 593 %cmp1 = icmp ugt i64 %a, %b 594 br i1 %cmp1, label %if.then2, label %if.end3 595 596if.then2: 597 tail call void @dummy2() 598 br label %if.end3 599 600if.end3: 601 ret void 602} 603 604 605define void @func24(i64 %a, i64 %b) { 606; CHECK-LABEL: @func24 607; CHECK: cmp 608; CHECK-NOT: cmp 609; CHECK: blr 610entry: 611 %cmp = icmp ult i64 %b, %a 612 br i1 %cmp, label %if.then, label %if.else 613 614if.then: 615 tail call void @dummy1() 616 br label %if.end3 617 618if.else: 619 %cmp1 = icmp eq i64 %a, %b 620 br i1 %cmp1, label %if.then2, label %if.end3 621 622if.then2: 623 tail call void @dummy2() 624 br label %if.end3 625 626if.end3: 627 ret void 628} 629 630 631define void @func25(i64 %a, i64 %b) { 632; CHECK-LABEL: @func25 633; CHECK: cmp 634; CHECK-NOT: cmp 635; CHECK: blr 636entry: 637 %cmp = icmp slt i64 %b, %a 638 br i1 %cmp, label %if.then, label %if.else, !prof !1 639 640if.then: 641 tail call void @dummy1() 642 br label %if.end6 643 644if.else: 645 %cmp2 = icmp eq i64 %a, %b 646 br i1 %cmp2, label %if.then4, label %if.else5 647 648if.then4: 649 tail call void @dummy2() 650 br label %if.end6 651 652if.else5: 653 tail call void @dummy3() 654 br label %if.end6 655 656if.end6: 657 ret void 658} 659 660 661define void @func26(i32 signext %a) { 662; CHECK-LABEL: @func26 663; CHECK: cmp 664; CHECK-NOT: cmp 665; CHECK: blr 666entry: 667 %cmp = icmp sgt i32 %a, 0 668 br i1 %cmp, label %if.then, label %if.else, !prof !2 669 670if.then: 671 tail call void @dummy1() 672 br label %if.end9 673 674if.else: 675 %cmp2 = icmp eq i32 %a, 0 676 br i1 %cmp2, label %if.then7, label %if.else8, !prof !2 677 678if.then7: 679 tail call void @dummy2() 680 br label %if.end9 681 682if.else8: 683 tail call void @dummy3() 684 br label %if.end9 685 686if.end9: 687 ret void 688} 689 690@g1 = external local_unnamed_addr global i32, align 4 691@g2 = external local_unnamed_addr global i32, align 4 692 693define void @func27(i32 signext %a) { 694; CHECK-LABEL: @func27 695; CHECK: cmp 696; CHECK: beq 697; CHECK-NOT: cmp 698; CHECK: bgelr 699; CHECK: blr 700entry: 701 %cmp = icmp eq i32 %a, 0 702 br i1 %cmp, label %if.end3.sink.split, label %if.else 703 704if.else: 705 %cmp1 = icmp slt i32 %a, 0 706 br i1 %cmp1, label %if.end3.sink.split, label %if.end 707 708if.end3.sink.split: 709 %g2.sink = phi i32* [ @g2, %if.else ], [ @g1, %entry ] 710 store i32 0, i32* %g2.sink, align 4 711 br label %if.end 712 713if.end: 714 ret void 715} 716 717; partially redundant case 718define void @func28(i32 signext %a) { 719; CHECK-LABEL: @func28 720; CHECK: cmplwi [[REG1:[0-9]+]], [[REG2:[0-9]+]] 721; CHECK: .[[LABEL2:[A-Z0-9_]+]]: 722; CHECK: cmpwi [[REG1]], [[REG2]] 723; CHECK: ble 0, .[[LABEL1:[A-Z0-9_]+]] 724; CHECK-NOT: cmp 725; CHECK: bne 0, .[[LABEL2]] 726; CHECK: bl dummy1 727; CHECK: b .[[LABEL2]] 728; CHECK: .[[LABEL1]]: 729; CHECK: blr 730entry: 731 br label %do.body 732 733do.body: 734 %a.addr.0 = phi i32 [ %a, %entry ], [ %call, %if.end ] 735 %cmp = icmp eq i32 %a.addr.0, 0 736 br i1 %cmp, label %if.then, label %if.end 737 738if.then: 739 tail call void @dummy1() #2 740 br label %if.end 741 742if.end: 743 %call = tail call signext i32 @func(i32 signext %a.addr.0) #2 744 %cmp1 = icmp sgt i32 %call, 0 745 br i1 %cmp1, label %do.body, label %do.end 746 747do.end: 748 ret void 749} 750 751define void @func29(i32 signext %a) { 752; We cannot merge two compares due to difference in sign extension behaviors. 753; equivalent C code example: 754; int a = .. ; 755; if (a == -1) dummy1(); 756; if (a == (uint16_t)-1) dummy2(); 757 758; CHECK-LABEL: @func29 759; CHECK: cmp 760; CHECK: cmp 761; CHECK: blr 762entry: 763 %cmp = icmp eq i32 %a, -1 764 br i1 %cmp, label %if.then, label %if.else 765 766if.then: 767 tail call void @dummy1() 768 br label %if.end3 769 770if.else: 771 %cmp1 = icmp eq i32 %a, 65535 772 br i1 %cmp1, label %if.then2, label %if.end3 773 774if.then2: 775 tail call void @dummy2() 776 br label %if.end3 777 778if.end3: 779 ret void 780} 781 782declare void @dummy1() 783declare void @dummy2() 784declare void @dummy3() 785declare signext i32 @func(i32 signext) 786 787!1 = !{!"branch_weights", i32 2000, i32 1} 788!2 = !{!"branch_weights", i32 1, i32 2000} 789