LLVM  8.0.1
Macros | Enumerations | Functions
InstCombineAndOrXor.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/PatternMatch.h"
Include dependency graph for InstCombineAndOrXor.cpp:

Go to the source code of this file.

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, llvm::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, llvm::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, llvm::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 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 InstructionmatchRotate (Instruction &Or)
 Transform UB-safe variants of bitwise rotate to the funnel shift intrinsic. 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)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 24 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 218 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 1865 of file InstCombineAndOrXor.cpp.

References assert(), B, C, llvm::ComputeNumSignBits(), D, llvm::dyn_cast(), foldAndOrOfEqualityCmpsWithConstants(), foldLogOpOfMaskedICmps(), llvm::ConstantInt::get(), llvm::Constant::getAggregateElement(), llvm::getICmpCode(), getNewICmpValue(), llvm::ConstantExpr::getNot(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::Type::getScalarSizeInBits(), llvm::ConstantInt::getSigned(), llvm::ConstantExpr::getTrunc(), llvm::ConstantInt::getType(), llvm::Value::getType(), llvm::ConstantInt::getValue(), llvm::Type::getVectorNumElements(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_UGE, llvm::CmpInst::ICMP_UGT, llvm::CmpInst::ICMP_ULE, llvm::CmpInst::ICMP_ULT, llvm::ICmpInst::isEquality(), llvm::Type::isIntOrIntVectorTy(), llvm::APInt::isPowerOf2(), llvm::CmpInst::isSigned(), llvm::Type::isVectorTy(), llvm::ConstantInt::isZero(), llvm_unreachable, llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_SExt(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Xor(), llvm::PatternMatch::m_Zero(), llvm::CmpInst::makeCmpResultType(), llvm::PatternMatch::match(), llvm::peekThroughBitcast(), llvm::predicatesFoldable(), llvm::MCID::Select, llvm::APInt::sgt(), std::swap(), llvm::ICmpInst::swapOperands(), llvm::APInt::ugt(), and llvm::APInt::ult().

◆ canNarrowShiftAmt()

static bool canNarrowShiftAmt ( Constant C,
unsigned  BitWidth 
)
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 282 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

◆ foldAndOrOfEqualityCmpsWithConstants()

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

◆ foldAndToXor()

static Instruction* foldAndToXor ( BinaryOperator I,
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,
llvm::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,
llvm::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 444 of file InstCombineAndOrXor.cpp.

References assert(), B, C, llvm::IRBuilder< T, Inserter >::CreateAnd(), llvm::IRBuilder< T, Inserter >::CreateICmp(), D, llvm::dyn_cast(), E, llvm::ConstantInt::get(), llvm::ConstantInt::getType(), llvm::Value::getType(), llvm::ConstantInt::getValue(), llvm::ConstantExpr::getXor(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, and llvm::ConstantInt::isZero().

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,
llvm::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 574 of file InstCombineAndOrXor.cpp.

References assert(), BMask_Mixed, conjugateICmpMask(), 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 931 of file InstCombineAndOrXor.cpp.

References llvm::AddOne(), assert(), llvm::IRBuilder< T, Inserter >::CreateICmpULT(), llvm::decomposeBitTestICmp(), llvm::dyn_cast(), llvm::CmpInst::FCMP_ORD, llvm::CmpInst::FCMP_UNO, foldAndOrOfEqualityCmpsWithConstants(), foldLogOpOfMaskedICmps(), llvm::ConstantInt::get(), llvm::IntegerType::getBitWidth(), llvm::Type::getContext(), getFCmpCode(), getFCmpValue(), llvm::getICmpCode(), llvm::APInt::getLowBitsSet(), llvm::Value::getName(), getNewICmpValue(), llvm::Instruction::getOpcode(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::Type::getScalarSizeInBits(), llvm::CmpInst::getSwappedPredicate(), llvm::ConstantInt::getType(), llvm::Value::getType(), llvm::ConstantInt::getValue(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_UGE, llvm::CmpInst::ICMP_UGT, llvm::CmpInst::ICMP_ULE, llvm::CmpInst::ICMP_ULT, llvm::APInt::intersects(), llvm::ICmpInst::isEquality(), llvm::APInt::isNullValue(), llvm::APInt::isPowerOf2(), llvm::CmpInst::isSigned(), llvm::APInt::isSubsetOf(), llvm::ConstantInt::isZero(), llvm_unreachable, llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_ConstantInt(), llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_PosZeroFP(), 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(), N, llvm::predicatesFoldable(), llvm::APInt::sgt(), llvm::APInt::shl(), llvm::SubOne(), std::swap(), llvm::ICmpInst::swapOperands(), llvm::APInt::ugt(), llvm::APIntOps::umin(), X, and llvm::APInt::zext().

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

References assert(), llvm::IRBuilder< T, Inserter >::CreateFCmp(), llvm::CmpInst::FCMP_FALSE, llvm::CmpInst::FCMP_TRUE, llvm::ConstantInt::get(), llvm::Value::getType(), and llvm::CmpInst::makeCmpResultType().

Referenced by foldSignedTruncationCheck().

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

References llvm::decomposeBitTestICmp(), llvm::Constant::getAllOnesValue(), getMaskedICmpType(), llvm::User::getOperand(), llvm::Value::getType(), llvm::ICmpInst::isEquality(), llvm::Type::isIntegerTy(), 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 56 of file InstCombineAndOrXor.cpp.

References llvm::IRBuilder< T, Inserter >::CreateICmp(), llvm::getPredForICmpCode(), and llvm::Value::getType().

Referenced by areInverseVectorBitmasks(), foldSignedTruncationCheck(), and foldXorToXor().

◆ matchDeMorgansLaws()

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

◆ matchRotate()

static Instruction* matchRotate ( Instruction Or)
static

◆ SimplifyBSwap()

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

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

References B, C, llvm::IRBuilder< T, Inserter >::CreateAnd(), llvm::IRBuilder< T, Inserter >::CreateNot(), D, llvm::Value::hasOneUse(), 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(), and X.

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