[llvm] r362615 - Revert "Title: [LOOPINFO] Extend Loop object to add utilities to get the loop"

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 5 10:10:41 PDT 2019


What's the reason for the revert? We usually mention that in the commit message,

Michael

Am Mi., 5. Juni 2019 um 11:21 Uhr schrieb Whitney Tsang via
llvm-commits <llvm-commits at lists.llvm.org>:
>
> Author: whitneyt
> Date: Wed Jun  5 08:32:56 2019
> New Revision: 362615
>
> URL: http://llvm.org/viewvc/llvm-project?rev=362615&view=rev
> Log:
> Revert "Title: [LOOPINFO] Extend Loop object to add utilities to get the loop"
>
> This reverts commit d34797dfc26c61cea19f45669a13ea572172ba34.
>
> Modified:
>     llvm/trunk/include/llvm/Analysis/LoopInfo.h
>     llvm/trunk/lib/Analysis/LoopInfo.cpp
>     llvm/trunk/unittests/Analysis/LoopInfoTest.cpp
>
> Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=362615&r1=362614&r2=362615&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
> +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Wed Jun  5 08:32:56 2019
> @@ -54,11 +54,9 @@ namespace llvm {
>  class DominatorTree;
>  class LoopInfo;
>  class Loop;
> -class InductionDescriptor;
>  class MDNode;
>  class MemorySSAUpdater;
>  class PHINode;
> -class ScalarEvolution;
>  class raw_ostream;
>  template <class N, bool IsPostDom> class DominatorTreeBase;
>  template <class N, class M> class LoopInfoBase;
> @@ -531,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)
> -  ///   <loop body>
> -  /// --- pseudo LLVMIR ---
> -  /// beforeloop:
> -  ///   guardcmp = (lb < ub)
> -  ///   if (guardcmp) goto preheader; else goto afterloop
> -  /// preheader:
> -  /// loop:
> -  ///   i_1 = phi[{lb, preheader}, {i_2, latch}]
> -  ///   <loop body>
> -  ///   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<Loop::LoopBounds> 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<LoopBounds> 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;
>
>
> Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=362615&r1=362614&r2=362615&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
> +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Wed Jun  5 08:32:56 2019
> @@ -17,12 +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/ScalarEvolutionExpressions.h"
>  #include "llvm/Analysis/ValueTracking.h"
>  #include "llvm/Config/llvm-config.h"
>  #include "llvm/IR/CFG.h"
> @@ -166,219 +164,6 @@ PHINode *Loop::getCanonicalInductionVari
>    return nullptr;
>  }
>
> -/// Get the latch condition instruction.
> -static ICmpInst *getLatchCmpInst(const Loop &L) {
> -  if (BasicBlock *Latch = L.getLoopLatch())
> -    if (BranchInst *BI = dyn_cast_or_null<BranchInst>(Latch->getTerminator()))
> -      if (BI->isConditional())
> -        return dyn_cast<ICmpInst>(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> 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<BranchInst>(Latch->getTerminator());
> -  assert(BI && BI->isConditional() && "Expecting conditional latch branch");
> -
> -  ICmpInst *LatchCmpInst = dyn_cast<ICmpInst>(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<SCEVAddRecExpr>(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::LoopBounds> 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");
> -  assert(getLoopLatch() && "Expected a valid loop latch");
> -  ICmpInst *CmpInst = getLatchCmpInst(*this);
> -  if (!CmpInst)
> -    return nullptr;
> -
> -  Instruction *LatchCmpOp0 = dyn_cast<Instruction>(CmpInst->getOperand(0));
> -  Instruction *LatchCmpOp1 = dyn_cast<Instruction>(CmpInst->getOperand(1));
> -
> -  for (PHINode &IndVar : Header->phis()) {
> -    InductionDescriptor IndDesc;
> -    if (!InductionDescriptor::isInductionPHI(&IndVar, this, &SE, IndDesc))
> -      continue;
> -
> -    Instruction *StepInst = IndDesc.getInductionBinOp();
> -
> -    // case 1:
> -    // IndVar = phi[{InitialValue, preheader}, {StepInst, latch}]
> -    // StepInst = IndVar + step
> -    // cmp = StepInst < FinalValue
> -    if (StepInst == LatchCmpOp0 || StepInst == LatchCmpOp1)
> -      return &IndVar;
> -
> -    // case 2:
> -    // IndVar = phi[{InitialValue, preheader}, {StepInst, latch}]
> -    // StepInst = IndVar + step
> -    // cmp = IndVar < FinalValue
> -    if (&IndVar == LatchCmpOp0 || &IndVar == LatchCmpOp1)
> -      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<Instruction>(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<ConstantInt>(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) {
>
> Modified: llvm/trunk/unittests/Analysis/LoopInfoTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/LoopInfoTest.cpp?rev=362615&r1=362614&r2=362615&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/Analysis/LoopInfoTest.cpp (original)
> +++ llvm/trunk/unittests/Analysis/LoopInfoTest.cpp Wed Jun  5 08:32:56 2019
> @@ -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 Fun
>    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<void(Function &F, LoopInfo &LI, ScalarEvolution &SE,
> -                      PostDominatorTree &PDT)>
> -        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<Module> 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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> 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<ConstantInt>(Bounds->getStepValue());
> -        EXPECT_EQ(StepValue, nullptr);
> -        ConstantInt *FinalIVValue =
> -            dyn_cast<ConstantInt>(&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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -                        EXPECT_NE(Bounds, None);
> -                        ConstantInt *InitialIVValue =
> -                            dyn_cast<ConstantInt>(&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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "indvars.iv.next");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc.outer");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<Loop::LoopBounds> InnerBounds = L->getBounds(SE);
> -        EXPECT_NE(InnerBounds, None);
> -        InitialIVValue =
> -            dyn_cast<ConstantInt>(&InnerBounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(InnerBounds->getStepInst().getName(), "inc");
> -        StepValue = dyn_cast_or_null<ConstantInt>(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<Module> 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<Loop::LoopBounds> Bounds = L->getBounds(SE);
> -        EXPECT_NE(Bounds, None);
> -        ConstantInt *InitialIVValue =
> -            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
> -        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
> -        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
> -        ConstantInt *StepValue =
> -            dyn_cast_or_null<ConstantInt>(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<PHINode>(*(II));
> -        EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_i, SE));
> -        PHINode &Instruction_aux = cast<PHINode>(*(++II));
> -        EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_aux, SE));
> -        PHINode &Instruction_loopvariant = cast<PHINode>(*(++II));
> -        EXPECT_FALSE(
> -            L->isAuxiliaryInductionVariable(Instruction_loopvariant, SE));
> -        PHINode &Instruction_usedoutside = cast<PHINode>(*(++II));
> -        EXPECT_FALSE(
> -            L->isAuxiliaryInductionVariable(Instruction_usedoutside, SE));
> -        PHINode &Instruction_mulopcode = cast<PHINode>(*(++II));
> -        EXPECT_FALSE(
> -            L->isAuxiliaryInductionVariable(Instruction_mulopcode, SE));
> -      });
> -}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list