[llvm] [ValueTracking] Improve `isImpliedCondICmps` to handle binops (PR #69840)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 21 22:24:35 PDT 2023
================
@@ -8272,8 +8280,36 @@ static std::optional<bool> isImpliedCondICmps(const ICmpInst *LHS,
// Can we infer anything when the 0-operands match and the 1-operands are
// constants (not necessarily matching)?
const APInt *LC, *RC;
- if (L0 == R0 && match(L1, m_APInt(LC)) && match(R1, m_APInt(RC)))
- return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
+ if (match(L1, m_APInt(LC)) && match(R1, m_APInt(RC))) {
+ if (L0 == R0)
+ return isImpliedCondCommonOperandWithConstants(LPred, *LC, RPred, *RC);
+
+ // handle R0 = L0 binop V and R0 = V binop L0
+ Value *R0Op1 = nullptr;
+ if (match(R0, m_c_BinOp(m_Specific(L0), m_Value(R0Op1)))) {
+ ConstantRange LHSRange = ConstantRange::makeExactICmpRegion(LPred, *LC);
+ ConstantRange CR = ConstantRange::makeExactICmpRegion(RPred, *RC);
+ // TODO: use contextual information from SimplifyQuery
+ ConstantRange RHSRange =
+ computeConstantRange(R0Op1, ICmpInst::isSigned(RPred),
+ /*UseInstrInfo*/ true, /*AC*/ nullptr,
+ /*CtxI*/ nullptr, /*DT*/ nullptr, Depth);
+ auto *BO = cast<BinaryOperator>(R0);
+ if (BO->getOperand(0) != L0)
+ std::swap(LHSRange, RHSRange);
+ unsigned NoWrapKind = 0;
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) {
+ if (OBO->hasNoUnsignedWrap())
+ NoWrapKind |= OverflowingBinaryOperator::NoUnsignedWrap;
+ if (OBO->hasNoSignedWrap())
+ NoWrapKind |= OverflowingBinaryOperator::NoSignedWrap;
+ }
+ ConstantRange Range =
+ LHSRange.overflowingBinaryOp(BO->getOpcode(), RHSRange, NoWrapKind);
----------------
goldsteinn wrote:
Still a bit confused about why `LHSRange` is based on the constant range of `LHS` and not of `L0`.
https://github.com/llvm/llvm-project/pull/69840
More information about the llvm-commits
mailing list