[llvm] [InstCombine] Improve `(icmp pred (and X, Y), ...)` fold. (PR #66787)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 15 06:28:17 PST 2023
================
@@ -233,56 +233,116 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
PatternMatch::m_Value()));
}
- /// Return true if the specified value is free to invert (apply ~ to).
- /// This happens in cases where the ~ can be eliminated. If WillInvertAllUses
- /// is true, work under the assumption that the caller intends to remove all
- /// uses of V and only keep uses of ~V.
- ///
- /// See also: canFreelyInvertAllUsersOf()
- static bool isFreeToInvert(Value *V, bool WillInvertAllUses,
- unsigned Depth = 0) {
+ /// Return nonnull value if V is free to invert (with condition) regarding
+ /// WillInvertAllUses.
+ /// If Builder is nonnull, it will return a simplified ~V
+ /// If builder is null, it will return an arbitrary nonnull value (not
+ /// dereferenceable).
+ static Value *getFreeInverted(Value *V, bool WillInvertAllUses,
+ BuilderTy *Builder, unsigned Depth = 0) {
+ static Value *const kNonNull = reinterpret_cast<Value *>(uintptr_t(1));
// ~(~(X)) -> X.
- if (match(V, m_Not(PatternMatch::m_Value())))
- return true;
+ Value *A, *B;
+ if (match(V, m_Not(PatternMatch::m_Value(A))))
+ return A;
+ Constant *C;
// Constants can be considered to be not'ed values.
- if (match(V, PatternMatch::m_AnyIntegralConstant()))
- return true;
+ if (match(V, PatternMatch::m_ImmConstant(C)))
+ return ConstantExpr::getNot(C);
if (Depth++ >= MaxAnalysisRecursionDepth)
- return false;
+ return nullptr;
// The rest of the cases require that we invert all uses so don't bother
// doing the analysis if we know we can't use the result.
if (!WillInvertAllUses)
- return false;
+ return nullptr;
// Compares can be inverted if all of their uses are being modified to use
// the ~V.
- if (isa<CmpInst>(V))
- return true;
+ if (auto *I = dyn_cast<CmpInst>(V)) {
+ if (Builder != nullptr)
+ return Builder->CreateCmp(I->getInversePredicate(), I->getOperand(0),
+ I->getOperand(1));
+ return kNonNull;
+ }
- Value *A, *B;
- // If `V` is of the form `A + B` then `-1 - V` can be folded into
- // `~B - A` or `~A - B` if we are willing to invert all of the uses.
- if (match(V, m_Add(PatternMatch::m_Value(A), PatternMatch::m_Value(B))))
- return isFreeToInvert(A, A->hasOneUse(), Depth) ||
- isFreeToInvert(B, B->hasOneUse(), Depth);
+ // If `V` is of the form `A + Constant` then `-1 - V` can be folded into
+ // `(-1 - Constant) - A` if we are willing to invert all of the uses.
+ if (match(V, m_Add(PatternMatch::m_Value(A), PatternMatch::m_Value(B)))) {
+ if (auto *BV = getFreeInverted(B, B->hasOneUse(), Builder, Depth))
+ return Builder ? Builder->CreateSub(BV, A) : kNonNull;
+ if (auto *AV = getFreeInverted(A, A->hasOneUse(), Builder, Depth))
+ return Builder ? Builder->CreateSub(AV, B) : kNonNull;
+ return nullptr;
+ }
- // If `V` is of the form `A - B` then `-1 - V` can be folded into
- // `~A + B` if we are willing to invert all of the uses.
- if (match(V, m_Sub(PatternMatch::m_Value(A), PatternMatch::m_Value())))
- return isFreeToInvert(A, A->hasOneUse(), Depth);
+ // If `V` is of the form `A ^ ~B` then `~(A ^ ~B)` can be folded
+ // into `A ^ B` if we are willing to invert all of the uses.
+ if (match(V, m_Xor(PatternMatch::m_Value(A), PatternMatch::m_Value(B)))) {
+ if (auto *BV = getFreeInverted(B, B->hasOneUse(), Builder, Depth))
+ return Builder ? Builder->CreateXor(A, BV) : kNonNull;
+ if (auto *AV = getFreeInverted(A, A->hasOneUse(), Builder, Depth))
+ return Builder ? Builder->CreateXor(AV, B) : kNonNull;
+ return nullptr;
+ }
+ // If `V` is of the form `Constant - A` then `-1 - V` can be folded into
+ // `A + (-1 - Constant)` if we are willing to invert all of the uses.
+ if (match(V, m_Sub(PatternMatch::m_Value(A), PatternMatch::m_Value(B)))) {
+ if (auto *AV = getFreeInverted(A, A->hasOneUse(), Builder, Depth))
+ return Builder ? Builder->CreateAdd(AV, B) : kNonNull;
+ return nullptr;
+ }
+
+ // If `V` is of the form `Constant - A` then `-1 - V` can be folded into
+ // `A + (-1 - Constant)` if we are willing to invert all of the uses.
----------------
nikic wrote:
Comment is about sub, implementation is for ashr.
https://github.com/llvm/llvm-project/pull/66787
More information about the llvm-commits
mailing list