LLVM 20.0.0git
Classes | Macros | Enumerations | Functions
InstCombineAndOrXor.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/ConstantRange.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
 

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)
 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 *LHS, Value *RHS, 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, ICmpInst *LHS, ICmpInst *RHS, ICmpInst::Predicate &PredL, ICmpInst::Predicate &PredR)
 Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
 
static ValuefoldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed (ICmpInst *LHS, ICmpInst *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 (ICmpInst *LHS, ICmpInst *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 (ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, bool IsLogical, InstCombiner::BuilderTy &Builder)
 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)
 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)
 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 InstructionmatchOrConcat (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 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 25 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 103 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 3101 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 1912 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 168 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 LHS,
Value RHS,
CmpInst::Predicate Pred,
Value *&  X,
Value *&  Y,
Value *&  Z 
)
static

Definition at line 182 of file InstCombineAndOrXor.cpp.

References llvm::decomposeBitTestICmp(), LHS, RHS, 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 1146 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

◆ foldBitwiseLogicWithIntrinsics()

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

◆ foldComplexAndOrPatterns()

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

◆ foldIsPowerOf2()

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

◆ foldIsPowerOf2OrZero()

static Value * foldIsPowerOf2OrZero ( ICmpInst Cmp0,
ICmpInst Cmp1,
bool  IsAnd,
InstCombiner::BuilderTy Builder 
)
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.

Definition at line 928 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateICmpUGT(), llvm::IRBuilderBase::CreateICmpULT(), llvm::User::getOperand(), llvm::Value::getType(), 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::PatternMatch::m_ZeroInt(), llvm::PatternMatch::match(), and X.

◆ foldLogicCastConstant()

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

◆ foldLogOpOfMaskedICmps()

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

◆ foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed()

static Value * foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed ( ICmpInst LHS,
ICmpInst 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 ( ICmpInst LHS,
ICmpInst 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 470 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 983 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

◆ 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 1049 of file InstCombineAndOrXor.cpp.

References A, B, BMask_NotAllOnes, BMask_NotMixed, llvm::CallingConv::C, D, foldNegativePower2AndShiftedMask(), getMaskedTypeForICmpPair(), llvm::CmpInst::getPredicate(), 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 831 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_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), 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 
)
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 41 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateFCmp(), 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,
ICmpInst LHS,
ICmpInst 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 198 of file InstCombineAndOrXor.cpp.

References A, assert(), B, llvm::CallingConv::C, D, llvm::decomposeBitTestICmp(), llvm::Constant::getAllOnesValue(), getMaskedICmpType(), llvm::Value::getType(), llvm::ICmpInst::isEquality(), llvm::Type::isIntOrIntVectorTy(), LHS, 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 31 of file InstCombineAndOrXor.cpp.

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

◆ 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 1370 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilderBase::CreateFCmp(), llvm::CmpInst::getOrderedPredicate(), LHS, matchIsNotNaN(), matchUnorderedInfCompare(), RHS, and llvm::IRBuilderBase::setFastMathFlags().

◆ 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 1519 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 1357 of file InstCombineAndOrXor.cpp.

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

Referenced by matchIsFiniteTest().

◆ matchOrConcat()

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

◆ matchUnorderedInfCompare()

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

Matches fcmp u__ x, +/-inf.

Definition at line 1362 of file InstCombineAndOrXor.cpp.

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

Referenced by matchIsFiniteTest().

◆ 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 1621 of file InstCombineAndOrXor.cpp.

References assert(), llvm::BinaryOperator::Create(), llvm::IRBuilderBase::CreateFCmp(), llvm::CmpInst::FCMP_ORD, llvm::CmpInst::FCMP_UNO, llvm::BinaryOperator::getOpcode(), llvm::User::getOperand(), 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 2103 of file InstCombineAndOrXor.cpp.

References llvm::BinaryOperator::Create(), llvm::IRBuilderBase::CreateBinOp(), llvm::BinaryOperator::getOpcode(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_c_BinOp(), llvm::PatternMatch::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 1349 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 4247 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_CombineAnd(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::Constant::replaceUndefsWith(), RHS, and X.

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