<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>I submitted a speculative fix for this in rL366241, but I'd
      really appreciate someone familiar with the bot extracting IR so
      that I can confirm the diagnosis.  <br>
    </p>
    <p>Philip<br>
    </p>
    <div class="moz-cite-prefix">On 7/15/19 9:34 PM, Amara Emerson
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:4DB0C231-2392-4A69-A214-87EF9FFD8BA2@apple.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      Hi Philip,
      <div class=""><br class="">
      </div>
      <div class="">This commit looks like (from the assertion, I
        haven’t bisected it completely) it broke a green dragon ThinLTO
        stage2 bot: <a
          href="http://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/"
          class="" moz-do-not-send="true">http://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/</a></div>
      <div class=""><br class="">
      </div>
      <div class="">Could you take a look?</div>
      <div class=""><br class="">
      </div>
      <div class="">Amara<br class="">
        <div><br class="">
          <blockquote type="cite" class="">
            <div class="">On Jul 12, 2019, at 10:05 AM, Philip Reames
              via llvm-commits <<a
                href="mailto:llvm-commits@lists.llvm.org" class=""
                moz-do-not-send="true">llvm-commits@lists.llvm.org</a>>
              wrote:</div>
            <br class="Apple-interchange-newline">
            <div class="">
              <div class="">Author: reames<br class="">
                Date: Fri Jul 12 10:05:35 2019<br class="">
                New Revision: 365920<br class="">
                <br class="">
                URL: <a
                  href="http://llvm.org/viewvc/llvm-project?rev=365920&view=rev"
                  class="" moz-do-not-send="true">http://llvm.org/viewvc/llvm-project?rev=365920&view=rev</a><br
                  class="">
                Log:<br class="">
                [IndVars] Use exit count reasoning to discharge
                obviously untaken exits<br class="">
                <br class="">
                Continue in the spirit of D63618, and use exit count
                reasoning to prove away loop exits which can not be
                taken since the backedge taken count of the loop as a
                whole is provably less than the minimal BE count
                required to take this particular loop exit.<br class="">
                <br class="">
                As demonstrated in the newly added tests, this triggers
                in a number of cases where IndVars was previously unable
                to discharge obviously redundant exit tests. And some
                not so obvious ones.<br class="">
                <br class="">
                Differential Revision: <a
                  href="https://reviews.llvm.org/D63733" class=""
                  moz-do-not-send="true">https://reviews.llvm.org/D63733</a><br
                  class="">
                <br class="">
                <br class="">
                Modified:<br class="">
                   llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp<br
                  class="">
   llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll<br
                  class="">
                <br class="">
                Modified:
                llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp<br
                  class="">
                URL: <a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=365920&r1=365919&r2=365920&view=diff"
                  class="" moz-do-not-send="true">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=365920&r1=365919&r2=365920&view=diff</a><br
                  class="">
