diff options
Diffstat (limited to 'llvm/unittests/Analysis/ScalarEvolutionTest.cpp')
-rw-r--r-- | llvm/unittests/Analysis/ScalarEvolutionTest.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp index 909a140..7fa5885 100644 --- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -63,6 +63,11 @@ protected: const SCEV *RHS) { return SE.computeConstantDifference(LHS, RHS); } + + static bool matchURem(ScalarEvolution &SE, const SCEV *Expr, const SCEV *&LHS, + const SCEV *&RHS) { + return SE.matchURem(Expr, LHS, RHS); + } }; TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) { @@ -1363,4 +1368,57 @@ TEST_F(ScalarEvolutionsTest, ProveImplicationViaNarrowing) { }); } +TEST_F(ScalarEvolutionsTest, MatchURem) { + LLVMContext C; + SMDiagnostic Err; + std::unique_ptr<Module> M = parseAssemblyString( + "target datalayout = \"e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128\" " + " " + "define void @test(i32 %a, i32 %b, i16 %c, i64 %d) {" + "entry: " + " %rem1 = urem i32 %a, 2" + " %rem2 = urem i32 %a, 5" + " %rem3 = urem i32 %a, %b" + " %c.ext = zext i16 %c to i32" + " %rem4 = urem i32 %c.ext, 2" + " %ext = zext i32 %rem4 to i64" + " %rem5 = urem i64 %d, 17179869184" + " ret void " + "} ", + Err, C); + + assert(M && "Could not parse module?"); + assert(!verifyModule(*M) && "Must have been well formed!"); + + runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) { + for (auto *N : {"rem1", "rem2", "rem3", "rem5"}) { + auto *URemI = getInstructionByName(F, N); + auto *S = SE.getSCEV(URemI); + const SCEV *LHS, *RHS; + EXPECT_TRUE(matchURem(SE, S, LHS, RHS)); + EXPECT_EQ(LHS, SE.getSCEV(URemI->getOperand(0))); + EXPECT_EQ(RHS, SE.getSCEV(URemI->getOperand(1))); + EXPECT_EQ(LHS->getType(), S->getType()); + EXPECT_EQ(RHS->getType(), S->getType()); + } + + // Check the case where the urem operand is zero-extended. Make sure the + // match results are extended to the size of the input expression. + auto *Ext = getInstructionByName(F, "ext"); + auto *URem1 = getInstructionByName(F, "rem4"); + auto *S = SE.getSCEV(Ext); + const SCEV *LHS, *RHS; + EXPECT_TRUE(matchURem(SE, S, LHS, RHS)); + EXPECT_NE(LHS, SE.getSCEV(URem1->getOperand(0))); + // RHS and URem1->getOperand(1) have different widths, so compare the + // integer values. + EXPECT_EQ(cast<SCEVConstant>(RHS)->getValue()->getZExtValue(), + cast<SCEVConstant>(SE.getSCEV(URem1->getOperand(1))) + ->getValue() + ->getZExtValue()); + EXPECT_EQ(LHS->getType(), S->getType()); + EXPECT_EQ(RHS->getType(), S->getType()); + }); +} + } // end namespace llvm |