diff options
Diffstat (limited to 'llvm/unittests/Analysis')
-rw-r--r-- | llvm/unittests/Analysis/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/Analysis/IVDescriptorsTest.cpp | 100 |
2 files changed, 101 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt index 45d31f88911..20b4ae21edb 100644 --- a/llvm/unittests/Analysis/CMakeLists.txt +++ b/llvm/unittests/Analysis/CMakeLists.txt @@ -18,6 +18,7 @@ add_llvm_unittest(AnalysisTests DivergenceAnalysisTest.cpp DomTreeUpdaterTest.cpp GlobalsModRefTest.cpp + IVDescriptorsTest.cpp LazyCallGraphTest.cpp LoopInfoTest.cpp MemoryBuiltinsTest.cpp diff --git a/llvm/unittests/Analysis/IVDescriptorsTest.cpp b/llvm/unittests/Analysis/IVDescriptorsTest.cpp new file mode 100644 index 00000000000..cba45a96e68 --- /dev/null +++ b/llvm/unittests/Analysis/IVDescriptorsTest.cpp @@ -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); + }); +} |