aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Analysis/ScalarEvolutionTest.cpp')
-rw-r--r--llvm/unittests/Analysis/ScalarEvolutionTest.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 04aaae1..ff33495 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1186,4 +1186,69 @@ TEST_F(ScalarEvolutionsTest, SCEVAddNUW) {
});
}
+TEST_F(ScalarEvolutionsTest, SCEVgetRanges) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define void @foo(i32 %i) { "
+ "entry: "
+ " br label %loop.body "
+ "loop.body: "
+ " %iv = phi i32 [ %iv.next, %loop.body ], [ 0, %entry ] "
+ " %iv.next = add nsw i32 %iv, 1 "
+ " %cmp = icmp eq i32 %iv.next, 16 "
+ " br i1 %cmp, label %exit, label %loop.body "
+ "exit: "
+ " ret void "
+ "} ",
+ Err, C);
+
+ runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ auto *ScevIV = SE.getSCEV(getInstructionByName(F, "iv")); // {0,+,1}
+ auto *ScevI = SE.getSCEV(getArgByName(F, "i"));
+ EXPECT_EQ(SE.getUnsignedRange(ScevIV).getLower(), 0);
+ EXPECT_EQ(SE.getUnsignedRange(ScevIV).getUpper(), 16);
+
+ auto *Add = SE.getAddExpr(ScevI, ScevIV);
+ ValueToSCEVMapTy RewriteMap;
+ RewriteMap[cast<SCEVUnknown>(ScevI)->getValue()] =
+ SE.getUMinExpr(ScevI, SE.getConstant(ScevI->getType(), 17));
+ auto *AddWithUMin = SCEVParameterRewriter::rewrite(Add, SE, RewriteMap);
+ EXPECT_EQ(SE.getUnsignedRange(AddWithUMin).getLower(), 0);
+ EXPECT_EQ(SE.getUnsignedRange(AddWithUMin).getUpper(), 33);
+ });
+}
+
+TEST_F(ScalarEvolutionsTest, SCEVgetExitLimitForGuardedLoop) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define void @foo(i32 %i) { "
+ "entry: "
+ " %cmp3 = icmp ult i32 %i, 16 "
+ " br i1 %cmp3, label %loop.body, label %exit "
+ "loop.body: "
+ " %iv = phi i32 [ %iv.next, %loop.body ], [ %i, %entry ] "
+ " %iv.next = add nsw i32 %iv, 1 "
+ " %cmp = icmp eq i32 %iv.next, 16 "
+ " br i1 %cmp, label %exit, label %loop.body "
+ "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 *ScevIV = SE.getSCEV(getInstructionByName(F, "iv")); // {0,+,1}
+ const Loop *L = cast<SCEVAddRecExpr>(ScevIV)->getLoop();
+
+ const SCEV *BTC = SE.getBackedgeTakenCount(L);
+ EXPECT_FALSE(isa<SCEVConstant>(BTC));
+ const SCEV *MaxBTC = SE.getConstantMaxBackedgeTakenCount(L);
+ EXPECT_EQ(cast<SCEVConstant>(MaxBTC)->getAPInt(), 15);
+ });
+}
+
} // end namespace llvm