[llvm] r360671 - Save the induction binary operator in IVDescriptors for non FP induction variables.

Kit Barton via llvm-commits llvm-commits at lists.llvm.org
Tue May 14 06:26:36 PDT 2019


Author: kbarton
Date: Tue May 14 06:26:36 2019
New Revision: 360671

URL: http://llvm.org/viewvc/llvm-project?rev=360671&view=rev
Log:
Save the induction binary operator in IVDescriptors for non FP induction variables.

Summary:
Currently InductionBinOps are only saved for FP induction variables, the PR extends it with non FP induction variable, so user of IVDescriptors can query the InductionBinOps for integer induction variables.

The changes in hasUnsafeAlgebra() and getUnsafeAlgebraInst() are required for the existing LIT test cases to pass. As described in the comment of the two functions, one of the requirement to return true is it is a FP induction variable. The checks was not needed because InductionBinOp was not set on non FP cases before.

https://reviews.llvm.org/D60565 depends on the patch.

Committed on behalf of @Whitney (Whitney Tsang).

Reviewers: jdoerfert, kbarton, fhahn, hfinkel, dmgreen, Meinersbur

Reviewed By: jdoerfert

Subscribers: mgorny, hiraditya, jsji, llvm-commits

Tags: #llvm

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

Added:
    llvm/trunk/unittests/Analysis/IVDescriptorsTest.cpp
Modified:
    llvm/trunk/include/llvm/Analysis/IVDescriptors.h
    llvm/trunk/lib/Analysis/IVDescriptors.cpp
    llvm/trunk/unittests/Analysis/CMakeLists.txt

Modified: llvm/trunk/include/llvm/Analysis/IVDescriptors.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVDescriptors.h?rev=360671&r1=360670&r2=360671&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/IVDescriptors.h (original)
+++ llvm/trunk/include/llvm/Analysis/IVDescriptors.h Tue May 14 06:26:36 2019
@@ -315,12 +315,16 @@ public:
   /// not have the "fast-math" property. Such operation requires a relaxed FP
   /// mode.
   bool hasUnsafeAlgebra() {
-    return InductionBinOp && !cast<FPMathOperator>(InductionBinOp)->isFast();
+    return (IK == IK_FpInduction) && InductionBinOp &&
+           !cast<FPMathOperator>(InductionBinOp)->isFast();
   }
 
   /// Returns induction operator that does not have "fast-math" property
   /// and requires FP unsafe mode.
   Instruction *getUnsafeAlgebraInst() {
+    if (IK != IK_FpInduction)
+      return nullptr;
+
     if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
       return nullptr;
     return InductionBinOp;

Modified: llvm/trunk/lib/Analysis/IVDescriptors.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IVDescriptors.cpp?rev=360671&r1=360670&r2=360671&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/IVDescriptors.cpp (original)
+++ llvm/trunk/lib/Analysis/IVDescriptors.cpp Tue May 14 06:26:36 2019
@@ -1053,6 +1053,13 @@ bool InductionDescriptor::isInductionPHI
 
   Value *StartValue =
       Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader());
+
+  BasicBlock *Latch = AR->getLoop()->getLoopLatch();
+  if (!Latch)
+    return false;
+  BinaryOperator *BOp =
+      dyn_cast<BinaryOperator>(Phi->getIncomingValueForBlock(Latch));
+
   const SCEV *Step = AR->getStepRecurrence(*SE);
   // Calculate the pointer stride and check if it is consecutive.
   // The stride may be a constant or a loop invariant integer value.
@@ -1061,7 +1068,7 @@ bool InductionDescriptor::isInductionPHI
     return false;
 
   if (PhiTy->isIntegerTy()) {
-    D = InductionDescriptor(StartValue, IK_IntInduction, Step, /*BOp=*/nullptr,
+    D = InductionDescriptor(StartValue, IK_IntInduction, Step, BOp,
                             CastsToIgnore);
     return true;
   }
@@ -1088,6 +1095,6 @@ bool InductionDescriptor::isInductionPHI
     return false;
   auto *StepValue =
       SE->getConstant(CV->getType(), CVSize / Size, true /* signed */);
-  D = InductionDescriptor(StartValue, IK_PtrInduction, StepValue);
+  D = InductionDescriptor(StartValue, IK_PtrInduction, StepValue, BOp);
   return true;
 }

