LLVM 19.0.0git
Macros | Functions
InstCombineSelect.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/OverflowInstAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <utility>
#include "llvm/Transforms/Utils/InstructionWorklist.h"

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, ICmpInst *Cmp, 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 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 (const ICmpInst *IC, Value *TrueVal, Value *FalseVal, 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 InstructionfoldSelectZeroOrMul (SelectInst &SI, InstCombinerImpl &IC)
 
static ValuecanonicalizeSaturatedSubtract (const ICmpInst *ICI, const Value *TrueVal, const Value *FalseVal, InstCombiner::BuilderTy &Builder)
 Transform patterns such as (a > b) ? a - b : 0 into usub.sat(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 46 of file InstCombineSelect.cpp.

Function Documentation

◆ canonicalizeSaturatedAdd()

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

◆ canonicalizeSaturatedSubtract()

static Value * canonicalizeSaturatedSubtract ( const ICmpInst ICI,
const Value TrueVal,
const Value FalseVal,
InstCombiner::BuilderTy Builder 
)
static

◆ foldAbsDiff()

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

◆ foldSelectBinOpIdentity()

static Instruction * foldSelectBinOpIdentity ( SelectInst Sel,
const TargetLibraryInfo TLI,
InstCombinerImpl IC 
)
static

◆ foldSelectICmpAnd()

static Value * foldSelectICmpAnd ( SelectInst Sel,
ICmpInst Cmp,
InstCombiner::BuilderTy Builder 
)
static

◆ foldSelectICmpAndAnd()

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

References B, llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateIsNotNull(), llvm::IRBuilderBase::CreateOr(), llvm::IRBuilderBase::CreateShl(), 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::PatternMatch::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()

static Value * foldSelectICmpAndBinOp ( const ICmpInst IC,
Value TrueVal,
Value FalseVal,
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 722 of file InstCombineSelect.cpp.

References llvm::IRBuilderBase::CreateAnd(), llvm::IRBuilderBase::CreateBinOp(), llvm::IRBuilderBase::CreateLShr(), llvm::IRBuilderBase::CreateShl(), llvm::IRBuilderBase::CreateXor(), llvm::IRBuilderBase::CreateZExtOrTrunc(), llvm::decomposeBitTestICmp(), llvm::ConstantExpr::getBinOpIdentity(), llvm::APInt::getOneBitSet(), llvm::BinaryOperator::getOpcode(), llvm::User::getOperand(), llvm::CmpInst::getPredicate(), llvm::Value::getType(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::ICmpInst::isEquality(), llvm::APInt::isPowerOf2(), llvm::Type::isVectorTy(), llvm::APInt::logBase2(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_BinOp(), llvm::PatternMatch::m_Power2(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::match(), NeedAnd, and Y.

◆ foldSelectICmpAndZeroShl()

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

◆ foldSelectICmpLshrAshr()

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

◆ foldSelectZeroOrMul()

static Instruction * foldSelectZeroOrMul ( SelectInst SI,
InstCombinerImpl IC 
)
static

◆ foldSetClearBits()

static Instruction * foldSetClearBits ( SelectInst Sel,
InstCombiner::BuilderTy Builder 
)
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 242 of file InstCombineSelect.cpp.

References I.

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

◆ isSelect01()

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