[PATCH] D151911: [LVI] Handle icmp of ashr.
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 20 03:13:25 PDT 2023
nikic added inline comments.
================
Comment at: llvm/lib/Analysis/LazyValueInfo.cpp:1152
+ // Recognize:
+ // icmp sgt (ashr X, ShAmtC), C --> icmp sgt X, ((C + 1) << ShAmtC) - 1
+ // and friends.
----------------
I think the better way to explain this is `icmp slt (ashr X, ShAmtC), C --> icmp slt X, C << ShAmtC` (https://alive2.llvm.org/ce/z/ww5u4i). In this case the only precondition is `((C << ShAmtC) >> ShAmtC) == C`. Same for sge.
All the +1/-1 get introduced by using sgt/sle because we're effectively trying to reduce them to that base case. This also introduces the extra preconditions to avoid overflow on +/-1.
With this in mind, I think we can introduce an abstraction like this to transparently handle all the signed predicates while only specifying the fold for slt (without knowledge of anything about ashr in particular):
```
static std::optional<ConstantRange> getRangeViaSLT(
CmpInst::Predicate Pred, APInt RHS,
function_ref<std::optional<ConstantRange>(const APInt &)> Fn) {
bool Invert = false;
if (Pred == ICmpInst::SGT || Pred == ICmpInst::SGE) {
Pred = ICmpInst::getInversePredicate(Pred);
Invert = true;
}
if (Pred == ICmpInst::SLE) {
Pred = ICmpInst::SLT;
if (RHS.isSignedMax())
return std::nullopt; // Could also return full/empty here, if we wanted.
++RHS;
}
assert(Pred == ICmpInst::SLT && "Must be signed predicate");
if (auto CR = Fn(RHS))
return Invert ? CR->inverse() : CR;
return std::nullopt;
}
```
And then do something like this:
```
const APInt *ShAmtC;
if (CmpInst::isSigned(EdgePred) &&
match(LHS, m_AShr(m_Specific(Val), m_APInt(ShAmtC))) &&
match(RHS, m_APInt(C))) {
return getRangeViaSLT(EdgePred, *C, [&](const APInt &RHS) {
APInt New = RHS << *ShAmtC;
if ((New.ashr(*ShAmtC)) != New)
return std::nullopt;
return ConstantRange::getNonEmpty(APInt:.getSignedMinValue(BW), New + 1);
});
}
```
Code is untested, but I think the general idea should work.
================
Comment at: llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll:1257
+ %s = ashr i8 %x, 2
+ %c = icmp sgt i8 %s, 0
+ br i1 %c, label %if, label %else
----------------
Can we have a test where the RHS is not zero? We should also have one where the shift round trip precondition does not hold.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151911/new/
https://reviews.llvm.org/D151911
More information about the llvm-commits
mailing list