Modified: llvm/trunk/unittests/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/CMakeLists.txt?rev=360671&r1=360670&r2=360671&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Analysis/CMakeLists.txt Tue May 14 06:26:36 2019
@@ -18,6 +18,7 @@ add_llvm_unittest(AnalysisTests
   DivergenceAnalysisTest.cpp
   DomTreeUpdaterTest.cpp
   GlobalsModRefTest.cpp
+  IVDescriptorsTest.cpp
   LazyCallGraphTest.cpp
   LoopInfoTest.cpp
   MemoryBuiltinsTest.cpp

Added: llvm/trunk/unittests/Analysis/IVDescriptorsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/IVDescriptorsTest.cpp?rev=360671&view=auto
==============================================================================
--- llvm/trunk/unittests/Analysis/IVDescriptorsTest.cpp (added)
+++ llvm/trunk/unittests/Analysis/IVDescriptorsTest.cpp Tue May 14 06:26:36 2019
@@ -0,0 +1,100 @@
+//===- IVDescriptorsTest.cpp - IVDescriptors unit tests -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/IVDescriptors.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+/// Build the loop info and scalar evolution for the function and run the Test.
+static void runWithLoopInfoAndSE(
+    Module &M, StringRef FuncName,
+    function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE)> Test) {
+  auto *F = M.getFunction(FuncName);
+  ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+  TargetLibraryInfoImpl TLII;
+  TargetLibraryInfo TLI(TLII);
+  AssumptionCache AC(*F);
+  DominatorTree DT(*F);
+  LoopInfo LI(DT);
+  ScalarEvolution SE(*F, TLI, AC, DT, LI);
+
+  Test(*F, LI, SE);
+}
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+  SMDiagnostic Err;
+  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+  if (!Mod)
+    Err.print("IVDescriptorsTests", errs());
+  return Mod;
+}
+
+// This tests that IVDescriptors can obtain the induction binary operator for
+// integer induction variables. And hasUnsafeAlgebra() and
+// getUnsafeAlgebraInst() correctly return the expected behavior, i.e. no unsafe
+// algebra.
+TEST(IVDescriptorsTest, LoopWithSingleLatch) {
+  // Parse the module.
+  LLVMContext Context;
+
+  std::unique_ptr<Module> M = parseIR(
+    Context,
+    R"(define void @foo(i32* %A, i32 %ub) {
+entry:
+  br label %for.body
+for.body:
+  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %idxprom = sext i32 %i to i64
+  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
+  store i32 %i, i32* %arrayidx, align 4
+  %inc = add nsw i32 %i, 1
+  %cmp = icmp slt i32 %inc, %ub
+  br i1 %cmp, label %for.body, label %for.exit
+for.exit:
+  br label %for.end
+for.end:
+  ret void
+})"
+    );
+
+  runWithLoopInfoAndSE(
+      *M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+        Function::iterator FI = F.begin();
+        // First basic block is entry - skip it.
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+        PHINode *Inst_i = dyn_cast<PHINode>(&Header->front());
+        assert(Inst_i->getName() == "i");
+        InductionDescriptor IndDesc;
+        bool IsInductionPHI =
+            InductionDescriptor::isInductionPHI(Inst_i, L, &SE, IndDesc);
+        EXPECT_TRUE(IsInductionPHI);
+        Instruction *Inst_inc = nullptr;
+        BasicBlock::iterator BBI = Header->begin();
+        do {
+          if ((&*BBI)->getName() == "inc")
+            Inst_inc = &*BBI;
+          ++BBI;
+        } while (!Inst_inc);
+        assert(Inst_inc->getName() == "inc");
+        EXPECT_EQ(IndDesc.getInductionBinOp(), Inst_inc);
+        EXPECT_FALSE(IndDesc.hasUnsafeAlgebra());
+        EXPECT_EQ(IndDesc.getUnsafeAlgebraInst(), nullptr);
+      });
+}




More information about the llvm-commits mailing list