[llvm] [LVI] Handle icmp of ashr. (PR #68010)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 19 10:44:36 PDT 2023
================
@@ -1148,6 +1149,57 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
CR.getUnsignedMin().zext(BitWidth), APInt(BitWidth, 0)));
}
+ // Recognize:
+ // icmp sgt (ashr X, ShAmtC), C --> icmp sgt X, ((C + 1) << ShAmtC) - 1
+ // and friends.
+ // Preconditions: (C != SIGNED_MAX) &&
+ // ((C+1) << ShAmtC != SIGNED_MIN) &&
+ // (((C+1) << ShAmtC) >> ShAmtC) == (C+1)
+ const APInt *ShAmtC;
+ if (CmpInst::isSigned(EdgePred) &&
+ match(LHS, m_AShr(m_Specific(Val), m_APInt(ShAmtC))) &&
+ match(RHS, m_APInt(C))) {
+ APInt New = ((*C + 1) << *ShAmtC) - 1;
+ APInt MaxSigned = APInt::getSignedMaxValue(New.getBitWidth());
+ APInt MinSigned = APInt::getSignedMinValue(New.getBitWidth());
+ auto CheckPreConds = [&]() {
+ if (*C == MaxSigned)
+ return false;
+ APInt Shifted = (*C + 1) << *ShAmtC;
+ if (Shifted == MinSigned)
+ return false;
+ if ((Shifted.ashr(*ShAmtC)) != (*C + 1))
+ return false;
+ return true;
+ };
+ if (!CheckPreConds())
+ return ValueLatticeElement::getOverdefined();
+ APInt Lower, Upper;
+ switch (EdgePred) {
+ default:
+ llvm_unreachable("Unknown signed predicate!");
+ case ICmpInst::ICMP_SGT:
+ Lower = New + 1;
+ Upper = MaxSigned;
+ break;
+ case ICmpInst::ICMP_SLE:
+ Lower = MinSigned;
+ Upper = New + 1;
+ break;
+ case ICmpInst::ICMP_SGE:
----------------
goldsteinn wrote:
Does this hold for preds other then SGT/SLE: https://alive2.llvm.org/ce/z/wHF_sk
https://github.com/llvm/llvm-project/pull/68010
More information about the llvm-commits
mailing list