LLVM  14.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"
Include dependency graph for InstCombineAndOrXor.cpp:

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 unsigned getFCmpCode (FCmpInst::Predicate CC)
 Similar to getICmpCode but for FCmpInst. More...
 
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. More...
 
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. More...
 
static ValueSimplifyBSwap (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 Transform BITWISE_OP(BSWAP(A),BSWAP(B)) or BITWISE_OP(BSWAP(A), Constant) to BSWAP(BITWISE_OP(A, B)) More...
 
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. More...
 
static unsigned conjugateICmpMask (unsigned Mask)
 Convert an analysis of a masked ICmp into its equivalent if all boolean operations had the opposite sense. More...
 
static bool decomposeBitTestICmp (Value *LHS, Value *RHS, CmpInst::Predicate &Pred, Value *&X, Value *&Y, Value *&Z)
 
static 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). More...
 
static ValuefoldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed (ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, Value *A, Value *B, Value *C, 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. More...
 
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. More...
 
static ValuefoldLogOpOfMaskedICmps (ICmpInst *LHS, ICmpInst *RHS, bool IsAnd, InstCombiner::BuilderTy &Builder)
 Try to fold (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) into a single (icmp(A & X) ==/!= Y). More...
 
static ValuefoldAndOrOfEqualityCmpsWithConstants (ICmpInst *LHS, ICmpInst *RHS, bool JoinedByAnd, InstCombiner::BuilderTy &Builder)
 
static ValuefoldSignedTruncationCheck (ICmpInst *ICmp0, ICmpInst *ICmp1, Instruction &CxtI, InstCombiner::BuilderTy &Builder)
 General pattern: X & Y. More...
 
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. More...
 
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. More...
 
static Optional< IntPartmatchIntPart (Value *V)
 Match an extraction of bits from an integer. More...
 
static ValueextractIntPart (const IntPart &P, IRBuilderBase &Builder)
 Materialize an extraction of bits from an integer in IR. More...
 
static ValuefoldAndOrOfICmpsWithConstEq (ICmpInst *Cmp0, ICmpInst *Cmp1, BinaryOperator &Logic, InstCombiner::BuilderTy &Builder, const SimplifyQuery &Q)
 Reduce logic-of-compares with equality to a constant by substituting a common operand with the constant. More...
 
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). More...
 
