LLVM 22.0.0git
InstCombineSelect.cpp File Reference

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "instcombine"

Functions

static InstructionfoldSelectBinOpIdentity (SelectInst &Sel, const TargetLibraryInfo &TLI, InstCombinerImpl &IC)
 Replace a select operand based on an equality comparison with the identity constant of a binop.
static ValuefoldSelectICmpAnd (SelectInst &Sel, Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)
 This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC and FC is a power-of-2.
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.
static bool isSelect01 (const APInt &C1I, const APInt &C2I)
static ValuefoldSelectICmpMinMax (const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
 Try to fold a select to a min/max intrinsic.
static InstructionfoldSelectICmpAndAnd (Type *SelType, const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
 We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (and X, (or Y, (shl 1, Z))), 0) Note: Z may be 0 if lshr is missing.
static ValuefoldSelectICmpAndZeroShl (const ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
 We want to turn: (select (icmp eq (and X, C1), 0), 0, (shl [nsw/nuw] X, C2)); iff C1 is a mask and the number of its leading zeros is equal to C2 into: shl X, C2.
static ValuefoldSelectICmpLshrAshr (const ICmpInst *IC, Value *TrueVal, Value *FalseVal, InstCombiner::BuilderTy &Builder)
 We want to turn: (select (icmp sgt x, C), lshr (X, Y), ashr (X, Y)); iff C s>= -1 (select (icmp slt x, C), ashr (X, Y), lshr (X, Y)); iff C s>= 0 into: ashr (X, Y)
static ValuefoldSelectICmpAndBinOp (Value *CondVal, Value *TrueVal, Value *FalseVal, Value *V, const APInt &AndMask, bool CreateAnd, InstCombiner::BuilderTy &Builder)
 We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y, (shl (and X, C1), C3)) ELSE (BinOp Y, (lshr (and X, C1), C3)) iff: 0 on the RHS is the identity value (i.e add, xor, shl, etc...) C1 and C2 are both powers of 2 where: IF C2 u>= C1 C3 = Log(C2) - Log(C1) ELSE C3 = Log(C1) - Log(C2)
static InstructionfoldSetClearBits (SelectInst &Sel, InstCombiner::BuilderTy &Builder)
 Canonicalize a set or clear of a masked set of constant bits to select-of-constants form.
static InstructionfoldSelectZeroOrFixedOp (SelectInst &SI, InstCombinerImpl &IC)
static ValuecanonicalizeSaturatedSubtract (const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
 Transform patterns such as (a > b) ?
static ValuecanonicalizeSaturatedAdd (ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
static ValuefoldAbsDiff (ICmpInst *Cmp, Value *TVal, Value *FVal, InstCombiner::BuilderTy &Builder)
 Try to match patterns with select and subtract as absolute difference.

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 47 of file InstCombineSelect.cpp.

Function Documentation

◆ canonicalizeSaturatedAdd()

◆ canonicalizeSaturatedSubtract()

◆ foldAbsDiff()

Value * foldAbsDiff ( ICmpInst * Cmp,
Value * TVal,
Value * FVal,
InstCombiner::BuilderTy & Builder )
static

◆ foldSelectBinOpIdentity()

◆ foldSelectICmpAnd()

Value * foldSelectICmpAnd ( SelectInst & Sel,
Value * CondVal,
Value * TrueVal,
Value * FalseVal,
Value * V,
const APInt & AndMask,
bool CreateAnd,
InstCombiner::BuilderTy & Builder )
static

This folds: select (icmp eq (and X, C1)), TC, FC iff C1 is a power 2 and the difference between TC and FC is a power-of-2.

To something like: (shr (and (X, C1)), (log2(C1) - log2(TC-FC))) + FC Or: (shl (and (X, C1)), (log2(TC-FC) - log2(C1))) + FC With some variations depending if FC is larger than TC, or the shift isn't needed, or the bit widths don't match.

Definition at line 123 of file InstCombineSelect.cpp.

References llvm::ConstantFoldBinaryOpOperands(), llvm::APInt::getBitWidth(), llvm::Instruction::getDataLayout(), llvm::Type::getScalarSizeInBits(), llvm::Value::getType(), llvm::Value::hasOneUse(), llvm::APInt::isPowerOf2(), llvm::APInt::isZero(), llvm::APInt::logBase2(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::match(), and Opc.

◆ foldSelectICmpAndAnd()

Instruction * foldSelectICmpAndAnd ( Type * SelType,
const ICmpInst * Cmp,
Value * TVal,
Value * FVal,
InstCombiner::BuilderTy & Builder )
static

We want to turn: (select (icmp eq (and X, Y), 0), (and (lshr X, Z), 1), 1) into: zext (icmp ne i32 (and X, (or Y, (shl 1, Z))), 0) Note: Z may be 0 if lshr is missing.

Worst-case scenario is that we will replace 5 instructions with 5 different instructions, but we got rid of select.

Definition at line 632 of file InstCombineSelect.cpp.

References B(), llvm::Type::getScalarSizeInBits(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_ULT, llvm::PatternMatch::m_And(), llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_One(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificInt_ICMP(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::match(), X, and Y.

◆ foldSelectICmpAndBinOp()

Value * foldSelectICmpAndBinOp ( Value * CondVal,
Value * TrueVal,
Value * FalseVal,
Value * V,
const APInt & AndMask,
bool CreateAnd,
InstCombiner::BuilderTy & Builder )
static

We want to turn: (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2)) into: IF C2 u>= C1 (BinOp Y, (shl (and X, C1), C3)) ELSE (BinOp Y, (lshr (and X, C1), C3)) iff: 0 on the RHS is the identity value (i.e add, xor, shl, etc...) C1 and C2 are both powers of 2 where: IF C2 u>= C1 C3 = Log(C2) - Log(C1) ELSE C3 = Log(C1) - Log(C2)

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 773 of file InstCombineSelect.cpp.

References llvm::cast(), llvm::dyn_cast(), llvm::ConstantExpr::getBinOpIdentity(), llvm::BinaryOperator::getOpcode(), llvm::Value::getType(), llvm::Value::hasOneUse(), llvm::APInt::logBase2(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::match(), and Y.

◆ foldSelectICmpAndZeroShl()

Value * foldSelectICmpAndZeroShl ( const ICmpInst * Cmp,
Value * TVal,
Value * FVal,
InstCombiner::BuilderTy & Builder )
static

◆ foldSelectICmpLshrAshr()

◆ foldSelectICmpMinMax()

Value * foldSelectICmpMinMax ( const ICmpInst * Cmp,
Value * TVal,
Value * FVal,
InstCombiner::BuilderTy & Builder,
const SimplifyQuery & SQ )
static

◆ foldSelectZeroOrFixedOp()

◆ foldSetClearBits()

◆ getSelectFoldableOperands()

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 221 of file InstCombineSelect.cpp.

References I.

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

◆ isSelect01()

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