LLVM 22.0.0git
Classes | Macros | Enumerations | Functions
InstCombineAndOrXor.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/FloatingPointPredicateUtils.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/Local.h"

Go to the source code of this file.

Classes

struct  IntPart
 
struct  DecomposedBitMaskMul
 

Macros

#define DEBUG_TYPE   "instcombine"
 

Enumerations

enum  MaskedICmpType {
  AMask_AllOnes = 1 , AMask_NotAllOnes = 2 , BMask_AllOnes = 4 , BMask_NotAllOnes = 8 ,
  Mask_AllZeros = 16 , Mask_NotAllZeros = 32 , AMask_Mixed = 64 , AMask_NotMixed = 128 ,
  BMask_Mixed = 256 , BMask_NotMixed = 512
}
 Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified. More...
 

Functions

static ValuegetNewICmpValue (unsigned Code, bool Sign, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder)
 This is the complement of getICmpCode, which turns an opcode and two operands into either a constant true or false, or a brand new ICmp instruction.
 
static ValuegetFCmpValue (unsigned Code, Value *LHS, Value *RHS, InstCombiner::BuilderTy &Builder, FMFSource FMF)
 This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp instruction, or a true/false constant.
 
static unsigned getMaskedICmpType (Value *A, Value *B, Value *C, ICmpInst::Predicate Pred)
 Return the set of patterns (from MaskedICmpType) that (icmp SCC (A & B), C) satisfies.
 
static unsigned conjugateICmpMask (unsigned Mask)
 Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite sense.
 
static bool decomposeBitTestICmp (Value *Cond, CmpInst::Predicate &Pred, Value *&X, Value *&Y, Value *&Z)
 
static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair (Value *&A, Value *&B, Value *&C, Value *&D, Value *&E, Value *LHS, Value *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
 Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
 
static ValuefoldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed (Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
 Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!= Y), where the left-hand side is of type Mask_NotAllZeros and the right hand side is of type BMask_Mixed.
 
static ValuefoldLogOpOfMaskedICmpsAsymmetric (Value *LHS, Value *RHS, bool IsAnd, Value *A, Value *B, Value *C, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, unsigned LHSMask, unsigned RHSMask, InstCombiner::BuilderTy &Builder)
 Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!= Y), where the left-hand side and the right hand side aren't of the common mask pattern type.
 
static ValuefoldLogOpOfMaskedICmps (Value *LHS, Value *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
 Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!= Y).
 
static ValuefoldAndOrOfICmpsWithPow2AndWithZero (InstCombiner::BuilderTy &Builder, ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, const SimplifyQuery &Q)
 
static ValuefoldSignedTruncationCheck (ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
 General pattern: X & Y.
 
static ValuefoldIsPowerOf2OrZero (ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
 Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1).
 
static ValuefoldIsPowerOf2 (ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder, InstCombinerImpl &IC)
 Reduce a pair of compares that check if a value has exactly 1 bit set.
 
static ValuefoldNegativePower2AndShiftedMask (Value *A, Value *B, Value *D, Value *E, ICmpInst::Predicate PredL, ICmpInst::Predicate PredR, InstCombiner::BuilderTy &Builder)
 Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff B is a contiguous set of ones starting from the most significant bit (negative power of 2), D and E are equal, and D is a contiguous set of ones starting at the most significant zero bit in B.
 
static ValuefoldPowerOf2AndShiftedMask (ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
 Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) & (icmp(X & M) != M)) into (icmp X u< M).
 
static ValuefoldUnsignedUnderflowCheck (ICmpInst *ZeroICmp, ICmpInst *UnsignedICmp, bool IsAnd, const SimplifyQuery &Q, InstCombiner::BuilderTy &Builder)
 Commuted variants are assumed to be handled by calling this function again with the parameters swapped.
 
static std::optional< IntPartmatchIntPart (Value *V)
 Match an extraction of bits from an integer.
 
static ValueextractIntPart (const IntPart &P, IRBuilderBase &Builder)
 Materialize an extraction of bits from an integer in IR.
 
