llvm.org GIT mirror llvm / 28bea3d
Generalize icmp matching in IndVars' eliminateTrunc We were only matching RHS being a loop invariant value, not the inverse. Since there's nothing which appears to canonicalize loop invariant values to RHS, this means we missed cases. Differential Revision: https://reviews.llvm.org/D63112 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363108 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 3 months ago
2 changed file(s) with 119 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
520520 if (isa(U) &&
521521 !DT->isReachableFromEntry(cast(U)->getParent()))
522522 continue;
523 if (ICmpInst *ICI = dyn_cast(U)) {
524 if (ICI->getOperand(0) == TI && L->isLoopInvariant(ICI->getOperand(1))) {
525 assert(L->contains(ICI->getParent()) && "LCSSA form broken?");
526 // If we cannot get rid of trunc, bail.
527 if (ICI->isSigned() && !DoesSExtCollapse)
528 return false;
529 if (ICI->isUnsigned() && !DoesZExtCollapse)
530 return false;
531 // For equality, either signed or unsigned works.
532 ICmpUsers.push_back(ICI);
533 } else
534 return false;
535 } else
523 ICmpInst *ICI = dyn_cast(U);
524 if (!ICI) return false;
525 assert(L->contains(ICI->getParent()) && "LCSSA form broken?");
526 if (!(ICI->getOperand(0) == TI && L->isLoopInvariant(ICI->getOperand(1))) &&
527 !(ICI->getOperand(1) == TI && L->isLoopInvariant(ICI->getOperand(0))))
536528 return false;
529 // If we cannot get rid of trunc, bail.
530 if (ICI->isSigned() && !DoesSExtCollapse)
531 return false;
532 if (ICI->isUnsigned() && !DoesZExtCollapse)
533 return false;
534 // For equality, either signed or unsigned works.
535 ICmpUsers.push_back(ICI);
537536 }
538537
539538 auto CanUseZExt = [&](ICmpInst *ICI) {
556555 };
557556 // Replace all comparisons against trunc with comparisons against IV.
558557 for (auto *ICI : ICmpUsers) {
559 auto *Op1 = ICI->getOperand(1);
558 bool IsSwapped = L->isLoopInvariant(ICI->getOperand(0));
559 auto *Op1 = IsSwapped ? ICI->getOperand(0) : ICI->getOperand(1);
560560 Instruction *Ext = nullptr;
561561 // For signed/unsigned predicate, replace the old comparison with comparison
562562 // of immediate IV against sext/zext of the invariant argument. If we can
565565 // TODO: If we see a signed comparison which can be turned into unsigned,
566566 // we can do it here for canonicalization purposes.
567567 ICmpInst::Predicate Pred = ICI->getPredicate();
568 if (IsSwapped) Pred = ICmpInst::getSwappedPredicate(Pred);
568569 if (CanUseZExt(ICI)) {
569570 assert(DoesZExtCollapse && "Unprofitable zext?");
570571 Ext = new ZExtInst(Op1, IVTy, "zext", ICI);
560560 ret void
561561 }
562562
563 define void @test_13a(i32 %n) {
564 ;
565 ; CHECK-LABEL: @test_13a(
566 ; CHECK-NEXT: entry:
567 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
568 ; CHECK-NEXT: br label [[LOOP:%.*]]
569 ; CHECK: loop:
570 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
571 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
572 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV]], [[ZEXT]]
573 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
574 ; CHECK: exit:
575 ; CHECK-NEXT: ret void
576 ;
577 entry:
578 br label %loop
579 loop:
580 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
581 %iv.next = add nsw nuw i64 %iv, 2
582 %narrow.iv = trunc i64 %iv to i32
583 %cmp = icmp ne i32 1024, %narrow.iv
584 br i1 %cmp, label %loop, label %exit
585 exit:
586 ret void
587 }
588
589 define void @test_13b(i32 %n) {
590 ;
591 ; CHECK-LABEL: @test_13b(
592 ; CHECK-NEXT: entry:
593 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
594 ; CHECK-NEXT: br label [[LOOP:%.*]]
595 ; CHECK: loop:
596 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
597 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
598 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
599 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
600 ; CHECK: exit:
601 ; CHECK-NEXT: ret void
602 ;
603 entry:
604 br label %loop
605 loop:
606 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
607 %iv.next = add nsw nuw i64 %iv, 2
608 %narrow.iv = trunc i64 %iv to i32
609 %cmp = icmp ugt i32 1024, %narrow.iv
610 br i1 %cmp, label %loop, label %exit
611 exit:
612 ret void
613 }
614
615 define void @test_13c(i32 %n) {
616 ;
617 ; CHECK-LABEL: @test_13c(
618 ; CHECK-NEXT: entry:
619 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 1024 to i64
620 ; CHECK-NEXT: br label [[LOOP:%.*]]
621 ; CHECK: loop:
622 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
623 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
624 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
625 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
626 ; CHECK: exit:
627 ; CHECK-NEXT: ret void
628 ;
629 entry:
630 br label %loop
631 loop:
632 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
633 %iv.next = add nsw nuw i64 %iv, 2
634 %narrow.iv = trunc i64 %iv to i32
635 %cmp = icmp sgt i32 1024, %narrow.iv
636 br i1 %cmp, label %loop, label %exit
637 exit:
638 ret void
639 }
640
641 define void @test_13d(i32 %n) {
642 ;
643 ; CHECK-LABEL: @test_13d(
644 ; CHECK-NEXT: entry:
645 ; CHECK-NEXT: [[SEXT:%.*]] = sext i32 1024 to i64
646 ; CHECK-NEXT: br label [[LOOP:%.*]]
647 ; CHECK: loop:
648 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -20, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
649 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 2
650 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
651 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
652 ; CHECK: exit:
653 ; CHECK-NEXT: ret void
654 ;
655 entry:
656 br label %loop
657 loop:
658 %iv = phi i64 [ -20, %entry ], [ %iv.next, %loop ]
659 %iv.next = add nsw i64 %iv, 2
660 %narrow.iv = trunc i64 %iv to i32
661 %cmp = icmp sgt i32 1024, %narrow.iv
662 br i1 %cmp, label %loop, label %exit
663 exit:
664 ret void
665 }
666
563667 !0 = !{i32 0, i32 1000}