[llvm] 53dc525 - [LoopInfo] Fix function getInductionVariable

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 11 00:25:25 PST 2021


Author: duanbo.db
Date: 2021-11-11T16:22:42+08:00
New Revision: 53dc5258282a8322451cba14b5ad2f670028d196

URL: https://github.com/llvm/llvm-project/commit/53dc5258282a8322451cba14b5ad2f670028d196
DIFF: https://github.com/llvm/llvm-project/commit/53dc5258282a8322451cba14b5ad2f670028d196.diff

LOG: [LoopInfo] Fix function getInductionVariable

The way function gets the induction variable is by judging whether
StepInst or IndVar in the phi statement is one of the operands of CMP.
But if the LatchCmpOp0/LatchCmpOp1 is a constant,  the subsequent
comparison may result in null == null, which is meaningless. This patch
fixes the typo.

Reviewed By: Whitney

Differential Revision: https://reviews.llvm.org/D112980

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 081578e004424..b35fb2a190f62 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/lib/Analysis/LoopInfo.cpp
@@ -301,15 +301,16 @@ PHINode *Loop::getInductionVariable(ScalarEvolution &SE) const {
   if (!CmpInst)
     return nullptr;
 
-  Instruction *LatchCmpOp0 = dyn_cast<Instruction>(CmpInst->getOperand(0));
-  Instruction *LatchCmpOp1 = dyn_cast<Instruction>(CmpInst->getOperand(1));
+  Value *LatchCmpOp0 = CmpInst->getOperand(0);
+  Value *LatchCmpOp1 = CmpInst->getOperand(1);
 
   for (PHINode &IndVar : Header->phis()) {
     InductionDescriptor IndDesc;
     if (!InductionDescriptor::isInductionPHI(&IndVar, this, &SE, IndDesc))
       continue;
 
-    Instruction *StepInst = IndDesc.getInductionBinOp();
+    BasicBlock *Latch = getLoopLatch();
+    Value *StepInst = IndVar.getIncomingValueForBlock(Latch);
 
     // case 1:
     // IndVar = phi[{InitialValue, preheader}, {StepInst, latch}]

diff  --git a/llvm/unittests/Analysis/LoopInfoTest.cpp b/llvm/unittests/Analysis/LoopInfoTest.cpp
index 550458c270187..9c24e1cb87608 100644
--- a/llvm/unittests/Analysis/LoopInfoTest.cpp
+++ b/llvm/unittests/Analysis/LoopInfoTest.cpp
@@ -1547,3 +1547,39 @@ TEST(LoopInfoTest, LoopUserBranch) {
     EXPECT_EQ(L->getLoopGuardBranch(), nullptr);
   });
 }
+
+TEST(LoopInfoTest, LoopInductionVariable) {
+  const char *ModuleStr =
+      "define i32 @foo(i32* %addr) {\n"
+      "entry:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %sum.08 = phi i32 [ 0, %entry ], [ %add, %for.body ]\n"
+      "  %addr.addr.06 = phi i32* [ %addr, %entry ], [ %incdec.ptr, %for.body "
+      "]\n"
+      "  %count.07 = phi i32 [ 6000, %entry ], [ %dec, %for.body ]\n"
+      "  %0 = load i32, i32* %addr.addr.06, align 4\n"
+      "  %add = add nsw i32 %0, %sum.08\n"
+      "  %dec = add nsw i32 %count.07, -1\n"
+      "  %incdec.ptr = getelementptr inbounds i32, i32* %addr.addr.06, i64 1\n"
+      "  %cmp = icmp ugt i32 %count.07, 1\n"
+      "  br i1 %cmp, label %for.body, label %for.end\n"
+      "for.end:\n"
+      "  %cmp1 = icmp eq i32 %add, -1\n"
+      "  %conv = zext i1 %cmp1 to i32\n"
+      "  ret i32 %conv\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();
+        BasicBlock *Header = &*(++FI);
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "count.07");
+      });
+}


        


More information about the llvm-commits mailing list