==============================================================================<br
                  class="">
                --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
                (original)<br class="">
                +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
                Fri Jul 12 10:05:35 2019<br class="">
                @@ -144,6 +144,7 @@ class IndVarSimplify {<br class="">
                  bool rewriteNonIntegerIVs(Loop *L);<br class="">
                <br class="">
                  bool simplifyAndExtend(Loop *L, SCEVExpander
                &Rewriter, LoopInfo *LI);<br class="">
                +  bool optimizeLoopExits(Loop *L);<br class="">
                <br class="">
                  bool canLoopBeDeleted(Loop *L,
                SmallVector<RewritePhi, 8> &RewritePhiSet);<br
                  class="">
                  bool rewriteLoopExitValues(Loop *L, SCEVExpander
                &Rewriter);<br class="">
                @@ -2623,6 +2624,112 @@ bool
                IndVarSimplify::sinkUnusedInvariant<br class="">
                  return MadeAnyChanges;<br class="">
                }<br class="">
                <br class="">
                +bool IndVarSimplify::optimizeLoopExits(Loop *L) {<br
                  class="">
                +  SmallVector<BasicBlock*, 16> ExitingBlocks;<br
                  class="">
                +  L->getExitingBlocks(ExitingBlocks);<br class="">
                +  BasicBlock * const Latch = L->getLoopLatch();<br
                  class="">
                +<br class="">
                +  // Form an expression for the maximum exit count
                possible for this loop. We<br class="">
                +  // merge the max and exact information to approximate
                a version of<br class="">
                +  // getMaxBackedgeTakenInfo which isn't restricted to
                just constants.<br class="">
                +  // TODO: factor this out as a version of
                getMaxBackedgeTakenCount which<br class="">
                +  // isn't guaranteed to return a constant.<br class="">
                +  SmallVector<const SCEV*, 4> ExitCounts;<br
                  class="">
                +  const SCEV *MaxConstEC =
                SE->getMaxBackedgeTakenCount(L);<br class="">
                +  if (!isa<SCEVCouldNotCompute>(MaxConstEC))<br
                  class="">
                +    ExitCounts.push_back(MaxConstEC);<br class="">
                +  for (BasicBlock *ExitingBB : ExitingBlocks) {<br
                  class="">
                +    const SCEV *ExitCount = SE->getExitCount(L,
                ExitingBB);<br class="">
                +    if (!isa<SCEVCouldNotCompute>(ExitCount)) {<br
                  class="">
                +      assert(DT->dominates(ExitingBB, Latch)
                &&<br class="">
                +             "We should only have known counts for
                exiting blocks that "<br class="">
                +             "dominate latch!");<br class="">
                +      ExitCounts.push_back(ExitCount);<br class="">
                +    }<br class="">
                +  }<br class="">
                +  if (ExitCounts.empty())<br class="">
                +    return false;<br class="">
                +  const SCEV *MaxExitCount =
                SE->getUMinFromMismatchedTypes(ExitCounts);<br
                  class="">
                +<br class="">
                +  bool Changed = false;<br class="">
                +  for (BasicBlock *ExitingBB : ExitingBlocks) {<br
                  class="">
                +    // If our exitting block exits multiple loops, we
                can only rewrite the<br class="">
                +    // innermost one.  Otherwise, we're changing how
                many times the innermost<br class="">
                +    // loop runs before it exits. <br class="">
                +    if (LI->getLoopFor(ExitingBB) != L)<br class="">
                +      continue;<br class="">
                +<br class="">
                +    // Can't rewrite non-branch yet.<br class="">
                +    BranchInst *BI =
                dyn_cast<BranchInst>(ExitingBB->getTerminator());<br
                  class="">
                +    if (!BI)<br class="">
                +      continue;<br class="">
                +<br class="">
                +    // If already constant, nothing to do.<br class="">
                +    if (isa<Constant>(BI->getCondition()))<br
                  class="">
                +      continue;<br class="">
                +    <br class="">
                +    const SCEV *ExitCount = SE->getExitCount(L,
                ExitingBB);<br class="">
                +    if (isa<SCEVCouldNotCompute>(ExitCount))<br
                  class="">
                +      continue;<br class="">
                +<br class="">
                +    // If we know we'd exit on the first iteration,
                rewrite the exit to<br class="">
                +    // reflect this.  This does not imply the loop must
                exit through this<br class="">
                +    // exit; there may be an earlier one taken on the
                first iteration.<br class="">
                +    // TODO: Given we know the backedge can't be taken,
                we should go ahead<br class="">
                +    // and break it.  Or at least, kill all the header
                phis and simplify.<br class="">
                +    if (ExitCount->isZero()) {<br class="">
                +      bool ExitIfTrue =
                !L->contains(*succ_begin(ExitingBB));<br class="">
                +      auto *OldCond = BI->getCondition();<br
                  class="">
                +      auto *NewCond = ExitIfTrue ?
                ConstantInt::getTrue(OldCond->getType()) :<br
                  class="">
                +        ConstantInt::getFalse(OldCond->getType());<br
                  class="">
                +      BI->setCondition(NewCond);<br class="">
                +      if (OldCond->use_empty())<br class="">
                +        DeadInsts.push_back(OldCond);<br class="">
                +      Changed = true;<br class="">
                +      continue;<br class="">
                +    }<br class="">
                +<br class="">
                +    // If we end up with a pointer exit count, bail.<br
                  class="">
                +    if (!ExitCount->getType()->isIntegerTy() ||<br
                  class="">
                +        !MaxExitCount->getType()->isIntegerTy())<br
                  class="">
                +      return false;<br class="">
                +    <br class="">
                +    Type *WiderType =<br class="">
                +      SE->getWiderType(MaxExitCount->getType(),
                ExitCount->getType());<br class="">
                +    ExitCount = SE->getNoopOrZeroExtend(ExitCount,
                WiderType);<br class="">
                +    MaxExitCount =
                SE->getNoopOrZeroExtend(MaxExitCount, WiderType);<br
                  class="">
                +    assert(MaxExitCount->getType() ==
                ExitCount->getType());<br class="">
                +    <br class="">
                +    // Can we prove that some other exit must be taken
                strictly before this<br class="">
                +    // one?  TODO: handle cases where ule is known, and
                equality is covered<br class="">
                +    // by a dominating exit<br class="">
                +    if (SE->isLoopEntryGuardedByCond(L,
                CmpInst::ICMP_ULT,<br class="">
                +                                     MaxExitCount,
                ExitCount)) {<br class="">
                +      bool ExitIfTrue =
                !L->contains(*succ_begin(ExitingBB));<br class="">
                +      auto *OldCond = BI->getCondition();<br
                  class="">
                +      auto *NewCond = ExitIfTrue ?
                ConstantInt::getFalse(OldCond->getType()) :<br
                  class="">
                +        ConstantInt::getTrue(OldCond->getType());<br
                  class="">
                +      BI->setCondition(NewCond);<br class="">
                +      if (OldCond->use_empty())<br class="">
                +        DeadInsts.push_back(OldCond);<br class="">
                +      Changed = true;<br class="">
                +      continue;<br class="">
                +    }<br class="">
                +<br class="">
                +    // TODO: If we can prove that the exiting iteration
                is equal to the exit<br class="">
                +    // count for this exit and that no previous exit
                oppurtunities exist within<br class="">
                +    // the loop, then we can discharge all other exits.
                 (May fall out of<br class="">
                +    // previous TODO.) <br class="">
                +    <br class="">
                +    // TODO: If we can't prove any relation between our
                exit count and the<br class="">
                +    // loops exit count, but taking this exit doesn't
                require actually running<br class="">
                +    // the loop (i.e. no side effects, no computed
                values used in exit), then<br class="">
                +    // we can replace the exit test with a loop
                invariant test which exits on<br class="">
                +    // the first iteration.  <br class="">
                +  }<br class="">
                +  return Changed;<br class="">
                +}<br class="">
                +<br class="">
