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)
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);