diff options
| author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-07 23:59:07 +0000 | 
|---|---|---|
| committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-02-07 23:59:07 +0000 | 
| commit | ec892139bda15b4e86d953d8fd3e70ffca83902d (patch) | |
| tree | ccfef68f851d6928238ee2bf5d05c5ae0e2bfd85 /llvm/lib/Transforms/Scalar | |
| parent | 165088aa5c1c694cd4085cda14f9df254dd7d442 (diff) | |
| download | bcm5719-llvm-ec892139bda15b4e86d953d8fd3e70ffca83902d.tar.gz bcm5719-llvm-ec892139bda15b4e86d953d8fd3e70ffca83902d.zip  | |
[IRCE] Add a missing invariant check
Currently IRCE relies on the loops it transforms to be (semantically) of
the form:
  for (i = START; i < END; i++)
    ...
or
  for (i = START; i > END; i--)
    ...
However, we were not verifying the presence of the START < END entry
check (i.e. check before the first iteration).  We were only verifying
that the backedge was guarded by (i + 1) < END.
Usually this would work "fine" since (especially in Java) most loops do
actually have the START < END check, but of course that is not
guaranteed.
llvm-svn: 294375
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp | 44 | 
1 files changed, 39 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index 8e81541c233..85db6e5e110 100644 --- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -446,6 +446,15 @@ struct LoopStructure {    BasicBlock *LatchExit;    unsigned LatchBrExitIdx; +  // The loop represented by this instance of LoopStructure is semantically +  // equivalent to: +  // +  // intN_ty inc = IndVarIncreasing ? 1 : -1; +  // pred_ty predicate = IndVarIncreasing ? ICMP_SLT : ICMP_SGT; +  // +  // for (intN_ty iv = IndVarStart; predicate(iv, LoopExitAt); iv = IndVarNext) +  //   ... body ... +    Value *IndVarNext;    Value *IndVarStart;    Value *LoopExitAt; @@ -789,6 +798,10 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE, BranchProbabilityInfo &BP      return None;    } +  const SCEV *StartNext = IndVarNext->getStart(); +  const SCEV *Addend = SE.getNegativeSCEV(IndVarNext->getStepRecurrence(SE)); +  const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend); +    ConstantInt *One = ConstantInt::get(IndVarTy, 1);    // TODO: generalize the predicates here to also match their unsigned variants.    if (IsIncreasing) { @@ -809,10 +822,22 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE, BranchProbabilityInfo &BP          return None;        } +      if (!SE.isLoopEntryGuardedByCond( +              &L, CmpInst::ICMP_SLT, IndVarStart, +              SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType())))) { +        FailureReason = "Induction variable start not bounded by upper limit"; +        return None; +      } +        IRBuilder<> B(Preheader->getTerminator());        RightValue = B.CreateAdd(RightValue, One); +    } else { +      if (!SE.isLoopEntryGuardedByCond(&L, CmpInst::ICMP_SLT, IndVarStart, +                                       RightSCEV)) { +        FailureReason = "Induction variable start not bounded by upper limit"; +        return None; +      }      } -    } else {      bool FoundExpectedPred =          (Pred == ICmpInst::ICMP_SGT && LatchBrExitIdx == 1) || @@ -831,15 +856,24 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE, BranchProbabilityInfo &BP          return None;        } +      if (!SE.isLoopEntryGuardedByCond( +              &L, CmpInst::ICMP_SGT, IndVarStart, +              SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType())))) { +        FailureReason = "Induction variable start not bounded by lower limit"; +        return None; +      } +        IRBuilder<> B(Preheader->getTerminator());        RightValue = B.CreateSub(RightValue, One); +    } else { +      if (!SE.isLoopEntryGuardedByCond(&L, CmpInst::ICMP_SGT, IndVarStart, +                                       RightSCEV)) { +        FailureReason = "Induction variable start not bounded by lower limit"; +        return None; +      }      }    } -  const SCEV *StartNext = IndVarNext->getStart(); -  const SCEV *Addend = SE.getNegativeSCEV(IndVarNext->getStepRecurrence(SE)); -  const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend); -    BasicBlock *LatchExit = LatchBr->getSuccessor(LatchBrExitIdx);    assert(SE.getLoopDisposition(LatchCount, &L) ==  | 