static ValuefoldAndOrOfICmpsWithConstEq (ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
 Reduce logic-of-compares with equality to a constant by substituting a common operand with the constant.
 
static ValuestripSignOnlyFPOps (Value *Val)
 Ignore all operations which only change the sign of a value, returning the underlying magnitude value.
 
static bool matchIsNotNaN (FCmpInst::Predicate P, Value *LHS, Value *RHS)
 Matches canonical form of isnan, fcmp ord x, 0.
 
static bool matchUnorderedInfCompare (FCmpInst::Predicate P, Value *LHS, Value *RHS)
 Matches fcmp u__ x, +/-inf.
 
static ValuematchIsFiniteTest (InstCombiner::BuilderTy &Builder, FCmpInst *LHS, FCmpInst *RHS)
 and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf
 
static bool matchIsFPClassLikeFCmp (Value *Op, Value *&ClassVal, uint64_t &ClassMask)
 Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.
 
static InstructionreassociateFCmps (BinaryOperator &BO, InstCombiner::BuilderTy &Builder)
 This a limited reassociation for a special case (see above) where we are checking if two values are either both NAN (unordered) or not-NAN (ordered).
 
static InstructionmatchDeMorgansLaws (BinaryOperator &I, InstCombiner &IC)
 Match variations of De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B))
 
static InstructionfoldLogicCastConstant (BinaryOperator &Logic, CastInst *Cast, InstCombinerImpl &IC)
 Fold {and,or,xor} (cast X), C.
 
