Index: llvm/unittests/Analysis/ScalarEvolutionTest.cpp =================================================================== --- llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -1744,4 +1744,34 @@ }); } +TEST_F(ScalarEvolutionsTest, WrongDivisibilty) { + LLVMContext C; + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString("define void @foo(i32 %num) { " + " 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(getArgByName(F, "num")); + // create the following SCEV: + // 8 umax (32 umin (4 * (%num /u 4))) + // SCEV doesn't conclude it divides by 4. + APInt Four(32, 4); + APInt ThirtyTwo(32, 32); + APInt Eight(32, 8); + auto Constant4 = SE.getConstant(Four); + auto Constant32 = SE.getConstant(ThirtyTwo); + auto Constant8 = SE.getConstant(Eight); + auto Mul = SE.getMulExpr(SE.getUDivExpr(ScevIV, Constant4), Constant4); + auto Min = SE.getUMinExpr(Mul, Constant32); + auto Max = SE.getUMaxExpr(Min, Constant8); + auto Rem = SE.getURemExpr(Max, Constant4); + ASSERT_TRUE(!Rem->isZero()); + }); +} + } // end namespace llvm