diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index dd789de49387..6b964cdf9eae 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -54,12 +54,9 @@ namespace llvm { class DominatorTree; class LoopInfo; class Loop; -class InductionDescriptor; class MDNode; class MemorySSAUpdater; class PHINode; -class PostDominatorTree; -class ScalarEvolution; class raw_ostream; template class DominatorTreeBase; template class LoopInfoBase; @@ -532,165 +529,6 @@ public: bool getIncomingAndBackEdge(BasicBlock *&Incoming, BasicBlock *&Backedge) const; - /// Below are some utilities to get loop bounds and induction variable, and - /// check if a given phinode is an auxiliary induction variable, as well as - /// checking if the loop is canonical. - /// - /// Here is an example: - /// \code - /// for (int i = lb; i < ub; i+=step) - /// - /// --- pseudo LLVMIR --- - /// beforeloop: - /// guardcmp = (lb < ub) - /// if (guardcmp) goto preheader; else goto afterloop - /// preheader: - /// loop: - /// i_1 = phi[{lb, preheader}, {i_2, latch}] - /// - /// i_2 = i_1 + step - /// latch: - /// cmp = (i_2 < ub) - /// if (cmp) goto loop - /// exit: - /// afterloop: - /// \endcode - /// - /// - getBounds - /// - getInitialIVValue --> lb - /// - getStepInst --> i_2 = i_1 + step - /// - getStepValue --> step - /// - getFinalIVValue --> ub - /// - getCanonicalPredicate --> '<' - /// - getDirection --> Increasing - /// - /// - getInductionVariable --> i_1 - /// - isAuxiliaryInductionVariable(x) --> true if x == i_1 - /// - isCanonical --> false - struct LoopBounds { - /// Return the LoopBounds object if - /// - the given \p IndVar is an induction variable - /// - the initial value of the induction variable can be found - /// - the step instruction of the induction variable can be found - /// - the final value of the induction variable can be found - /// - /// Else None. - static Optional getBounds(const Loop &L, PHINode &IndVar, - ScalarEvolution &SE); - - /// Get the initial value of the loop induction variable. - Value &getInitialIVValue() const { return InitialIVValue; } - - /// Get the instruction that updates the loop induction variable. - Instruction &getStepInst() const { return StepInst; } - - /// Get the step that the loop induction variable gets updated by in each - /// loop iteration. Return nullptr if not found. - Value *getStepValue() const { return StepValue; } - - /// Get the final value of the loop induction variable. - Value &getFinalIVValue() const { return FinalIVValue; } - - /// Return the canonical predicate for the latch compare instruction, if - /// able to be calcuated. Else BAD_ICMP_PREDICATE. - /// - /// A predicate is considered as canonical if requirements below are all - /// satisfied: - /// 1. The first successor of the latch branch is the loop header - /// If not, inverse the predicate. - /// 2. One of the operands of the latch comparison is StepInst - /// If not, and - /// - if the current calcuated predicate is not ne or eq, flip the - /// predicate. - /// - else if the loop is increasing, return slt - /// (notice that it is safe to change from ne or eq to sign compare) - /// - else if the loop is decreasing, return sgt - /// (notice that it is safe to change from ne or eq to sign compare) - /// - /// Here is an example when both (1) and (2) are not satisfied: - /// \code - /// loop.header: - /// %iv = phi [%initialiv, %loop.preheader], [%inc, %loop.header] - /// %inc = add %iv, %step - /// %cmp = slt %iv, %finaliv - /// br %cmp, %loop.exit, %loop.header - /// loop.exit: - /// \endcode - /// - The second successor of the latch branch is the loop header instead - /// of the first successor (slt -> sge) - /// - The first operand of the latch comparison (%cmp) is the IndVar (%iv) - /// instead of the StepInst (%inc) (sge -> sgt) - /// - /// The predicate would be sgt if both (1) and (2) are satisfied. - /// getCanonicalPredicate() returns sgt for this example. - /// Note: The IR is not changed. - ICmpInst::Predicate getCanonicalPredicate() const; - - /// An enum for the direction of the loop - /// - for (int i = 0; i < ub; ++i) --> Increasing - /// - for (int i = ub; i > 0; --i) --> Descresing - /// - for (int i = x; i != y; i+=z) --> Unknown - enum class Direction { Increasing, Decreasing, Unknown }; - - /// Get the direction of the loop. - Direction getDirection() const; - - private: - LoopBounds(const Loop &Loop, Value &I, Instruction &SI, Value *SV, Value &F, - ScalarEvolution &SE) - : L(Loop), InitialIVValue(I), StepInst(SI), StepValue(SV), - FinalIVValue(F), SE(SE) {} - - const Loop &L; - - // The initial value of the loop induction variable - Value &InitialIVValue; - - // The instruction that updates the loop induction variable - Instruction &StepInst; - - // The value that the loop induction variable gets updated by in each loop - // iteration - Value *StepValue; - - // The final value of the loop induction variable - Value &FinalIVValue; - - ScalarEvolution &SE; - }; - - /// Return the struct LoopBounds collected if all struct members are found, - /// else None. - Optional getBounds(ScalarEvolution &SE) const; - - /// Return the loop induction variable if found, else return nullptr. - /// An instruction is considered as the loop induction variable if - /// - it is an induction variable of the loop; and - /// - it is used to determine the condition of the branch in the loop latch - /// - /// Note: the induction variable doesn't need to be canonical, i.e. starts at - /// zero and increments by one each time through the loop (but it can be). - PHINode *getInductionVariable(ScalarEvolution &SE) const; - - /// Get the loop induction descriptor for the loop induction variable. Return - /// true if the loop induction variable is found. - bool getInductionDescriptor(ScalarEvolution &SE, - InductionDescriptor &IndDesc) const; - - /// Return true if the given PHINode \p AuxIndVar is - /// - in the loop header - /// - not used outside of the loop - /// - incremented by a loop invariant step for each loop iteration - /// - step instruction opcode should be add or sub - /// Note: auxiliary induction variable is not required to be used in the - /// conditional branch in the loop latch. (but it can be) - bool isAuxiliaryInductionVariable(PHINode &AuxIndVar, - ScalarEvolution &SE) const; - - /// Return true if the loop induction variable starts at zero and increments - /// by one each time through the loop. - bool isCanonical(ScalarEvolution &SE) const; - /// Return true if the Loop is in LCSSA form. bool isLCSSAForm(DominatorTree &DT) const; diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 50e08e994876..aa933d98f249 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -17,13 +17,10 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Analysis/IVDescriptors.h" #include "llvm/Analysis/LoopInfoImpl.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" -#include "llvm/Analysis/PostDominators.h" -#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/CFG.h" @@ -167,249 +164,6 @@ PHINode *Loop::getCanonicalInductionVariable() const { return nullptr; } -/// Return true if V1 and V2 have the same value ignoring bit width. -static bool isEqualIgnoreBitwidth(Value &V1, Value &V2, ScalarEvolution &SE) { - const SCEV *S1 = SE.getSCEV(&V1); - const SCEV *S2 = SE.getSCEV(&V2); - Type *WiderType = SE.getWiderType(S1->getType(), S2->getType()); - S1 = SE.getNoopOrAnyExtend(S1, WiderType); - S2 = SE.getNoopOrAnyExtend(S2, WiderType); - return SE.getMinusSCEV(S1, S2)->isZero(); -} - -/// Get the latch condition instruction. -static ICmpInst *getLatchCmpInst(const Loop &L) { - if (BasicBlock *Latch = L.getLoopLatch()) - if (BranchInst *BI = dyn_cast_or_null(Latch->getTerminator())) - if (BI->isConditional()) - return dyn_cast(BI->getCondition()); - - return nullptr; -} - -/// Return the final value of the loop induction variable if found. -static Value *findFinalIVValue(const Loop &L, const PHINode &IndVar, - const Instruction &StepInst) { - ICmpInst *LatchCmpInst = getLatchCmpInst(L); - if (!LatchCmpInst) - return nullptr; - - Value *Op0 = LatchCmpInst->getOperand(0); - Value *Op1 = LatchCmpInst->getOperand(1); - if (Op0 == &IndVar || Op0 == &StepInst) - return Op1; - - if (Op1 == &IndVar || Op1 == &StepInst) - return Op0; - - return nullptr; -} - -Optional Loop::LoopBounds::getBounds(const Loop &L, - PHINode &IndVar, - ScalarEvolution &SE) { - InductionDescriptor IndDesc; - if (!InductionDescriptor::isInductionPHI(&IndVar, &L, &SE, IndDesc)) - return None; - - Value *InitialIVValue = IndDesc.getStartValue(); - Instruction *StepInst = IndDesc.getInductionBinOp(); - if (!InitialIVValue || !StepInst) - return None; - - const SCEV *Step = IndDesc.getStep(); - Value *StepInstOp1 = StepInst->getOperand(1); - Value *StepInstOp0 = StepInst->getOperand(0); - Value *StepValue = nullptr; - if (SE.getSCEV(StepInstOp1) == Step) - StepValue = StepInstOp1; - else if (SE.getSCEV(StepInstOp0) == Step) - StepValue = StepInstOp0; - - Value *FinalIVValue = findFinalIVValue(L, IndVar, *StepInst); - if (!FinalIVValue) - return None; - - return LoopBounds(L, *InitialIVValue, *StepInst, StepValue, *FinalIVValue, - SE); -} - -using Direction = Loop::LoopBounds::Direction; - -ICmpInst::Predicate Loop::LoopBounds::getCanonicalPredicate() const { - BasicBlock *Latch = L.getLoopLatch(); - assert(Latch && "Expecting valid latch"); - - BranchInst *BI = dyn_cast_or_null(Latch->getTerminator()); - assert(BI && BI->isConditional() && "Expecting conditional latch branch"); - - ICmpInst *LatchCmpInst = dyn_cast(BI->getCondition()); - assert(LatchCmpInst && - "Expecting the latch compare instruction to be a CmpInst"); - - // Need to inverse the predicate when first successor is not the loop - // header - ICmpInst::Predicate Pred = (BI->getSuccessor(0) == L.getHeader()) - ? LatchCmpInst->getPredicate() - : LatchCmpInst->getInversePredicate(); - - if (LatchCmpInst->getOperand(0) == &getFinalIVValue()) - Pred = ICmpInst::getSwappedPredicate(Pred); - - // Need to flip strictness of the predicate when the latch compare instruction - // is not using StepInst - if (LatchCmpInst->getOperand(0) == &getStepInst() || - LatchCmpInst->getOperand(1) == &getStepInst()) - return Pred; - - // Cannot flip strictness of NE and EQ - if (Pred != ICmpInst::ICMP_NE && Pred != ICmpInst::ICMP_EQ) - return ICmpInst::getFlippedStrictnessPredicate(Pred); - - Direction D = getDirection(); - if (D == Direction::Increasing) - return ICmpInst::ICMP_SLT; - - if (D == Direction::Decreasing) - return ICmpInst::ICMP_SGT; - - // If cannot determine the direction, then unable to find the canonical - // predicate - return ICmpInst::BAD_ICMP_PREDICATE; -} - -Direction Loop::LoopBounds::getDirection() const { - if (const SCEVAddRecExpr *StepAddRecExpr = - dyn_cast(SE.getSCEV(&getStepInst()))) - if (const SCEV *StepRecur = StepAddRecExpr->getStepRecurrence(SE)) { - if (SE.isKnownPositive(StepRecur)) - return Direction::Increasing; - if (SE.isKnownNegative(StepRecur)) - return Direction::Decreasing; - } - - return Direction::Unknown; -} - -Optional Loop::getBounds(ScalarEvolution &SE) const { - if (PHINode *IndVar = getInductionVariable(SE)) - return LoopBounds::getBounds(*this, *IndVar, SE); - - return None; -} - -PHINode *Loop::getInductionVariable(ScalarEvolution &SE) const { - if (!isLoopSimplifyForm()) - return nullptr; - - BasicBlock *Header = getHeader(); - assert(Header && "Expected a valid loop header"); - BasicBlock *Latch = getLoopLatch(); - assert(Latch && "Expected a valid loop latch"); - ICmpInst *CmpInst = getLatchCmpInst(*this); - if (!CmpInst) - return nullptr; - - // case 1: - // IndVar = phi[{InitialValue, preheader}, {StepInst, latch}] - // StepInst = IndVar + step - // cmp = StepInst < FinalValue - Instruction *LatchCmpOp0 = dyn_cast(CmpInst->getOperand(0)); - Instruction *LatchCmpOp1 = dyn_cast(CmpInst->getOperand(1)); - // Loop over all of the PHI nodes in loop header, store the PHI node that has - // incoming value from latch equals to the StepInst - BinaryOperator *StepInst = nullptr; - PHINode *IndVar = nullptr; - for (PHINode &PN : Header->phis()) { - Value *IncomingValue = PN.getIncomingValueForBlock(Latch); - assert(IncomingValue && "Expecting valid incoming value from latch"); - if (IncomingValue == LatchCmpOp0 || IncomingValue == LatchCmpOp1) { - IndVar = &PN; - StepInst = dyn_cast(IncomingValue); - if (StepInst) - if (isEqualIgnoreBitwidth(*StepInst->getOperand(0), *IndVar, SE) || - isEqualIgnoreBitwidth(*StepInst->getOperand(1), *IndVar, SE)) - return IndVar; - } - } - - // case 2: - // IndVar = phi[{InitialValue, preheader}, {StepInst, latch}] - // StepInst = IndVar + step - // cmp = IndVar < FinalValue - for (Value *Op : CmpInst->operands()) { - PHINode *IndVar = dyn_cast(Op); - if (!IndVar) - continue; - - if (IndVar->getParent() != Header) - continue; - - Value *IncomingValue = IndVar->getIncomingValueForBlock(Latch); - assert(IncomingValue && "Expecting valid incoming value from latch"); - StepInst = dyn_cast(IncomingValue); - if (StepInst) - if (StepInst->getOperand(0) == IndVar || - StepInst->getOperand(1) == IndVar) - return IndVar; - } - - return nullptr; -} - -bool Loop::getInductionDescriptor(ScalarEvolution &SE, - InductionDescriptor &IndDesc) const { - if (PHINode *IndVar = getInductionVariable(SE)) - return InductionDescriptor::isInductionPHI(IndVar, this, &SE, IndDesc); - - return false; -} - -bool Loop::isAuxiliaryInductionVariable(PHINode &AuxIndVar, - ScalarEvolution &SE) const { - // Located in the loop header - BasicBlock *Header = getHeader(); - if (AuxIndVar.getParent() != Header) - return false; - - // No uses outside of the loop - for (User *U : AuxIndVar.users()) - if (const Instruction *I = dyn_cast(U)) - if (!contains(I)) - return false; - - InductionDescriptor IndDesc; - if (!InductionDescriptor::isInductionPHI(&AuxIndVar, this, &SE, IndDesc)) - return false; - - // The step instruction opcode should be add or sub. - if (IndDesc.getInductionOpcode() != Instruction::Add && - IndDesc.getInductionOpcode() != Instruction::Sub) - return false; - - // Incremented by a loop invariant step for each loop iteration - return SE.isLoopInvariant(IndDesc.getStep(), this); -} - -bool Loop::isCanonical(ScalarEvolution &SE) const { - InductionDescriptor IndDesc; - if (!getInductionDescriptor(SE, IndDesc)) - return false; - - ConstantInt *Init = dyn_cast_or_null(IndDesc.getStartValue()); - if (!Init || !Init->isZero()) - return false; - - if (IndDesc.getInductionOpcode() != Instruction::Add) - return false; - - ConstantInt *Step = IndDesc.getConstIntStepValue(); - if (!Step || !Step->isOne()) - return false; - - return true; -} - // Check that 'BB' doesn't have any uses outside of the 'L' static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB, DominatorTree &DT) { diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index ad7113cb0e9a..bec5af584f43 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -292,6 +292,33 @@ static LoopVector populateWorklist(Loop &L) { return LoopList; } +static PHINode *getInductionVariable(Loop *L, ScalarEvolution *SE) { + PHINode *InnerIndexVar = L->getCanonicalInductionVariable(); + if (InnerIndexVar) + return InnerIndexVar; + if (L->getLoopLatch() == nullptr || L->getLoopPredecessor() == nullptr) + return nullptr; + for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) { + PHINode *PhiVar = cast(I); + Type *PhiTy = PhiVar->getType(); + if (!PhiTy->isIntegerTy() && !PhiTy->isFloatingPointTy() && + !PhiTy->isPointerTy()) + return nullptr; + const SCEVAddRecExpr *AddRec = + dyn_cast(SE->getSCEV(PhiVar)); + if (!AddRec || !AddRec->isAffine()) + continue; + const SCEV *Step = AddRec->getStepRecurrence(*SE); + if (!isa(Step)) + continue; + // Found the induction variable. + // FIXME: Handle loops with more than one induction variable. Note that, + // currently, legality makes sure we have only one induction variable. + return PhiVar; + } + return nullptr; +} + namespace { /// LoopInterchangeLegality checks if it is legal to interchange the loop. @@ -1200,7 +1227,7 @@ bool LoopInterchangeTransform::transform() { if (InnerLoop->getSubLoops().empty()) { BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader(); LLVM_DEBUG(dbgs() << "Calling Split Inner Loop\n"); - PHINode *InductionPHI = InnerLoop->getInductionVariable(*SE); + PHINode *InductionPHI = getInductionVariable(InnerLoop, SE); if (!InductionPHI) { LLVM_DEBUG(dbgs() << "Failed to find the point to split loop latch \n"); return false; diff --git a/llvm/unittests/Analysis/LoopInfoTest.cpp b/llvm/unittests/Analysis/LoopInfoTest.cpp index 005e1dc405b7..483532a18752 100644 --- a/llvm/unittests/Analysis/LoopInfoTest.cpp +++ b/llvm/unittests/Analysis/LoopInfoTest.cpp @@ -7,10 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/AssumptionCache.h" -#include "llvm/Analysis/PostDominators.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/Dominators.h" #include "llvm/Support/SourceMgr.h" @@ -30,26 +26,6 @@ runWithLoopInfo(Module &M, StringRef FuncName, Test(*F, LI); } -/// Build the loop info and scalar evolution for the function and run the Test. -static void runWithLoopInfoPlus( - Module &M, StringRef FuncName, - function_ref - Test) { - auto *F = M.getFunction(FuncName); - ASSERT_NE(F, nullptr) << "Could not find " << FuncName; - - TargetLibraryInfoImpl TLII; - TargetLibraryInfo TLI(TLII); - AssumptionCache AC(*F); - DominatorTree DT(*F); - LoopInfo LI(DT); - ScalarEvolution SE(*F, TLI, AC, DT, LI); - - PostDominatorTree PDT(*F); - Test(*F, LI, SE, PDT); -} - static std::unique_ptr makeLLVMModule(LLVMContext &Context, const char *ModuleStr) { SMDiagnostic Err; @@ -234,879 +210,3 @@ TEST(LoopInfoTest, PreorderTraversals) { EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]); EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]); } - -TEST(LoopInfoTest, CanonicalLoop) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopWithInverseGuardSuccs) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp sge i32 0, %ub\n" - " br i1 %guardcmp, label %for.end, label %for.preheader\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopWithSwappedGuardCmp) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp sgt i32 %ub, 0\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp sge i32 %inc, %ub\n" - " br i1 %cmp, label %for.exit, label %for.body\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopWithInverseLatchSuccs) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp sge i32 %inc, %ub\n" - " br i1 %cmp, label %for.exit, label %for.body\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopWithLatchCmpNE) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp ne i32 %i, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopWithGuardCmpSLE) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %ubPlusOne = add i32 %ub, 1\n" - " %guardcmp = icmp sle i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp ne i32 %i, %ubPlusOne\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ubPlusOne"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopNonConstantStep) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub, i32 %step) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = zext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, %step\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - EXPECT_EQ(Bounds->getStepValue()->getName(), "step"); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), Loop::LoopBounds::Direction::Unknown); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopUnsignedBounds) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp ult i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = zext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add i32 %i, 1\n" - " %cmp = icmp ult i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_ULT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, DecreasingLoop) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ %ub, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = sub nsw i32 %i, 1\n" - " %cmp = icmp sgt i32 %inc, 0\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - EXPECT_EQ(Bounds->getInitialIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_EQ(StepValue, nullptr); - ConstantInt *FinalIVValue = - dyn_cast(&Bounds->getFinalIVValue()); - EXPECT_TRUE(FinalIVValue && FinalIVValue->isZero()); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SGT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Decreasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, CannotFindDirection) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub, i32 %step) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, %step\n" - " %cmp = icmp ne i32 %i, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus(*M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - // - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - EXPECT_EQ(Bounds->getStepValue()->getName(), "step"); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), - ICmpInst::BAD_ICMP_PREDICATE); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Unknown); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, ZextIndVar) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %indvars.iv = phi i64 [ 0, %for.preheader ], [ %indvars.iv.next, %for.body ]\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n" - " %inc = add nsw i32 %i, 1\n" - " %wide.trip.count = zext i32 %ub to i64\n" - " %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n" - " br i1 %exitcond, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "indvars.iv.next"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "wide.trip.count"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_NE); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "indvars.iv"); - }); -} - -TEST(LoopInfoTest, UnguardedLoop) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First basic block is entry - skip it. - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, UnguardedLoopWithControlFlow) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub, i1 %cond) {\n" - "entry:\n" - " br i1 %cond, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, LoopNest) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.outer.preheader, label %for.end\n" - "for.outer.preheader:\n" - " br label %for.outer\n" - "for.outer:\n" - " %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]\n" - " br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch\n" - "for.inner.preheader:\n" - " br label %for.inner\n" - "for.inner:\n" - " %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.inner, label %for.inner.exit\n" - "for.inner.exit:\n" - " br label %for.outer.latch\n" - "for.outer.latch:\n" - " %inc.outer = add nsw i32 %j, 1\n" - " %cmp.outer = icmp slt i32 %inc.outer, %ub\n" - " br i1 %cmp.outer, label %for.outer, label %for.outer.exit\n" - "for.outer.exit:\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.outer.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.outer"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc.outer"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "j"); - - // Next two basic blocks are for.outer and for.inner.preheader - skip - // them. - ++FI; - Header = &*(++FI); - assert(Header->getName() == "for.inner"); - L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional InnerBounds = L->getBounds(SE); - EXPECT_NE(InnerBounds, None); - InitialIVValue = - dyn_cast(&InnerBounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(InnerBounds->getStepInst().getName(), "inc"); - StepValue = dyn_cast_or_null(InnerBounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(InnerBounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(InnerBounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(InnerBounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - }); -} - -TEST(LoopInfoTest, AuxiliaryIV) { - const char *ModuleStr = - "define void @foo(i32* %A, i32 %ub) {\n" - "entry:\n" - " %guardcmp = icmp slt i32 0, %ub\n" - " br i1 %guardcmp, label %for.preheader, label %for.end\n" - "for.preheader:\n" - " br label %for.body\n" - "for.body:\n" - " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n" - " %aux = phi i32 [ 0, %for.preheader ], [ %auxinc, %for.body ]\n" - " %loopvariant = phi i32 [ 0, %for.preheader ], [ %loopvariantinc, %for.body ]\n" - " %usedoutside = phi i32 [ 0, %for.preheader ], [ %usedoutsideinc, %for.body ]\n" - " %mulopcode = phi i32 [ 0, %for.preheader ], [ %mulopcodeinc, %for.body ]\n" - " %idxprom = sext i32 %i to i64\n" - " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n" - " store i32 %i, i32* %arrayidx, align 4\n" - " %mulopcodeinc = mul nsw i32 %mulopcode, 5\n" - " %usedoutsideinc = add nsw i32 %usedoutside, 5\n" - " %loopvariantinc = add nsw i32 %loopvariant, %i\n" - " %auxinc = add nsw i32 %aux, 5\n" - " %inc = add nsw i32 %i, 1\n" - " %cmp = icmp slt i32 %inc, %ub\n" - " br i1 %cmp, label %for.body, label %for.exit\n" - "for.exit:\n" - " %lcssa = phi i32 [ %usedoutside, %for.body ]\n" - " br label %for.end\n" - "for.end:\n" - " ret void\n" - "}\n"; - - // Parse the module. - LLVMContext Context; - std::unique_ptr M = makeLLVMModule(Context, ModuleStr); - - runWithLoopInfoPlus( - *M, "foo", - [&](Function &F, LoopInfo &LI, ScalarEvolution &SE, - PostDominatorTree &PDT) { - Function::iterator FI = F.begin(); - // First two basic block are entry and for.preheader - skip them. - ++FI; - BasicBlock *Header = &*(++FI); - assert(Header->getName() == "for.body"); - Loop *L = LI.getLoopFor(Header); - EXPECT_NE(L, nullptr); - - Optional Bounds = L->getBounds(SE); - EXPECT_NE(Bounds, None); - ConstantInt *InitialIVValue = - dyn_cast(&Bounds->getInitialIVValue()); - EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero()); - EXPECT_EQ(Bounds->getStepInst().getName(), "inc"); - ConstantInt *StepValue = - dyn_cast_or_null(Bounds->getStepValue()); - EXPECT_TRUE(StepValue && StepValue->isOne()); - EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub"); - EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT); - EXPECT_EQ(Bounds->getDirection(), - Loop::LoopBounds::Direction::Increasing); - EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i"); - BasicBlock::iterator II = Header->begin(); - PHINode &Instruction_i = cast(*(II)); - EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_i, SE)); - PHINode &Instruction_aux = cast(*(++II)); - EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_aux, SE)); - PHINode &Instruction_loopvariant = cast(*(++II)); - EXPECT_FALSE( - L->isAuxiliaryInductionVariable(Instruction_loopvariant, SE)); - PHINode &Instruction_usedoutside = cast(*(++II)); - EXPECT_FALSE( - L->isAuxiliaryInductionVariable(Instruction_usedoutside, SE)); - PHINode &Instruction_mulopcode = cast(*(++II)); - EXPECT_FALSE( - L->isAuxiliaryInductionVariable(Instruction_mulopcode, SE)); - }); -}