[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:19:43 PST 2023
================
@@ -248,32 +249,38 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
if (match(V, PatternMatch::m_AnyIntegralConstant()))
return true;
+ if (Depth++ >= MaxAnalysisRecursionDepth)
+ return false;
+
+ // 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;
+
// Compares can be inverted if all of their uses are being modified to use
// the ~V.
if (isa<CmpInst>(V))
- return WillInvertAllUses;
-
- // 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(), PatternMatch::m_ImmConstant())))
- return WillInvertAllUses;
-
- // 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_ImmConstant(), PatternMatch::m_Value())))
- return WillInvertAllUses;
-
- // Selects with invertible operands are freely invertible
- if (match(V,
- m_Select(PatternMatch::m_Value(), m_Not(PatternMatch::m_Value()),
- m_Not(PatternMatch::m_Value()))))
- return WillInvertAllUses;
-
- // Min/max may be in the form of intrinsics, so handle those identically
- // to select patterns.
- if (match(V, m_MaxOrMin(m_Not(PatternMatch::m_Value()),
- m_Not(PatternMatch::m_Value()))))
- return WillInvertAllUses;
+ return true;
+
+ 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 - 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);
+
+ // Selects/min/max with invertible operands are freely invertible
+ if (match(V, m_Select(PatternMatch::m_Value(), PatternMatch::m_Value(A),
+ PatternMatch::m_Value(B))) ||
----------------
nikic wrote:
With this generalization, the select case should check `shouldAvoidAbsorbingNotIntoSelect()` to avoid inverting logical and/or into non-canonical form.
https://github.com/llvm/llvm-project/pull/66787
More information about the llvm-commits
mailing list