[SCEV] Support unsigned predicates in isKnownPredicateViaNoOverflow

SCEV should be able to prove facts like `x <u x+1<nuw>`.

Differential Revision: https://reviews.llvm.org/D88015
Reviewed By: lebedev.ri
This commit is contained in:
Max Kazantsev 2020-09-22 17:03:52 +07:00
parent 0356a413a4
commit 16fde88dbd
2 changed files with 39 additions and 0 deletions

View File

@ -9314,6 +9314,24 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred,
if (MatchBinaryAddToConst(LHS, RHS, C, SCEV::FlagNSW) && C.isNegative())
return true;
break;
case ICmpInst::ICMP_UGE:
std::swap(LHS, RHS);
LLVM_FALLTHROUGH;
case ICmpInst::ICMP_ULE:
// X u<= (X + C)<nuw> for any C
if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW))
return true;
break;
case ICmpInst::ICMP_UGT:
std::swap(LHS, RHS);
LLVM_FALLTHROUGH;
case ICmpInst::ICMP_ULT:
// X u< (X + C)<nuw> if C != 0
if (MatchBinaryAddToConst(RHS, LHS, C, SCEV::FlagNUW) && !C.isNullValue())
return true;
break;
}
return false;

View File

@ -1165,4 +1165,25 @@ TEST_F(ScalarEvolutionsTest, SCEVrewriteUnknowns) {
cast<SCEVAddRecExpr>(ScevIV)->getStepRecurrence(SE));
});
}
TEST_F(ScalarEvolutionsTest, SCEVAddNUW) {
LLVMContext C;
SMDiagnostic Err;
std::unique_ptr<Module> M = parseAssemblyString("define void @foo(i32 %x) { "
" 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 *X = SE.getSCEV(getArgByName(F, "x"));
auto *One = SE.getOne(X->getType());
auto *Sum = SE.getAddExpr(X, One, SCEV::FlagNUW);
EXPECT_TRUE(SE.isKnownPredicate(ICmpInst::ICMP_UGE, Sum, X));
EXPECT_TRUE(SE.isKnownPredicate(ICmpInst::ICMP_UGT, Sum, X));
});
}
} // end namespace llvm