static InstructionmatchDeMorgansLaws (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 Match De Morgan's Laws: (~A & ~B) == (~(A | B)) (~A | ~B) == (~(A & B)) More...
 
static InstructionfoldLogicCastConstant (BinaryOperator &Logic, CastInst *Cast, InstCombiner::BuilderTy &Builder)
 Fold {and,or,xor} (cast X), C. More...
 
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. More...
 
static InstructionmatchFunnelShift (Instruction &Or, InstCombinerImpl &IC)
 Match UB-safe variants of the funnel shift intrinsic. More...
 
static InstructionmatchOrConcat (Instruction &Or, InstCombiner::BuilderTy &Builder)
 Attempt to combine or(zext(x),shl(zext(y),bw/2) concat packing patterns. More...
 
static bool areInverseVectorBitmasks (Constant *C1, Constant *C2)
 If all elements of two constant vectors are 0/-1 and inverses, return true. More...
 
static InstructionfoldXorToXor (BinaryOperator &I, InstCombiner::BuilderTy &Builder)
 A ^ B can be specified using other logic ops in a variety of patterns. More...
 
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 |. More...
 
static InstructionsinkNotIntoXor (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. More...
 

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 171 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 2260 of file InstCombineAndOrXor.cpp.

References C1, llvm::Constant::getAggregateElement(), i, llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_Zero(), and llvm::PatternMatch::match().

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

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

◆ canonicalizeAbs()

static Instruction* canonicalizeAbs ( BinaryOperator Xor,
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 235 of file InstCombineAndOrXor.cpp.

References AMask_AllOnes, AMask_Mixed, AMask_NotAllOnes, AMask_NotMixed, BMask_AllOnes, BMask_Mixed, BMask_NotAllOnes, BMask_NotMixed, llvm::BitmaskEnumDetail::Mask(), 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

◆ extractIntPart()

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

Materialize an extraction of bits from an integer in IR.

Definition at line 1103 of file InstCombineAndOrXor.cpp.

References Builder, llvm::Value::getType(), llvm::Type::getWithNewBitWidth(), and P.

◆ foldAndOrOfEqualityCmpsWithConstants()

static Value* foldAndOrOfEqualityCmpsWithConstants ( ICmpInst LHS,
ICmpInst RHS,
bool  JoinedByAnd,
InstCombiner::BuilderTy Builder 
)
static

◆ foldAndOrOfICmpsWithConstEq()

static Value* foldAndOrOfICmpsWithConstEq ( ICmpInst Cmp0,
ICmpInst Cmp1,
BinaryOperator Logic,
InstCombiner::BuilderTy Builder,
const SimplifyQuery Q 
)
static

Reduce logic-of-compares with equality to a constant by substituting a common operand with the constant.

Callers are expected to call this with Cmp0/Cmp1 switched to handle logic op commutativity.

Definition at line 1162 of file InstCombineAndOrXor.cpp.

References assert(), Builder, llvm::BinaryOperator::getOpcode(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::isGuaranteedNotToBeUndefOrPoison(), llvm::PatternMatch::m_c_ICmp(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::SimplifyICmpInst(), X, and Y.

◆ foldAndToXor()

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

◆ foldIsPowerOf2()

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

◆ foldLogicCastConstant()

static Instruction* foldLogicCastConstant ( BinaryOperator Logic,
CastInst Cast,
InstCombiner::BuilderTy Builder 
)
static

◆ foldLogOpOfMaskedICmps()

static Value* foldLogOpOfMaskedICmps ( ICmpInst LHS,
ICmpInst RHS,
bool  IsAnd,
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 C,
Value D,
Value E,
ICmpInst::Predicate  PredL,
ICmpInst::Predicate  PredR,
InstCombiner::BuilderTy Builder 
)
static

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.

For example, (icmp (A & 12) != 0) & (icmp (A & 15) == 8) -> (icmp (A & 15) == 8).

Definition at line 397 of file InstCombineAndOrXor.cpp.

References assert(), B, Builder, C1, D, E, llvm::ConstantInt::get(), llvm::ConstantInt::getType(), llvm::Value::getType(), llvm::ConstantInt::getValue(), llvm::ConstantExpr::getXor(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::ConstantInt::isZero(), llvm::PatternMatch::m_ConstantInt(), and llvm::PatternMatch::match().

Referenced by foldLogOpOfMaskedICmpsAsymmetric().

◆ 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.

Definition at line 518 of file InstCombineAndOrXor.cpp.

References assert(), B, BMask_Mixed, Builder, conjugateICmpMask(), D, E, foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed(), llvm::ICmpInst::isEquality(), and Mask_NotAllZeros.

Referenced by foldLogOpOfMaskedICmps().

◆ foldOrToXor()

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

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

References assert(), Builder, llvm::decomposeBitTestICmp(), llvm::ConstantInt::get(), 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::isNullValue(), llvm::APInt::isPowerOf2(), llvm::APInt::isSubsetOf(), 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_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::BitmaskEnumDetail::Mask(), llvm::PatternMatch::match(), llvm::APInt::shl(), llvm::APInt::ugt(), 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

◆ getFCmpCode()

static unsigned getFCmpCode ( FCmpInst::Predicate  CC)
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 67 of file InstCombineAndOrXor.cpp.

References assert(), Builder, llvm::CmpInst::FCMP_FALSE, llvm::CmpInst::FCMP_TRUE, llvm::ConstantInt::get(), llvm::Value::getType(), and llvm::CmpInst::makeCmpResultType().

◆ getMaskedICmpType()

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

◆ getMaskedTypeForICmpPair()

static 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 267 of file InstCombineAndOrXor.cpp.

References assert(), B, D, llvm::decomposeBitTestICmp(), E, llvm::Constant::getAllOnesValue(), getMaskedICmpType(), llvm::User::getOperand(), llvm::Value::getType(), llvm::ICmpInst::isEquality(), llvm::Type::isIntegerTy(), L2, llvm::PatternMatch::m_And(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::None, and R2.

Referenced by foldLogOpOfMaskedICmps().

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

References Builder, llvm::getPredForICmpCode(), and llvm::Value::getType().

◆ matchDeMorgansLaws()

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

◆ matchFunnelShift()

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

◆ matchIntPart()

static Optional<IntPart> matchIntPart ( Value V)
static

◆ matchOrConcat()

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

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

References assert(), Builder, llvm::BinaryOperator::Create(), 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_Value(), llvm::PatternMatch::match(), std::swap(), X, and Y.

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

◆ SimplifyBSwap()

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

Transform BITWISE_OP(BSWAP(A),BSWAP(B)) or BITWISE_OP(BSWAP(A), Constant) to BSWAP(BITWISE_OP(A, B))

Parameters
IBinary operator to transform.
Returns
Pointer to node that must replace the original binary operator, or null pointer if no transformation was made.

Definition at line 84 of file InstCombineAndOrXor.cpp.

References assert(), Builder, F, llvm::ConstantInt::get(), llvm::Intrinsic::getDeclaration(), llvm::Value::hasOneUse(), I, llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_BSwap(), llvm::PatternMatch::m_Value(), and llvm::PatternMatch::match().

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

◆ sinkNotIntoXor()

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

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

References B, Builder, D, llvm::Constant::getAllOnesValue(), llvm::Type::getScalarType(), I, M, 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(), and X.

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