LLVM  6.0.0svn
Macros | Functions
InstCombineSelect.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
Include dependency graph for InstCombineSelect.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "instcombine"
 

Functions

static SelectPatternFlavor getInverseMinMaxSelectPattern (SelectPatternFlavor SPF)
 
static CmpInst::Predicate getCmpPredicateForMinMax (SelectPatternFlavor SPF, bool Ordered=false)
 
static ValuegenerateMinMaxSelectPattern (InstCombiner::BuilderTy &Builder, SelectPatternFlavor SPF, Value *A, Value *B)
 
static ValuefoldSelectICmpAnd (Type *SelType, const ICmpInst *IC, APInt TrueVal, APInt FalseVal, InstCombiner::BuilderTy &Builder)
 If one of the constants is zero (we know they can't both be) and we have an icmp instruction with zero, and we have an 'and' with the non-constant value and a power of two we can turn the select into a shift on the result of the 'and'. More...
 
static unsigned getSelectFoldableOperands (BinaryOperator *I)
 We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond, B, 0 D = or A, C. More...
 
static APInt getSelectFoldableConstant (BinaryOperator *I)
 For the same transformation as the previous function, return the identity constant that goes into the select. More...
 
static bool isSelect01 (const APInt &C1I, const APInt &C2I)
 
static ValuefoldSelectICmpAndOr (const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
 We want to turn: (select (icmp eq (and X, C1), 0), Y, (or Y, C2)) into: (or (shl (and X, C1), C3), Y) iff: C1 and C2 are both powers of 2 where: C3 = Log(C2) - Log(C1) More...
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 25 of file InstCombineSelect.cpp.

Function Documentation

◆ foldSelectICmpAnd()

static Value* foldSelectICmpAnd ( Type SelType,
const ICmpInst IC,
APInt  TrueVal,
APInt  FalseVal,
InstCombiner::BuilderTy Builder 
)
static

If one of the constants is zero (we know they can't both be) and we have an icmp instruction with zero, and we have an 'and' with the non-constant value and a power of two we can turn the select into a shift on the result of the 'and'.

This folds: select (icmp eq (and X, C1)), C2, C3 iff C1 is a power 2 and the difference between C2 and C3 is a power of 2. To something like: (shr (and (X, C1)), (log2(C1) - log2(C2-C3))) + C3 Or: (shl (and (X, C1)), (log2(C2-C3) - log2(C1))) + C3 With some variations depending if C3 is larger than C2, or the shift isn't needed, or the bit widths don't match.

Definition at line 86 of file InstCombineSelect.cpp.

References assert(), llvm::IRBuilder< T, Inserter >::CreateAdd(), llvm::IRBuilder< T, Inserter >::CreateAnd(), llvm::IRBuilder< T, Inserter >::CreateLShr(), llvm::IRBuilder< T, Inserter >::CreateShl(), llvm::IRBuilder< T, Inserter >::CreateXor(), llvm::IRBuilder< T, Inserter >::CreateZExtOrTrunc(), llvm::decomposeBitTestICmp(), llvm::ConstantInt::get(), llvm::APInt::getBitWidth(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::Value::getType(), llvm::CmpInst::ICMP_NE, llvm::ICmpInst::isEquality(), llvm::Type::isIntOrIntVectorTy(), llvm::APInt::isNullValue(), llvm::APInt::isPowerOf2(), llvm::Type::isVectorTy(), llvm::APInt::logBase2(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), and llvm::PatternMatch::match().

Referenced by foldSelectICmpAndOr().

◆ foldSelectICmpAndOr()

static Value* foldSelectICmpAndOr ( const ICmpInst IC,
Value TrueVal,
Value FalseVal,
InstCombiner::BuilderTy Builder 
)
static

We want to turn: (select (icmp eq (and X, C1), 0), Y, (or Y, C2)) into: (or (shl (and X, C1), C3), Y) iff: C1 and C2 are both powers of 2 where: C3 = Log(C2) - Log(C1)

This transform handles cases where:

  1. The icmp predicate is inverted
  2. The select operands are reversed
  3. The magnitude of C2 and C1 are flipped

Definition at line 418 of file InstCombineSelect.cpp.

References llvm::MCID::Add, llvm::any_of(), assert(), B, C, llvm::Instruction::clone(), llvm::computeKnownBits(), llvm::CastInst::Create(), llvm::SelectInst::Create(), CreateAdd(), llvm::IRBuilder< T, Inserter >::CreateAdd(), llvm::IRBuilder< T, Inserter >::CreateAnd(), llvm::IRBuilder< T, Inserter >::CreateAShr(), llvm::CastInst::CreateBitOrPointerCast(), llvm::IRBuilder< T, Inserter >::CreateCast(), llvm::IRBuilder< T, Inserter >::CreateFCmp(), llvm::IRBuilder< T, Inserter >::CreateFNeg(), llvm::IRBuilder< T, Inserter >::CreateICmp(), llvm::IRBuilder< T, Inserter >::CreateICmpSLT(), llvm::IRBuilder< T, Inserter >::CreateICmpULT(), llvm::IRBuilder< T, Inserter >::CreateLShr(), llvm::IRBuilder< T, Inserter >::CreateNeg(), llvm::IRBuilder< T, Inserter >::CreateNot(), llvm::IRBuilder< T, Inserter >::CreateOr(), llvm::IRBuilder< T, Inserter >::CreateSelect(), llvm::IRBuilder< T, Inserter >::CreateShl(), llvm::IRBuilder< T, Inserter >::CreateXor(), llvm::IRBuilder< T, Inserter >::CreateZExtOrTrunc(), D, llvm::decomposeBitTestICmp(), llvm::dyn_cast(), llvm::CmpInst::FCMP_OEQ, llvm::CmpInst::FCMP_UNE, llvm::SelectPatternResult::Flavor, foldSelectICmpAnd(), generateMinMaxSelectPattern(), llvm::ConstantInt::get(), llvm::ConstantVector::get(), llvm::Constant::getAggregateElement(), llvm::APInt::getAllOnesValue(), llvm::APInt::getBitWidth(), llvm::ConstantExpr::getCast(), getCmpPredicateForMinMax(), llvm::SelectInst::getCondition(), llvm::Value::getContext(), llvm::ConstantInt::getFalse(), llvm::SelectInst::getFalseValue(), llvm::Instruction::getFastMathFlags(), llvm::Type::getInt32Ty(), getInverseMinMaxSelectPattern(), llvm::CmpInst::getInversePredicate(), llvm::Value::getName(), llvm::BinaryOperator::getNotArgument(), llvm::Constant::getNullValue(), llvm::APInt::getOneBitSet(), llvm::Instruction::getOpcode(), llvm::User::getOperand(), llvm::Instruction::getParent(), llvm::CmpInst::getPredicate(), llvm::Type::getScalarSizeInBits(), llvm::Type::getScalarType(), llvm::ConstantExpr::getSExt(), llvm::APInt::getSignedMinValue(), llvm::BasicBlock::getSinglePredecessor(), llvm::CmpInst::getSwappedPredicate(), llvm::ConstantInt::getTrue(), llvm::SelectInst::getTrueValue(), llvm::ConstantExpr::getTrunc(), llvm::Value::getType(), llvm::ConstantFP::getValueAPF(), llvm::Type::getVectorNumElements(), llvm::ConstantExpr::getZExt(), llvm::Value::hasNUses(), llvm::Value::hasNUsesOrMore(), llvm::Value::hasOneUse(), I, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLT, llvm::CmpInst::ICMP_UGT, llvm::CmpInst::ICMP_ULT, llvm::IRBuilder< T, Inserter >::Insert(), Int32Ty, llvm::APInt::isAllOnesValue(), llvm::isCanonicalPredicate(), llvm::ICmpInst::isEquality(), llvm::Type::isFPOrFPVectorTy(), llvm::IsFreeToInvert(), llvm::isImpliedCondition(), llvm::Type::isIntOrIntVectorTy(), llvm::CmpInst::isIntPredicate(), llvm::SelectPatternResult::isMinOrMax(), llvm::BinaryOperator::isNot(), llvm::Constant::isNullValue(), llvm::Constant::isOneValue(), llvm::APInt::isOneValue(), llvm::APInt::isSignMask(), llvm::CmpInst::isUnordered(), llvm::CmpInst::isUnsigned(), llvm::Type::isVectorTy(), llvm::APFloat::isZero(), llvm::APInt::logBase2(), llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_BitCast(), llvm::PatternMatch::m_Cmp(), llvm::PatternMatch::m_Constant(), llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_Instruction(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_One(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Or(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_SExt(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Xor(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::m_ZExt(), llvm::BitmaskEnumDetail::Mask(), llvm::PatternMatch::match(), llvm::matchSelectPattern(), llvm::Instruction::moveBefore(), NeedAnd, llvm::KnownBits::One, llvm::SelectPatternResult::Ordered, llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), llvm::User::replaceUsesOfWith(), llvm::SmallVectorImpl< T >::reserve(), llvm::CallInst::setArgOperand(), llvm::SelectInst::setCondition(), llvm::SelectInst::setFalseValue(), llvm::IRBuilderBase::setFastMathFlags(), llvm::Instruction::setFastMathFlags(), llvm::User::setOperand(), llvm::CmpInst::setPredicate(), llvm::SelectInst::setTrueValue(), llvm::APInt::sge(), llvm::APInt::sgt(), SI, llvm::SimplifySelectInst(), llvm::APInt::sle(), llvm::APInt::slt(), llvm::SPF_ABS, llvm::SPF_NABS, llvm::SPF_SMAX, llvm::SPF_SMIN, llvm::SPF_UMAX, llvm::SPF_UMIN, std::swap(), llvm::Instruction::swapProfMetadata(), llvm::APInt::uge(), llvm::APInt::ugt(), llvm::APInt::ule(), llvm::APInt::ult(), llvm::Value::user_begin(), llvm::Value::users(), llvm::InstCombiner::visitSelectInst(), X, Y, and llvm::KnownBits::Zero.

◆ generateMinMaxSelectPattern()

static Value* generateMinMaxSelectPattern ( InstCombiner::BuilderTy Builder,
SelectPatternFlavor  SPF,
Value A,
Value B 
)
static

◆ getCmpPredicateForMinMax()

static CmpInst::Predicate getCmpPredicateForMinMax ( SelectPatternFlavor  SPF,
bool  Ordered = false 
)
static

◆ getInverseMinMaxSelectPattern()

static SelectPatternFlavor getInverseMinMaxSelectPattern ( SelectPatternFlavor  SPF)
static

◆ getSelectFoldableConstant()

static APInt getSelectFoldableConstant ( BinaryOperator I)
static

◆ getSelectFoldableOperands()

static unsigned getSelectFoldableOperands ( BinaryOperator I)
static

We want to turn code that looks like this: C = or A, B D = select cond, C, A into: C = select cond, B, 0 D = or A, C.

Assuming that the specified instruction is an operand to the select, return a bitmask indicating which operands of this instruction are foldable if they equal the other incoming value of the select.

Definition at line 189 of file InstCombineSelect.cpp.

References llvm::MCID::Add, and llvm::BinaryOperator::getOpcode().

Referenced by isSelect01().

◆ isSelect01()

static bool isSelect01 ( const APInt C1I,
const APInt C2I 
)
static