[llvm] r373857 - [LOOPGUARD] Remove asserts in getLoopGuardBranch

Whitney Tsang via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 6 09:39:43 PDT 2019


Author: whitneyt
Date: Sun Oct  6 09:39:43 2019
New Revision: 373857

URL: http://llvm.org/viewvc/llvm-project?rev=373857&view=rev
Log:
[LOOPGUARD] Remove asserts in getLoopGuardBranch
Summary: The assertion in getLoopGuardBranch can be a 'return nullptr'
under if condition.
Authored By: DTharun
Reviewer: Whitney, fhahn
Reviewed By: Whitney, fhahn
Subscribers: fhahn, llvm-commits
Tag: LLVM
Differential Revision: https://reviews.llvm.org/D66084

Modified:
    llvm/trunk/lib/Analysis/LoopInfo.cpp
    llvm/trunk/unittests/Analysis/LoopInfoTest.cpp

Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=373857&r1=373856&r2=373857&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LoopInfo.cpp Sun Oct  6 09:39:43 2019
@@ -360,11 +360,17 @@ bool Loop::isAuxiliaryInductionVariable(
 }
 
 BranchInst *Loop::getLoopGuardBranch() const {
-  assert(isLoopSimplifyForm() && "Only valid for loop in simplify form");
+  if (!isLoopSimplifyForm())
+    return nullptr;
+
   BasicBlock *Preheader = getLoopPreheader();
-  assert(Preheader && getLoopLatch() &&
+  BasicBlock *Latch = getLoopLatch();
+  assert(Preheader && Latch &&
          "Expecting a loop with valid preheader and latch");
-  assert(isLoopExiting(getLoopLatch()) && "Only valid for rotated loop");
+
+  // Loop should be in rotate form.
+  if (!isLoopExiting(Latch))
+    return nullptr;
 
   // Disallow loops with more than one unique exit block, as we do not verify
   // that GuardOtherSucc post dominates all exit blocks.

Modified: llvm/trunk/unittests/Analysis/LoopInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/LoopInfoTest.cpp?rev=373857&r1=373856&r2=373857&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/LoopInfoTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/LoopInfoTest.cpp Sun Oct  6 09:39:43 2019
@@ -1272,6 +1272,91 @@ TEST(LoopInfoTest, AuxiliaryIV) {
       });
 }
 
+TEST(LoopInfoTest, LoopNotInSimplifyForm) {
+  const char *ModuleStr =
+      "define void @foo(i32 %n) {\n"
+      "entry:\n"
+      "  %guard.cmp = icmp sgt i32 %n, 0\n"
+      "  br i1 %guard.cmp, label %for.cond, label %for.end\n"
+      "for.cond:\n"
+      "  %i.0 = phi i32 [ 0, %entry ], [ %inc, %latch.1 ], [ %inc, %latch.2 ]\n"
+      "  %inc = add nsw i32 %i.0, 1\n"
+      "  %cmp = icmp slt i32 %i.0, %n\n"
+      "  br i1 %cmp, label %latch.1, label %for.end\n"
+      "latch.1:\n"
+      "  br i1 undef, label %for.cond, label %latch.2\n"
+      "latch.2:\n"
+      "  br label %for.cond\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
+    Function::iterator FI = F.begin();
+    // First basic block is entry - skip it.
+    BasicBlock *Header = &*(++FI);
+    assert(Header && "No header");
+    Loop *L = LI.getLoopFor(Header);
+    EXPECT_NE(L, nullptr);
+    EXPECT_FALSE(L->isLoopSimplifyForm());
+    // No loop guard because loop in not in simplify form.
+    EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
+    EXPECT_FALSE(L->isGuarded());
+  });
+}
+
+TEST(LoopInfoTest, LoopLatchNotExiting) {
+  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.latch, label %for.exit\n"
+      "for.latch:\n"
+      "  br 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) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        BasicBlock *Latch = &*(++FI);
+        assert(Header && "No header");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+        EXPECT_TRUE(L->isLoopSimplifyForm());
+        EXPECT_EQ(L->getLoopLatch(), Latch);
+        EXPECT_FALSE(L->isLoopExiting(Latch));
+        // No loop guard becuase loop is not exiting on latch.
+        EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
+        EXPECT_FALSE(L->isGuarded());
+      });
+}
+
 // Examine getUniqueExitBlocks/getUniqueNonLatchExitBlocks functions.
 TEST(LoopInfoTest, LoopUniqueExitBlocks) {
   const char *ModuleStr =




More information about the llvm-commits mailing list