static InstructionfoldAndToXor (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static InstructionfoldOrToXor (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static bool canNarrowShiftAmt (Constant *C, unsigned BitWidth)
 Return true if a constant shift amount is always less than the specified bit-width.
 
static InstructionfoldComplexAndOrPatterns (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 Try folding relatively complex patterns for both And and Or operations with all And and Or swapped.
 
static InstructionreassociateForUses (BinaryOperator &BO, InstCombinerImpl::BuilderTy &Builder)
 Try to reassociate a pair of binops so that values with one use only are part of the same instruction.
 
static InstructioncanonicalizeLogicFirst (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static InstructionfoldBitwiseLogicWithIntrinsics (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static ValuesimplifyAndOrWithOpReplaced (Value *V, Value *Op, Value *RepOp, bool SimplifyOnly, InstCombinerImpl &IC, unsigned Depth=0)
 
static InstructionmatchFunnelShift (Instruction &Or, InstCombinerImpl &IC)
 Match UB-safe variants of the funnel shift intrinsic.
 
static ValuematchOrConcat (Instruction &Or, InstCombiner::BuilderTy &Builder)
 Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns.
 
static bool areInverseVectorBitmasks (Constant *C1, Constant *C2)
 If all elements of two constant vectors are 0/-1 and inverses, return true.
 
static ValuefoldAndOrOfICmpEqConstantAndICmp (ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, IRBuilderBase &Builder)
 
static ValuefoldOrOfInversions (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static bool matchSubIntegerPackFromVector (Value *V, Value *&Vec, int64_t &VecOffset, SmallBitVector &Mask, const DataLayout &DL)
 Match V as "shufflevector -> bitcast" or "extractelement -> zext -> shl" patterns, which extract vector elements and pack them in the same relative positions.
 
static InstructionfoldIntegerPackFromVector (Instruction &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
 Try to fold the join of two scalar integers whose contents are packed elements of the same vector.
 
static bool matchZExtedSubInteger (Value *V, Value *&Int, APInt &Mask, uint64_t &Offset, bool &IsShlNUW, bool &IsShlNSW)
 Match V as "lshr -> mask -> zext -> shl".
 
static ValuefoldIntegerRepackThroughZExt (Value *Lhs, Value *Rhs, InstCombiner::BuilderTy &Builder)
 Try to fold the join of two scalar integers whose bits are unpacked and zexted from the same source integer.
 
static std::optional< DecomposedBitMaskMulmatchBitmaskMul (Value *V)
 
static ValuefoldBitmaskMul (Value *Op0, Value *Op1, InstCombiner::BuilderTy &Builder)
 (A & N) * C + (A & M) * C -> (A & (N + M)) & C This also accepts the equivalent select form of (A & N) * C expressions i.e.
 
static ValuefoldOrUnsignedUMulOverflowICmp (BinaryOperator &I, InstCombiner::BuilderTy &Builder, const DataLayout &DL)
 Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2)) --> (ugt x (c2/c1)).
 
static InstructionfoldXorToXor (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 A ^ B can be specified using other logic ops in a variety of patterns.
 
static InstructionvisitMaskedMerge (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 If we have a masked merge, in the canonical form of: (assuming that A only has one use.) | A | |B| ((x ^ y) & M) ^ y | D |.
 
static InstructionfoldNotXor (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 
static InstructioncanonicalizeAbs (BinaryOperator &Xor, InstCombiner::BuilderTy &Builder)
 Canonicalize a shifty way to code absolute value to the more common pattern that uses negation and select.
 
static bool canFreelyInvert (InstCombiner &IC, Value *Op, Instruction *IgnoredUser)
 
static ValuefreelyInvert (InstCombinerImpl &IC, Value *Op, Instruction *IgnoredUser)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 29 of file InstCombineAndOrXor.cpp.

Enumeration Type Documentation

◆ MaskedICmpType

Classify (icmp eq (A & B), C) and (icmp ne (A & B), C) as matching patterns that can be simplified.

One of A and B is considered the mask. The other is the value. This is described as the "AMask" or "BMask" part of the enum. If the enum contains only "Mask", then both A and B can be considered masks. If A is the mask, then it was proven that (A & C) == C. This is trivial if C == A or C == 0. If both A and C are constants, this proof is also easy. For the following explanations, we assume that A is the mask.

"AllOnes" declares that the comparison is true only if (A & B) == A or all bits of A are set in B. Example: (icmp eq (A & 3), 3) -> AMask_AllOnes

"AllZeros" declares that the comparison is true only if (A & B) == 0 or all bits of A are cleared in B. Example: (icmp eq (A & 3), 0) -> Mask_AllZeroes

"Mixed" declares that (A & B) == C and C might or might not contain any number of one bits and zero bits. Example: (icmp eq (A & 3), 1) -> AMask_Mixed

"Not" means that in above descriptions "==" should be replaced by "!=". Example: (icmp ne (A & 3), 3) -> AMask_NotAllOnes

If the mask A contains a single bit, then the following is equivalent: (icmp eq (A & B), A) equals (icmp ne (A & B), 0) (icmp ne (A & B), A) equals (icmp eq (A & B), 0)

Enumerator
AMask_AllOnes 
AMask_NotAllOnes 
BMask_AllOnes 
BMask_NotAllOnes 
Mask_AllZeros 
Mask_NotAllZeros 
AMask_Mixed 
AMask_NotMixed 
BMask_Mixed 
BMask_NotMixed 

Definition at line 107 of file InstCombineAndOrXor.cpp.

Function Documentation

◆ areInverseVectorBitmasks()

static bool areInverseVectorBitmasks ( Constant C1,
Constant C2 
)
static

If all elements of two constant vectors are 0/-1 and inverses, return true.

Definition at line 3185 of file InstCombineAndOrXor.cpp.

References llvm::Constant::getAggregateElement(), llvm::Value::getType(), llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_Zero(), and llvm::PatternMatch::match().

◆ canFreelyInvert()

static bool canFreelyInvert ( InstCombiner IC,
Value Op,
Instruction IgnoredUser 
)
static

◆ canNarrowShiftAmt()

static bool canNarrowShiftAmt ( Constant C,
unsigned  BitWidth 
)
static

Return true if a constant shift amount is always less than the specified bit-width.

If not, the shift could create poison in the narrower type.

Definition at line 1996 of file InstCombineAndOrXor.cpp.

References llvm::BitWidth, llvm::CallingConv::C, llvm::CmpInst::ICMP_ULT, llvm::PatternMatch::m_SpecificInt_ICMP(), and llvm::PatternMatch::match().

◆ canonicalizeAbs()

static Instruction * canonicalizeAbs ( BinaryOperator Xor,
InstCombiner::BuilderTy Builder 
)
static

◆ canonicalizeLogicFirst()

static Instruction * canonicalizeLogicFirst ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ conjugateICmpMask()

static unsigned conjugateICmpMask ( unsigned  Mask)
static

Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite sense.

Since each "NotXXX" flag (recording !=) is adjacent to the corresponding normal flag (recording ==), this just involves swapping those bits over.

Definition at line 172 of file InstCombineAndOrXor.cpp.

References AMask_AllOnes, AMask_Mixed, AMask_NotAllOnes, AMask_NotMixed, BMask_AllOnes, BMask_Mixed, BMask_NotAllOnes, BMask_NotMixed, Mask_AllZeros, and Mask_NotAllZeros.

Referenced by foldLogOpOfMaskedICmps(), and foldLogOpOfMaskedICmpsAsymmetric().

◆ decomposeBitTestICmp()

static bool decomposeBitTestICmp ( Value Cond,
CmpInst::Predicate Pred,
Value *&  X,
Value *&  Y,
Value *&  Z 
)
static

Definition at line 186 of file InstCombineAndOrXor.cpp.

References Cond, llvm::decomposeBitTest(), X, and Y.

◆ extractIntPart()

static Value * extractIntPart ( const IntPart P,
IRBuilderBase Builder 
)
static

Materialize an extraction of bits from an integer in IR.

Definition at line 1173 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateLShr(), llvm::IRBuilderBase::CreateTrunc(), and P.

◆ foldAndOrOfICmpEqConstantAndICmp()

static Value * foldAndOrOfICmpEqConstantAndICmp ( ICmpInst LHS,
ICmpInst RHS,
bool  IsAnd,
bool  IsLogical,
IRBuilderBase Builder 
)
static

◆ foldAndOrOfICmpsWithConstEq()

static Value * foldAndOrOfICmpsWithConstEq ( ICmpInst Cmp0,
ICmpInst Cmp1,
bool  IsAnd,
bool  IsLogical,
InstCombiner::BuilderTy Builder,
const SimplifyQuery Q 
)
static

◆ foldAndOrOfICmpsWithPow2AndWithZero()

static Value * foldAndOrOfICmpsWithPow2AndWithZero ( InstCombiner::BuilderTy Builder,
ICmpInst LHS,
ICmpInst RHS,
bool  IsAnd,
const SimplifyQuery Q 
)
static

◆ foldAndToXor()

static Instruction * foldAndToXor ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldBitmaskMul()

static Value * foldBitmaskMul ( Value Op0,
Value Op1,
InstCombiner::BuilderTy Builder 
)
static

(A & N) * C + (A & M) * C -> (A & (N + M)) & C This also accepts the equivalent select form of (A & N) * C expressions i.e.

!(A & N) ? 0 : N * C)

Definition at line 3924 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateMul(), llvm::Value::getType(), and matchBitmaskMul().

◆ foldBitwiseLogicWithIntrinsics()

static Instruction * foldBitwiseLogicWithIntrinsics ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldComplexAndOrPatterns()

static Instruction * foldComplexAndOrPatterns ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldIntegerPackFromVector()

static Instruction * foldIntegerPackFromVector ( Instruction I,
InstCombiner::BuilderTy Builder,
const DataLayout DL 
)
static

Try to fold the join of two scalar integers whose contents are packed elements of the same vector.

Definition at line 3742 of file InstCombineAndOrXor.cpp.

References assert(), llvm::CastInst::Create(), llvm::IRBuilderBase::CreateShuffleVector(), DL, llvm::Constant::getNullValue(), llvm::Value::getType(), I, Idx, and matchSubIntegerPackFromVector().

Referenced by llvm::InstCombinerImpl::visitOr().

◆ foldIntegerRepackThroughZExt()

static Value * foldIntegerRepackThroughZExt ( Value Lhs,
Value Rhs,
InstCombiner::BuilderTy Builder 
)
static

Try to fold the join of two scalar integers whose bits are unpacked and zexted from the same source integer.

Definition at line 3820 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateShl(), llvm::IRBuilderBase::CreateZExt(), llvm::Value::getName(), llvm::Value::getType(), matchZExtedSubInteger(), and llvm::Value::takeName().

◆ foldIsPowerOf2()

static Value * foldIsPowerOf2 ( ICmpInst Cmp0,
ICmpInst Cmp1,
bool  JoinedByAnd,
InstCombiner::BuilderTy Builder,
InstCombinerImpl IC 
)
static

◆ foldIsPowerOf2OrZero()

static Value * foldIsPowerOf2OrZero ( ICmpInst Cmp0,
ICmpInst Cmp1,
bool  IsAnd,
InstCombiner::BuilderTy Builder,
InstCombinerImpl IC 
)
static

Fold (icmp eq ctpop(X) 1) | (icmp eq X 0) into (icmp ult ctpop(X) 2) and fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1).

Also used for logical and/or, must be poison safe if range attributes are dropped.

Definition at line 939 of file InstCombineAndOrXor.cpp.

References llvm::InstCombiner::addToWorklist(), llvm::IRBuilderBase::CreateICmpUGT(), llvm::IRBuilderBase::CreateICmpULT(), llvm::User::getOperand(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Value(), llvm::MIPatternMatch::m_ZeroInt(), llvm::PatternMatch::match(), and X.

◆ foldLogicCastConstant()

static Instruction * foldLogicCastConstant ( BinaryOperator Logic,
CastInst Cast,
InstCombinerImpl IC 
)
static

◆ foldLogOpOfMaskedICmps()

static Value * foldLogOpOfMaskedICmps ( Value LHS,
Value RHS,
bool  IsAnd,
bool  IsLogical,
InstCombiner::BuilderTy Builder,
const SimplifyQuery Q 
)
static

◆ foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed()

static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed ( Value LHS,
Value RHS,
bool  IsAnd,
Value A,
Value B,
Value D,
Value E,
ICmpInst::Predicate  PredL,
ICmpInst::Predicate  PredR,
InstCombiner::BuilderTy Builder 
)
static

◆ foldLogOpOfMaskedICmpsAsymmetric()

static Value * foldLogOpOfMaskedICmpsAsymmetric ( Value LHS,
Value RHS,
bool  IsAnd,
Value A,
Value B,
Value C,
Value D,
Value E,
ICmpInst::Predicate  PredL,
ICmpInst::Predicate  PredR,
unsigned  LHSMask,
unsigned  RHSMask,
InstCombiner::BuilderTy Builder 
)
static

Try to fold (icmp(A & B) ==/!= 0) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!= Y), where the left-hand side and the right hand side aren't of the common mask pattern type.

Also used for logical and/or, must be poison safe.

Definition at line 499 of file InstCombineAndOrXor.cpp.

References A, assert(), B, BMask_Mixed, llvm::CallingConv::C, conjugateICmpMask(), D, foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(), llvm::ICmpInst::isEquality(), LHS, Mask_NotAllZeros, and RHS.

Referenced by foldLogOpOfMaskedICmps().

◆ foldNegativePower2AndShiftedMask()

static Value * foldNegativePower2AndShiftedMask ( Value A,
Value B,
Value D,
Value E,
ICmpInst::Predicate  PredL,
ICmpInst::Predicate  PredR,
InstCombiner::BuilderTy Builder 
)
static

Try to fold (icmp(A & B) == 0) & (icmp(A & D) != E) into (icmp A u< D) iff B is a contiguous set of ones starting from the most significant bit (negative power of 2), D and E are equal, and D is a contiguous set of ones starting at the most significant zero bit in B.

Parameter B supports masking using undef/poison in either scalar or vector values.

Definition at line 1011 of file InstCombineAndOrXor.cpp.

References A, assert(), B, llvm::APInt::countLeadingOnes(), llvm::APInt::countLeadingZeros(), llvm::IRBuilderBase::CreateICmp(), D, I, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_ULT, llvm::ICmpInst::isEquality(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_APIntAllowPoison(), llvm::PatternMatch::m_NegatedPower2(), llvm::PatternMatch::m_ShiftedMask(), and llvm::PatternMatch::match().

Referenced by foldPowerOf2AndShiftedMask().

◆ foldNotXor()

static Instruction * foldNotXor ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldOrOfInversions()

static Value * foldOrOfInversions ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldOrToXor()

static Instruction * foldOrToXor ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ foldOrUnsignedUMulOverflowICmp()

static Value * foldOrUnsignedUMulOverflowICmp ( BinaryOperator I,
InstCombiner::BuilderTy Builder,
const DataLayout DL 
)
static

Fold Res, Overflow = (umul.with.overflow x c1); (or Overflow (ugt Res c2)) --> (ugt x (c2/c1)).

This code checks whether a multiplication of two unsigned numbers (one is a constant) is mathematically greater than a second constant.

Definition at line 3980 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateICmp(), I, llvm::CmpInst::ICMP_UGT, llvm::APInt::isZero(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_c_Or(), llvm::PatternMatch::m_Deferred(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_SpecificCmp(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::APInt::udiv(), and X.

Referenced by llvm::InstCombinerImpl::visitOr().

◆ foldPowerOf2AndShiftedMask()

static Value * foldPowerOf2AndShiftedMask ( ICmpInst Cmp0,
ICmpInst Cmp1,
bool  JoinedByAnd,
InstCombiner::BuilderTy Builder 
)
static

Try to fold ((icmp X u< P) & (icmp(X & M) != M)) or ((icmp X s> -1) & (icmp(X & M) != M)) into (icmp X u< M).

Where P is a power of 2, M < P, and M is a contiguous shifted mask starting at the right most significant zero bit in P. SGT is supported as when P is the largest representable power of 2, an earlier optimization converts the expression into (icmp X s> -1). Parameter P supports masking using undef/poison in either scalar or vector values.

Definition at line 1077 of file InstCombineAndOrXor.cpp.

References A, B, BMask_NotAllOnes, BMask_NotMixed, llvm::CallingConv::C, D, foldNegativePower2AndShiftedMask(), getMaskedTypeForICmpPair(), and Mask_AllZeros.

◆ foldSignedTruncationCheck()

static Value * foldSignedTruncationCheck ( ICmpInst ICmp0,
ICmpInst ICmp1,
Instruction CxtI,
InstCombiner::BuilderTy Builder 
)
static

General pattern: X & Y.

Where Y is checking that all the high bits (covered by a mask 4294967168) are uniform, i.e. arg & 4294967168 can be either 4294967168 or 0 Pattern can be one of: t = add i32 arg, 128 r = icmp ult i32 t, 256 Or t0 = shl i32 arg, 24 t1 = ashr i32 t0, 24 r = icmp eq i32 t1, arg Or t0 = trunc i32 arg to i8 t1 = sext i8 t0 to i32 r = icmp eq i32 t1, arg This pattern is a signed truncation check.

And X is checking that some bit in that same mask is zero. I.e. can be one of: r = icmp sgt i32 arg, -1 Or t = and i32 arg, 2147483648 r = icmp eq i32 t, 0

Since we are checking that all the bits in that mask are the same, and a particular bit is zero, what we are really checking is that all the masked bits are zero. So this should be transformed to: r = icmp ult i32 arg, 128

Definition at line 843 of file InstCombineAndOrXor.cpp.

References assert(), llvm::IRBuilderBase::CreateICmpULT(), llvm::decomposeBitTestICmp(), llvm::Value::getName(), llvm::Instruction::getOpcode(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::Type::getScalarSizeInBits(), llvm::Value::getType(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_ULT, llvm::APInt::intersects(), llvm::APInt::isPowerOf2(), llvm::APInt::isSubsetOf(), llvm::APInt::isZero(), llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::APInt::shl(), llvm::APIntOps::umin(), X, and llvm::APInt::zext().

◆ foldUnsignedUnderflowCheck()

static Value * foldUnsignedUnderflowCheck ( ICmpInst ZeroICmp,
ICmpInst UnsignedICmp,
bool  IsAnd,
const SimplifyQuery Q,
InstCombiner::BuilderTy Builder 
)
static

◆ foldXorToXor()

static Instruction * foldXorToXor ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

◆ freelyInvert()

static Value * freelyInvert ( InstCombinerImpl IC,
Value Op,
Instruction IgnoredUser 
)
static

◆ getFCmpValue()

static Value * getFCmpValue ( unsigned  Code,
Value LHS,
Value RHS,
InstCombiner::BuilderTy Builder,
FMFSource  FMF 
)
static

This is the complement of getFCmpCode, which turns an opcode and two operands into either a FCmp instruction, or a true/false constant.

Definition at line 45 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateFCmpFMF(), llvm::getPredForFCmpCode(), llvm::Value::getType(), LHS, and RHS.

◆ getMaskedICmpType()

static unsigned getMaskedICmpType ( Value A,
Value B,
Value C,
ICmpInst::Predicate  Pred 
)
static

◆ getMaskedTypeForICmpPair()

static std::optional< std::pair< unsigned, unsigned > > getMaskedTypeForICmpPair ( Value *&  A,
Value *&  B,
Value *&  C,
Value *&  D,
Value *&  E,
Value LHS,
Value RHS,
ICmpInst::Predicate &  PredL,
ICmpInst::Predicate &  PredR 
)
static

Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).

Return the pattern classes (from MaskedICmpType) for the left hand side and the right hand side as a pair. LHS and RHS are the left hand side and the right hand side ICmps and PredL and PredR are their predicates, respectively.

Definition at line 206 of file InstCombineAndOrXor.cpp.

References A, B, llvm::CallingConv::C, D, llvm::decomposeBitTestICmp(), llvm::Constant::getAllOnesValue(), getMaskedICmpType(), llvm::Value::getType(), llvm::ICmpInst::isEquality(), LHS, llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), R2, and RHS.

Referenced by foldLogOpOfMaskedICmps(), and foldPowerOf2AndShiftedMask().

◆ getNewICmpValue()

static Value * getNewICmpValue ( unsigned  Code,
bool  Sign,
Value LHS,
Value RHS,
InstCombiner::BuilderTy Builder 
)
static

This is the complement of getICmpCode, which turns an opcode and two operands into either a constant true or false, or a brand new ICmp instruction.

The sign is passed in to determine which kind of predicate to use in the new icmp instruction.

Definition at line 35 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateICmp(), llvm::getPredForICmpCode(), llvm::Value::getType(), LHS, and RHS.

◆ matchBitmaskMul()

static std::optional< DecomposedBitMaskMul > matchBitmaskMul ( Value V)
static

◆ matchDeMorgansLaws()

static Instruction * matchDeMorgansLaws ( BinaryOperator I,
InstCombiner IC 
)
static

◆ matchFunnelShift()

static Instruction * matchFunnelShift ( Instruction Or,
InstCombinerImpl IC 
)
static

◆ matchIntPart()

static std::optional< IntPart > matchIntPart ( Value V)
static

◆ matchIsFiniteTest()

static Value * matchIsFiniteTest ( InstCombiner::BuilderTy Builder,
FCmpInst LHS,
FCmpInst RHS 
)
static

and (fcmp ord x, 0), (fcmp u* x, inf) -> fcmp o* x, inf

Clang emits this pattern for doing an isfinite check in __builtin_isnormal.

Definition at line 1445 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateFCmpFMF(), llvm::CmpInst::getOrderedPredicate(), llvm::FMFSource::intersect(), LHS, matchIsNotNaN(), matchUnorderedInfCompare(), and RHS.

◆ matchIsFPClassLikeFCmp()

static bool matchIsFPClassLikeFCmp ( Value Op,
Value *&  ClassVal,
uint64_t ClassMask 
)
static

Match an fcmp against a special value that performs a test possible by llvm.is.fpclass.

Definition at line 1591 of file InstCombineAndOrXor.cpp.

References llvm::fcmpToClassTest().

◆ matchIsNotNaN()

static bool matchIsNotNaN ( FCmpInst::Predicate  P,
Value LHS,
Value RHS 
)
static

Matches canonical form of isnan, fcmp ord x, 0.

Definition at line 1432 of file InstCombineAndOrXor.cpp.

References llvm::CmpInst::FCMP_ORD, llvm::PatternMatch::m_AnyZeroFP(), llvm::PatternMatch::match(), P, and RHS.

Referenced by matchIsFiniteTest().

◆ matchOrConcat()

static Value * matchOrConcat ( Instruction Or,
InstCombiner::BuilderTy Builder 
)
static

◆ matchSubIntegerPackFromVector()

static bool matchSubIntegerPackFromVector ( Value V,
Value *&  Vec,
int64_t &  VecOffset,
SmallBitVector Mask,
const DataLayout DL 
)
static

Match V as "shufflevector -> bitcast" or "extractelement -> zext -> shl" patterns, which extract vector elements and pack them in the same relative positions.

Vec is the underlying vector being extracted from. Mask is a bitmask identifying which packed elements are obtained from the vector. VecOffset is the vector element corresponding to index 0 of the mask.

Definition at line 3639 of file InstCombineAndOrXor.cpp.

References DL, llvm::Constant::getAggregateElement(), llvm::Value::getType(), Idx, llvm::PatternMatch::m_BitCast(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_ExtractElt(), llvm::PatternMatch::m_InsertElt(), llvm::PatternMatch::m_Instruction(), llvm::PatternMatch::m_ShlOrSelf(), llvm::PatternMatch::m_Shuffle(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::m_ZExtOrSelf(), llvm::PatternMatch::match(), llvm::PoisonMaskElem, and llvm::ArrayRef< T >::size().

Referenced by foldIntegerPackFromVector().

◆ matchUnorderedInfCompare()

static bool matchUnorderedInfCompare ( FCmpInst::Predicate  P,
Value LHS,
Value RHS 
)
static

Matches fcmp u__ x, +/-inf.

Definition at line 1437 of file InstCombineAndOrXor.cpp.

References llvm::CmpInst::isUnordered(), llvm::PatternMatch::m_Inf(), llvm::PatternMatch::match(), P, and RHS.

Referenced by matchIsFiniteTest().

◆ matchZExtedSubInteger()

static bool matchZExtedSubInteger ( Value V,
Value *&  Int,
APInt Mask,
uint64_t Offset,
bool IsShlNUW,
bool IsShlNSW 
)
static

Match V as "lshr -> mask -> zext -> shl".

Int is the underlying integer being extracted from. Mask is a bitmask identifying which bits of the integer are being extracted. Offset identifies which bit of the result V corresponds to the least significant bit of Int

Definition at line 3779 of file InstCombineAndOrXor.cpp.

References llvm::APInt::getBitsSetFrom(), Int, llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_CombineOr(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_LShr(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Shl(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_ZExt(), llvm::PatternMatch::match(), llvm::Offset, and llvm::APInt::shl().

Referenced by foldIntegerRepackThroughZExt().

◆ reassociateFCmps()

static Instruction * reassociateFCmps ( BinaryOperator BO,
InstCombiner::BuilderTy Builder 
)
static

This a limited reassociation for a special case (see above) where we are checking if two values are either both NAN (unordered) or not-NAN (ordered).

This could be handled more generally in '-reassociation', but it seems like an unlikely pattern for a large number of logic ops and fcmps.

Definition at line 1693 of file InstCombineAndOrXor.cpp.

References assert(), llvm::BinaryOperator::Create(), llvm::IRBuilderBase::CreateFCmpFMF(), llvm::CmpInst::FCMP_ORD, llvm::CmpInst::FCMP_UNO, llvm::BinaryOperator::getOpcode(), llvm::User::getOperand(), llvm::FMFSource::intersect(), llvm::PatternMatch::m_AnyZeroFP(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_FCmp(), llvm::PatternMatch::m_SpecificFCmp(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), std::swap(), X, and Y.

Referenced by llvm::InstCombinerImpl::visitAnd(), and llvm::InstCombinerImpl::visitOr().

◆ reassociateForUses()

static Instruction * reassociateForUses ( BinaryOperator BO,
InstCombinerImpl::BuilderTy &  Builder 
)
static

Try to reassociate a pair of binops so that values with one use only are part of the same instruction.

This may enable folds that are limited with multi-use restrictions and makes it more likely to match other patterns that are looking for a common operand.

Definition at line 2185 of file InstCombineAndOrXor.cpp.

References llvm::BinaryOperator::Create(), llvm::IRBuilderBase::CreateBinOp(), llvm::BinaryOperator::getOpcode(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_c_BinOp(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), X, and Y.

Referenced by llvm::InstCombinerImpl::visitAnd(), llvm::InstCombinerImpl::visitOr(), and llvm::InstCombinerImpl::visitXor().

◆ simplifyAndOrWithOpReplaced()

static Value * simplifyAndOrWithOpReplaced ( Value V,
Value Op,
Value RepOp,
bool  SimplifyOnly,
InstCombinerImpl IC,
unsigned  Depth = 0 
)
static

◆ stripSignOnlyFPOps()

static Value * stripSignOnlyFPOps ( Value Val)
static

Ignore all operations which only change the sign of a value, returning the underlying magnitude value.

Definition at line 1424 of file InstCombineAndOrXor.cpp.

References llvm::PatternMatch::m_CopySign(), llvm::PatternMatch::m_FAbs(), llvm::PatternMatch::m_FNeg(), llvm::PatternMatch::m_Value(), and llvm::PatternMatch::match().

◆ visitMaskedMerge()

static Instruction * visitMaskedMerge ( BinaryOperator I,
InstCombiner::BuilderTy Builder 
)
static

If we have a masked merge, in the canonical form of: (assuming that A only has one use.) | A | |B| ((x ^ y) & M) ^ y | D |.

  • If M is inverted: | D | ((x ^ y) & ~M) ^ y We can canonicalize by swapping the final xor operand to eliminate the 'not' of the mask. ((x ^ y) & M) ^ x
  • If M is a constant, and D has one use, we transform to 'and' / 'or' ops because that shortens the dependency chain and improves analysis: (x & M) | (y & ~M)

Definition at line 4752 of file InstCombineAndOrXor.cpp.

References B, llvm::CallingConv::C, llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateNot(), D, llvm::Constant::getAllOnesValue(), I, LHS, llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_c_Xor(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_Deferred(), llvm::MIPatternMatch::m_Not(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::Constant::replaceUndefsWith(), RHS, and X.

Referenced by llvm::InstCombinerImpl::visitXor().