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.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index a7b3c5c..a6a5ffd 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1589,4 +1589,40 @@ TEST_F(ScalarEvolutionsTest, ApplyLoopGuards) {
});
}
+TEST_F(ScalarEvolutionsTest, ForgetValueWithOverflowInst) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) "
+ "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 "
+ " %call = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %iv, i32 -2) "
+ " %extractvalue = extractvalue {i32, i1} %call, 0 "
+ " %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 *ExtractValue = getInstructionByName(F, "extractvalue");
+ auto *IV = getInstructionByName(F, "iv");
+
+ auto *ExtractValueScev = SE.getSCEV(ExtractValue);
+ EXPECT_NE(ExtractValueScev, nullptr);
+
+ SE.forgetValue(IV);
+ auto *ExtractValueScevForgotten = SE.getExistingSCEV(ExtractValue);
+ EXPECT_EQ(ExtractValueScevForgotten, nullptr);
+ });
+}
+
} // end namespace llvm