[llvm] r261958 - [LoopUnrollAnalyzer] Check that we're using SCEV for the same loop we're simulating.

Michael Zolotukhin via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 18:57:05 PST 2016


Author: mzolotukhin
Date: Thu Feb 25 20:57:05 2016
New Revision: 261958

URL: http://llvm.org/viewvc/llvm-project?rev=261958&view=rev
Log:
[LoopUnrollAnalyzer] Check that we're using SCEV for the same loop we're simulating.

Summary: Check that we're using SCEV for the same loop we're simulating. Otherwise, we might try to use the iteration number of the current loop in SCEV expressions for inner/outer loops IVs, which is clearly incorrect.

Reviewers: chandlerc, hfinkel

Subscribers: sanjoy, llvm-commits, mzolotukhin

Differential Revision: http://reviews.llvm.org/D17632

Modified:
    llvm/trunk/include/llvm/Analysis/LoopUnrollAnalyzer.h
    llvm/trunk/lib/Analysis/LoopUnrollAnalyzer.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
    llvm/trunk/unittests/Analysis/UnrollAnalyzer.cpp

Modified: llvm/trunk/include/llvm/Analysis/LoopUnrollAnalyzer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopUnrollAnalyzer.h?rev=261958&r1=261957&r2=261958&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LoopUnrollAnalyzer.h (original)
+++ llvm/trunk/include/llvm/Analysis/LoopUnrollAnalyzer.h Thu Feb 25 20:57:05 2016
@@ -48,8 +48,8 @@ class UnrolledInstAnalyzer : private Ins
 public:
   UnrolledInstAnalyzer(unsigned Iteration,
                        DenseMap<Value *, Constant *> &SimplifiedValues,
-                       ScalarEvolution &SE)
-      : SimplifiedValues(SimplifiedValues), SE(SE) {
+                       ScalarEvolution &SE, const Loop *L)
+      : SimplifiedValues(SimplifiedValues), SE(SE), L(L) {
       IterationNumber = SE.getConstant(APInt(64, Iteration));
   }
 
@@ -80,6 +80,7 @@ private:
   DenseMap<Value *, Constant *> &SimplifiedValues;
 
   ScalarEvolution &SE;
+  const Loop *L;
 
   bool simplifyInstWithSCEV(Instruction *I);
 

Modified: llvm/trunk/lib/Analysis/LoopUnrollAnalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopUnrollAnalyzer.cpp?rev=261958&r1=261957&r2=261958&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopUnrollAnalyzer.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopUnrollAnalyzer.cpp Thu Feb 25 20:57:05 2016
@@ -37,7 +37,7 @@ bool UnrolledInstAnalyzer::simplifyInstW
   }
 
   auto *AR = dyn_cast<SCEVAddRecExpr>(S);
-  if (!AR)
+  if (!AR || AR->getLoop() != L)
     return false;
 
   const SCEV *ValueAtIteration = AR->evaluateAtIteration(IterationNumber, SE);

Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=261958&r1=261957&r2=261958&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Thu Feb 25 20:57:05 2016
@@ -265,7 +265,7 @@ analyzeLoopUnrollCost(const Loop *L, uns
     while (!SimplifiedInputValues.empty())
       SimplifiedValues.insert(SimplifiedInputValues.pop_back_val());
 
-    UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, SE);
+    UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, SE, L);
 
     BBWorklist.clear();
     BBWorklist.insert(L->getHeader());

Modified: llvm/trunk/unittests/Analysis/UnrollAnalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/UnrollAnalyzer.cpp?rev=261958&r1=261957&r2=261958&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/UnrollAnalyzer.cpp (original)
+++ llvm/trunk/unittests/Analysis/UnrollAnalyzer.cpp Thu Feb 25 20:57:05 2016
@@ -38,7 +38,7 @@ struct UnrollAnalyzerTest : public Funct
     TripCount = SE->getSmallConstantTripCount(L, Exiting);
     for (unsigned Iteration = 0; Iteration < TripCount; Iteration++) {
       DenseMap<Value *, Constant *> SimplifiedValues;
-      UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, *SE);
+      UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, *SE, L);
       for (auto *BB : L->getBlocks())
         for (Instruction &I : *BB)
           Analyzer.visit(I);
@@ -124,6 +124,53 @@ TEST(UnrollAnalyzerTest, BasicSimplifica
   EXPECT_TRUE(I2 != SimplifiedValuesVector[TripCount - 1].end());
   EXPECT_TRUE(dyn_cast<ConstantInt>((*I2).second)->getZExtValue());
 }
+
+TEST(UnrollAnalyzerTest, OuterLoopSimplification) {
+  const char *ModuleStr =
+      "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
+      "define void @foo() {\n"
+      "entry:\n"
+      "  br label %outer.loop\n"
+      "outer.loop:\n"
+      "  %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.loop.latch ]\n"
+      "  br label %inner.loop\n"
+      "inner.loop:\n"
+      "  %iv.inner = phi i64 [ 0, %outer.loop ], [ %iv.inner.next, %inner.loop ]\n"
+      "  %iv.inner.next = add nuw nsw i64 %iv.inner, 1\n"
+      "  %exitcond.inner = icmp eq i64 %iv.inner.next, 1000\n"
+      "  br i1 %exitcond.inner, label %outer.loop.latch, label %inner.loop\n"
+      "outer.loop.latch:\n"
+      "  %iv.outer.next = add nuw nsw i64 %iv.outer, 1\n"
+      "  %exitcond.outer = icmp eq i64 %iv.outer.next, 40\n"
+      "  br i1 %exitcond.outer, label %exit, label %outer.loop\n"
+      "exit:\n"
+      "  ret void\n"
+      "}\n";
+
+  UnrollAnalyzerTest *P = new UnrollAnalyzerTest();
+  std::unique_ptr<Module> M = makeLLVMModule(P, ModuleStr);
+  legacy::PassManager Passes;
+  Passes.add(P);
+  Passes.run(*M);
+
+  Module::iterator MI = M->begin();
+  Function *F = &*MI++;
+  Function::iterator FI = F->begin();
+  FI++;
+  BasicBlock *Header = &*FI++;
+  BasicBlock *InnerBody = &*FI++;
+
+  BasicBlock::iterator BBI = Header->begin();
+  Instruction *Y1 = &*BBI++;
+  BBI = InnerBody->begin();
+  Instruction *Y2 = &*BBI++;
+  // Check that we can simplify IV of the outer loop, but can't simplify the IV
+  // of the inner loop if we only know the iteration number of the outer loop.
+  auto I1 = SimplifiedValuesVector[0].find(Y1);
+  EXPECT_TRUE(I1 != SimplifiedValuesVector[0].end());
+  auto I2 = SimplifiedValuesVector[0].find(Y2);
+  EXPECT_TRUE(I2 == SimplifiedValuesVector[0].end());
+}
 } // end namespace llvm
 
 INITIALIZE_PASS_BEGIN(UnrollAnalyzerTest, "unrollanalyzertestpass",




More information about the llvm-commits mailing list