summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Analysis
diff options
context:
space:
mode:
authorDaniel Neilson <dneilson@azul.com>2017-10-11 19:05:14 +0000
committerDaniel Neilson <dneilson@azul.com>2017-10-11 19:05:14 +0000
commit5acfd1dd78f2485cef0dc3f5968d0ddf57ea6629 (patch)
treedf291e597ff96dabc33dfe249f61d819a139e5b8 /llvm/unittests/Analysis
parent198d385a77794555d9041515f051cb8a6c437f83 (diff)
downloadbcm5719-llvm-5acfd1dd78f2485cef0dc3f5968d0ddf57ea6629.tar.gz
bcm5719-llvm-5acfd1dd78f2485cef0dc3f5968d0ddf57ea6629.zip
[SCEV] Properly handle the case of a non-constant start with a zero accum in ScalarEvolution::createAddRecFromPHIWithCastsImpl
Summary: This patch fixes an error in the patch to ScalarEvolution::createAddRecFromPHIWithCastsImpl made in D37265. In that patch we handle the cases where the either the start or accum values can be zero after truncation. But, we assume that the start value must be a constant if the accum is zero. This is clearly an erroneous assumption. This change removes that assumption. Reviewers: sanjoy, dorit, mkazantsev Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D38814 llvm-svn: 315491
Diffstat (limited to 'llvm/unittests/Analysis')
-rw-r--r--llvm/unittests/Analysis/ScalarEvolutionTest.cpp58
1 files changed, 57 insertions, 1 deletions
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 4bede8bc59c..f4ef32bc6f8 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1009,6 +1009,63 @@ TEST_F(ScalarEvolutionsTest, SCEVAddRecFromPHIwithLargeConstants) {
auto Result = SE.createAddRecFromPHIWithCasts(cast<SCEVUnknown>(Expr));
}
+TEST_F(ScalarEvolutionsTest, SCEVAddRecFromPHIwithLargeConstantAccum) {
+ // Make sure that SCEV does not blow up when constructing an AddRec
+ // with predicates for a phi with the update pattern:
+ // (SExt/ZExt ix (Trunc iy (%SymbolicPHI) to ix) to iy) + InvariantAccum
+ // when the InvariantAccum is a constant that is too large to fit in an
+ // ix but are zero when truncated to ix, and the initial value of the
+ // phi is not a constant.
+ Type *Int32Ty = Type::getInt32Ty(Context);
+ SmallVector<Type *, 1> Types;
+ Types.push_back(Int32Ty);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
+ Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
+
+ /*
+ Create IR:
+ define @addrecphitest(i32)
+ entry:
+ br label %loop
+ loop:
+ %1 = phi i32 [%0, %entry], [%4, %loop]
+ %2 = shl i32 %1, 16
+ %3 = ashr exact i32 %2, 16
+ %4 = add i32 %3, -2147483648
+ br i1 undef, label %exit, label %loop
+ exit:
+ ret void
+ */
+ BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
+ BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
+ BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
+
+ // entry:
+ BranchInst::Create(LoopBB, EntryBB);
+ // loop:
+ auto *MinInt32 = ConstantInt::get(Context, APInt(32, 0x80000000U, true));
+ auto *Int32_16 = ConstantInt::get(Context, APInt(32, 16));
+ auto *Br = BranchInst::Create(
+ LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)), LoopBB);
+ auto *Phi = PHINode::Create(Int32Ty, 2, "", Br);
+ auto *Shl = BinaryOperator::CreateShl(Phi, Int32_16, "", Br);
+ auto *AShr = BinaryOperator::CreateExactAShr(Shl, Int32_16, "", Br);
+ auto *Add = BinaryOperator::CreateAdd(AShr, MinInt32, "", Br);
+ auto *Arg = &*(F->arg_begin());
+ Phi->addIncoming(Arg, EntryBB);
+ Phi->addIncoming(Add, LoopBB);
+ // exit:
+ ReturnInst::Create(Context, nullptr, ExitBB);
+
+ // Make sure that SCEV doesn't blow up
+ ScalarEvolution SE = buildSE(*F);
+ SCEVUnionPredicate Preds;
+ const SCEV *Expr = SE.getSCEV(Phi);
+ EXPECT_NE(nullptr, Expr);
+ EXPECT_TRUE(isa<SCEVUnknown>(Expr));
+ auto Result = SE.createAddRecFromPHIWithCasts(cast<SCEVUnknown>(Expr));
+}
+
TEST_F(ScalarEvolutionsTest, SCEVFoldSumOfTruncs) {
// Verify that the following SCEV gets folded to a zero:
// (-1 * (trunc i64 (-1 * %0) to i32)) + (-1 * (trunc i64 %0 to i32)
@@ -1035,7 +1092,6 @@ TEST_F(ScalarEvolutionsTest, SCEVFoldSumOfTruncs) {
const auto *B = SE.getNegativeSCEV(B0);
const auto *Expr = SE.getAddExpr(A, B);
- dbgs() << "DDN\nExpr: " << *Expr << "\n";
// Verify that the SCEV was folded to 0
const auto *ZeroConst = SE.getConstant(Int32Ty, 0);
EXPECT_EQ(Expr, ZeroConst);
OpenPOWER on IntegriCloud