aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2020-09-24 11:06:55 +0100
committerFlorian Hahn <flo@fhahn.com>2020-09-24 11:06:55 +0100
commitd4ddf63fc40cfbbc348adcc45cdc6f6d78268c5c (patch)
treee30377405b189a3310b3919a1211a8698f2e049c /llvm/unittests/Analysis/ScalarEvolutionTest.cpp
parent15c9af5618c8c4a810994df53543af9060086a8e (diff)
downloadllvm-d4ddf63fc40cfbbc348adcc45cdc6f6d78268c5c.zip
llvm-d4ddf63fc40cfbbc348adcc45cdc6f6d78268c5c.tar.gz
llvm-d4ddf63fc40cfbbc348adcc45cdc6f6d78268c5c.tar.bz2
[SCEV] Use loop guard info when computing the max BE taken count in howFarToZero.
For some expressions, we can use information from loop guards when we are looking for a maximum. This patch applies information from loop guards to the expression used to compute the maximum backedge taken count in howFarToZero. It currently replaces an unknown expression X with UMin(X, Y), if the loop is guarded by X ult Y. This patch is minimal in what conditions it applies, and there are a few TODOs to generalize. This partly addresses PR40961. We will also need an update to LV to address it completely. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D67178
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