[PATCH] D101409: [SCEV] Check IDom with single predecessor on getPredecessorWithUniqueSuccessorForBB

JinGu Kang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 27 15:56:55 PDT 2021


jaykang10 created this revision.
jaykang10 added reviewers: nikic, reames, lebedev.ri, fhahn.
Herald added a subscriber: hiraditya.
jaykang10 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

`getPredecessorWithUniqueSuccessorForBB` finds a BB which has a single predecessor and dominates target BB.

At this moment, the function is checking below two things.

1. Target BB has single predecessor. If so, it returns predecessor and target BB.
2. Target BB is part of loop. If so, it returns the loop's pre-header and header.

We could check one more thing as below.

If Target BB has IDom and the IDom has single predecessor, it also meet the condition of `getPredecessorWithUniqueSuccessorForBB` and we can return the IDom's predecessor and the IDom.


https://reviews.llvm.org/D101409

Files:
  llvm/lib/Analysis/ScalarEvolution.cpp
  llvm/unittests/Analysis/ScalarEvolutionTest.cpp


Index: llvm/unittests/Analysis/ScalarEvolutionTest.cpp
===================================================================
--- llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1467,4 +1467,44 @@
   });
 }
 
+TEST_F(ScalarEvolutionsTest, BasicBlockEntryGuardedByCondWithIDom) {
+  LLVMContext C;
+  SMDiagnostic Err;
+  std::unique_ptr<Module> M = parseAssemblyString(
+      "define void @foo(i64 %0, i64 %1, i64 %n) { "
+      "entry: "
+      "  br label %bb "
+      "bb: "
+      "  %if.cond = icmp slt i64 1, %n "
+      "  br i1 %if.cond, label %if.then, label %exit "
+      "if.then: "
+      "  %if.cond.2 = icmp slt i64 1, %n "
+      "  br i1 %if.cond.2, label %loop.ph, label %if.then.else "
+      "if.then.else: "
+      "  br label %loop.ph "
+      "loop.ph: "
+      "  br label %loop "
+      "loop: "
+      "  %iv = phi i64 [ %inc, %loop ], [ 1, %loop.ph ] "
+      "  %inc = add nuw nsw i64 %iv, 1 "
+      "  %cond = icmp eq i64 %inc, %n "
+      "  br i1 %cond, label %exit, label %loop "
+      "exit: "
+      "  ret void "
+      "} ",
+      Err, C);
+
+  ASSERT_TRUE(M && "Could not parse module?");
+  ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!");
+
+  runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+    auto *Guarded = getInstructionByName(F, "iv")->getParent();
+    const SCEV *RHS = SE.getSCEV(getArgByName(F, "n"));
+    const SCEV *LHS = SE.getZero(RHS->getType());
+    ICmpInst::Predicate Pred = ICmpInst::ICMP_SLT;
+    EXPECT_TRUE(
+        SE.isBasicBlockEntryGuardedByCond(Guarded, Pred, LHS, RHS));
+  });
+}
+
 }  // end namespace llvm
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9305,6 +9305,13 @@
   if (const BasicBlock *Pred = BB->getSinglePredecessor())
     return {Pred, BB};
 
+  // Check IDom of BB and the IDom has single predecessor.
+  if (auto *IDom = DT.getNode(BB)->getIDom()) {
+    const BasicBlock *IDomBB = IDom->getBlock();
+    if (const BasicBlock *IDomPred = IDomBB->getSinglePredecessor())
+      return {IDomPred, IDomBB};
+  }
+
   // A loop's header is defined to be a block that dominates the loop.
   // If the header has a unique predecessor outside the loop, it must be
   // a block that has exactly one successor that can reach the loop.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101409.341008.patch
Type: text/x-patch
Size: 2473 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210427/54808d9f/attachment.bin>


More information about the llvm-commits mailing list