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