//===----------------------------------------------------------------------===//<br
                  class="">
                //  IndVarSimplify driver. Manage several subpasses of
                IV simplification.<br class="">
//===----------------------------------------------------------------------===//<br
                  class="">
                @@ -2679,6 +2786,8 @@ bool IndVarSimplify::run(Loop *L)
                {<br class="">
                  // Eliminate redundant IV cycles.<br class="">
                  NumElimIV += Rewriter.replaceCongruentIVs(L, DT,
                DeadInsts);<br class="">
                <br class="">
                +  Changed |= optimizeLoopExits(L);<br class="">
                +<br class="">
                  // If we have a trip count expression, rewrite the
                loop's exit condition<br class="">
                  // using it.  <br class="">
                  if (!DisableLFTR) {<br class="">
                @@ -2702,23 +2811,7 @@ bool IndVarSimplify::run(Loop *L)
                {<br class="">
                      if (isa<SCEVCouldNotCompute>(ExitCount))<br
                  class="">
                        continue;<br class="">
                <br class="">
                -      // If we know we'd exit on the first iteration,
                rewrite the exit to<br class="">
                -      // reflect this.  This does not imply the loop
                must exit through this<br class="">
                -      // exit; there may be an earlier one taken on the
                first iteration.<br class="">
                -      // TODO: Given we know the backedge can't be
                taken, we should go ahead<br class="">
                -      // and break it.  Or at least, kill all the
                header phis and simplify.<br class="">
                -      if (ExitCount->isZero()) {<br class="">
                -        auto *BI =
                cast<BranchInst>(ExitingBB->getTerminator());<br
                  class="">
                -        bool ExitIfTrue =
                !L->contains(*succ_begin(ExitingBB));<br class="">
                -        auto *OldCond = BI->getCondition();<br
                  class="">
                -        auto *NewCond = ExitIfTrue ?
                ConstantInt::getTrue(OldCond->getType()) :<br
                  class="">
                -          ConstantInt::getFalse(OldCond->getType());<br
                  class="">
                -        BI->setCondition(NewCond);<br class="">
                -        if (OldCond->use_empty())<br class="">
                -          DeadInsts.push_back(OldCond);<br class="">
                -        Changed = true;<br class="">
                -        continue;<br class="">
                -      }<br class="">
                +      assert(!ExitCount->isZero() && "Should
                have been folded above");<br class="">
                <br class="">
                      PHINode *IndVar = FindLoopCounter(L, ExitingBB,
                ExitCount, SE, DT);<br class="">
                      if (!IndVar)<br class="">
                <br class="">
                Modified:
                llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll<br
                  class="">
                URL: <a
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll?rev=365920&r1=365919&r2=365920&view=diff"
                  class="" moz-do-not-send="true">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll?rev=365920&r1=365919&r2=365920&view=diff</a><br
                  class="">
==============================================================================<br
                  class="">
                ---
                llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll
                (original)<br class="">
                +++
                llvm/trunk/test/Transforms/IndVarSimplify/eliminate-exit.ll
                Fri Jul 12 10:05:35 2019<br class="">
                @@ -15,8 +15,7 @@ define void @ult(i64 %n, i64 %m) {<br
                  class="">
                ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label
                [[EXIT_LOOPEXIT:%.*]]<br class="">
                ; CHECK:       latch:<br class="">
                ; CHECK-NEXT:    call void @side_effect()<br class="">
                -; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]],
                [[M]]<br class="">
                -; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label
                [[EXIT_LOOPEXIT]]<br class="">
                +; CHECK-NEXT:    br i1 true, label [[LOOP]], label
                [[EXIT_LOOPEXIT]]<br class="">
                ; CHECK:       exit.loopexit:<br class="">
                ; CHECK-NEXT:    br label [[EXIT]]<br class="">
                ; CHECK:       exit:<br class="">
                @@ -48,8 +47,7 @@ define void @ugt(i64 %n, i64 %m) {<br
                  class="">
                ; CHECK:       loop:<br class="">
                ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]],
                [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]<br class="">
                ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1<br
                  class="">
                -; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]],
                [[N]]<br class="">
                -; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label
                [[EXIT_LOOPEXIT:%.*]]<br class="">
                +; CHECK-NEXT:    br i1 true, label [[LATCH]], label
                [[EXIT_LOOPEXIT:%.*]]<br class="">
                ; CHECK:       latch:<br class="">
                ; CHECK-NEXT:    call void @side_effect()<br class="">
                ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]],
                [[M]]<br class="">
                @@ -160,9 +158,7 @@ define void @ult_const_max(i64 %n) {<br
                  class="">
                ; CHECK:       loop:<br class="">
                ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]],
                [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]<br class="">
                ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1<br
                  class="">
                -; CHECK-NEXT:    [[UDIV:%.*]] = udiv i64 [[IV]], 10<br
                  class="">
                -; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[UDIV]],
                2<br class="">
                -; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label
                [[EXIT_LOOPEXIT:%.*]]<br class="">
                +; CHECK-NEXT:    br i1 true, label [[LATCH]], label
                [[EXIT_LOOPEXIT:%.*]]<br class="">
                ; CHECK:       latch:<br class="">
                ; CHECK-NEXT:    call void @side_effect()<br class="">
                ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]],
                [[N]]<br class="">
                <br class="">
                <br class="">
                _______________________________________________<br
                  class="">
                llvm-commits mailing list<br class="">
                <a href="mailto:llvm-commits@lists.llvm.org" class=""
                  moz-do-not-send="true">llvm-commits@lists.llvm.org</a><br
                  class="">
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="">
              </div>
            </div>
          </blockquote>
        </div>
        <br class="">
      </div>
    </blockquote>
  </body>
</html>