[PATCH] D66529: [LOOPGUARD] Disable loop with multiple loop exiting blocks.

Whitney Tsang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 10:34:32 PDT 2019


Whitney updated this revision to Diff 216428.
Whitney added a comment.

Add a test case with multiple loop exiting blocks.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66529/new/

https://reviews.llvm.org/D66529

Files:
  llvm/lib/Analysis/LoopInfo.cpp
  llvm/unittests/Analysis/LoopInfoTest.cpp


Index: llvm/unittests/Analysis/LoopInfoTest.cpp
===================================================================
--- llvm/unittests/Analysis/LoopInfoTest.cpp
+++ llvm/unittests/Analysis/LoopInfoTest.cpp
@@ -868,6 +868,64 @@
       });
 }
 
+TEST(LoopInfoTest, MultiExitingLoop) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub, i1 %cond) {\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.1 ]\n"
+      "  br i1 %cond, label %for.body.1, label %for.exit\n"
+      "for.body.1:\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) {
+        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");
+        EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
+        EXPECT_FALSE(L->isGuarded());
+      });
+}
+
 TEST(LoopInfoTest, UnguardedLoop) {
   const char *ModuleStr =
       "define void @foo(i32* %A, i32 %ub) {\n"
Index: llvm/lib/Analysis/LoopInfo.cpp
===================================================================
--- llvm/lib/Analysis/LoopInfo.cpp
+++ llvm/lib/Analysis/LoopInfo.cpp
@@ -367,6 +367,10 @@
          "Expecting a loop with valid preheader and latch");
   assert(isLoopExiting(Latch) && "Only valid for rotated loop");
 
+  BasicBlock *Exiting = getExitingBlock();
+  if (!Exiting)
+    return nullptr;
+
   Instruction *LatchTI = Latch->getTerminator();
   if (!LatchTI || LatchTI->getNumSuccessors() != 2)
     return nullptr;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66529.216428.patch
Type: text/x-patch
Size: 3216 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190821/7ff823eb/attachment.bin>


More information about the llvm-commits mailing list