LLVM 20.0.0git
Macros | Functions | Variables
InstCombineCalls.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InlineAsm.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/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsHexagon.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SimplifyLibCalls.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <optional>
#include <utility>
#include <vector>
#include "llvm/Transforms/Utils/InstructionWorklist.h"

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "instcombine"
 

Functions

 STATISTIC (NumSimplified, "Number of library calls simplified")
 
static TypegetPromotedType (Type *Ty)
 Return the specified type promoted as it would be to pass though a va_arg area.
 
static bool hasUndefSource (AnyMemTransferInst *MI)
 Recognize a memcpy/memmove from a trivially otherwise unused alloca.
 
static InstructionsimplifyInvariantGroupIntrinsic (IntrinsicInst &II, InstCombinerImpl &IC)
 This function transforms launder.invariant.group and strip.invariant.group like: launder(launder(x)) -> launder(x) (the result is not the argument) launder(strip(x)) -> launder(x) strip(strip(x)) -> strip(x) (the result is not the argument) strip(launder(x)) -> strip(x) This is legal because it preserves the most recent information about the presence or absence of invariant.group.
 
static InstructionfoldCttzCtlz (IntrinsicInst &II, InstCombinerImpl &IC)
 
static InstructionfoldCtpop (IntrinsicInst &II, InstCombinerImpl &IC)
 
static ValuesimplifyNeonTbl1 (const IntrinsicInst &II, InstCombiner::BuilderTy &Builder)
 Convert a table lookup to shufflevector if the mask is constant.
 
static bool haveSameOperands (const IntrinsicInst &I, const IntrinsicInst &E, unsigned NumOperands)
 
static bool removeTriviallyEmptyRange (IntrinsicInst &EndI, InstCombinerImpl &IC, std::function< bool(const IntrinsicInst &)> IsStart)
 
static CallInstcanonicalizeConstantArg0ToArg1 (CallInst &Call)
 
static InstructioncreateOverflowTuple (IntrinsicInst *II, Value *Result, Constant *Overflow)
 Creates a result tuple for an overflow intrinsic II with a given Result and a constant Overflow value.
 
static bool inputDenormalIsIEEE (const Function &F, const Type *Ty)
 
static bool inputDenormalIsDAZ (const Function &F, const Type *Ty)
 
static FCmpInst::Predicate fpclassTestIsFCmp0 (FPClassTest Mask, const Function &F, Type *Ty)
 
static std::optional< boolgetKnownSign (Value *Op, const SimplifyQuery &SQ)
 
static std::optional< boolgetKnownSignOrZero (Value *Op, const SimplifyQuery &SQ)
 
static bool signBitMustBeTheSame (Value *Op0, Value *Op1, const SimplifyQuery &SQ)
 Return true if two values Op0 and Op1 are known to have the same sign.
 
static InstructionmoveAddAfterMinMax (IntrinsicInst *II, InstCombiner::BuilderTy &Builder)
 Try to canonicalize min/max(X + C0, C1) as min/max(X, C1 - C0) + C0.
 
static InstructionfoldClampRangeOfTwo (IntrinsicInst *II, InstCombiner::BuilderTy &Builder)
 If we have a clamp pattern like max (min X, 42), 41 – where the output can only be one of two possible constant values – turn that into a select of constants.
 
static ValuereassociateMinMaxWithConstants (IntrinsicInst *II, IRBuilderBase &Builder, const SimplifyQuery &SQ)
 If this min/max has a constant operand and an operand that is a matching min/max with a constant operand, constant-fold the 2 constant operands.
 
static InstructionreassociateMinMaxWithConstantInOperand (IntrinsicInst *II, InstCombiner::BuilderTy &Builder)
 If this min/max has a matching min/max operand with a constant, try to push the constant operand into this instruction.
 
static InstructionfactorizeMinMaxTree (IntrinsicInst *II)
 Reduce a sequence of min/max intrinsics with a common operand.
 
static InstructionfoldShuffledIntrinsicOperands (IntrinsicInst *II, InstCombiner::BuilderTy &Builder)
 If all arguments of the intrinsic are unary shuffles with the same mask, try to shuffle after the intrinsic.
 
template<Intrinsic::ID IntrID>
static InstructionfoldBitOrderCrossLogicOp (Value *V, InstCombiner::BuilderTy &Builder)
 Fold the following cases and accepts bswap and bitreverse intrinsics: bswap(logic_op(bswap(x), y)) --> logic_op(x, bswap(y)) bswap(logic_op(bswap(x), bswap(y))) --> logic_op(x, y) (ignores multiuse)
 
static ValuesimplifyReductionOperand (Value *Arg, bool CanReorderLanes)
 
template<Intrinsic::ID IntrID>
static ValuefoldMinimumOverTrailingOrLeadingZeroCount (Value *I0, Value *I1, const DataLayout &DL, InstCombiner::BuilderTy &Builder)
 Fold an unsigned minimum of trailing or leading zero bits counts: umin(cttz(CtOp, ZeroUndef), ConstOp) --> cttz(CtOp | (1 << ConstOp)) umin(ctlz(CtOp, ZeroUndef), ConstOp) --> ctlz(CtOp | (SignedMin >> ConstOp))
 
static IntrinsicInstfindInitTrampolineFromAlloca (Value *TrampMem)
 
static IntrinsicInstfindInitTrampolineFromBB (IntrinsicInst *AdjustTramp, Value *TrampMem)
 
static IntrinsicInstfindInitTrampoline (Value *Callee)
 

Variables

static cl::opt< unsignedGuardWideningWindow ("instcombine-guard-widening-window", cl::init(3), cl::desc("How wide an instruction window to bypass looking for " "another guard"))
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 78 of file InstCombineCalls.cpp.

Function Documentation

◆ canonicalizeConstantArg0ToArg1()

static CallInst * canonicalizeConstantArg0ToArg1 ( CallInst Call)
static

Definition at line 811 of file InstCombineCalls.cpp.

References assert().

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

◆ createOverflowTuple()

static Instruction * createOverflowTuple ( IntrinsicInst II,
Value Result,
Constant Overflow 
)
static

Creates a result tuple for an overflow intrinsic II with a given Result and a constant Overflow value.

Definition at line 824 of file InstCombineCalls.cpp.

References llvm::InsertValueInst::Create(), llvm::ConstantStruct::get(), llvm::PoisonValue::get(), II, and Struct.

◆ factorizeMinMaxTree()

static Instruction * factorizeMinMaxTree ( IntrinsicInst II)
static

Reduce a sequence of min/max intrinsics with a common operand.

Definition at line 1297 of file InstCombineCalls.cpp.

References A, assert(), B, llvm::CallingConv::C, llvm::CallInst::Create(), D, llvm::Intrinsic::getDeclaration(), llvm::Value::hasOneUse(), II, LHS, llvm::Mod, and RHS.

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

◆ findInitTrampoline()

static IntrinsicInst * findInitTrampoline ( Value Callee)
static

◆ findInitTrampolineFromAlloca()

static IntrinsicInst * findInitTrampolineFromAlloca ( Value TrampMem)
static

◆ findInitTrampolineFromBB()

static IntrinsicInst * findInitTrampolineFromBB ( IntrinsicInst AdjustTramp,
Value TrampMem 
)
static

◆ foldBitOrderCrossLogicOp()

template<Intrinsic::ID IntrID>
static Instruction * foldBitOrderCrossLogicOp ( Value V,
InstCombiner::BuilderTy Builder 
)
static

Fold the following cases and accepts bswap and bitreverse intrinsics: bswap(logic_op(bswap(x), y)) --> logic_op(x, bswap(y)) bswap(logic_op(bswap(x), bswap(y))) --> logic_op(x, y) (ignores multiuse)

Definition at line 1407 of file InstCombineCalls.cpp.

References llvm::BinaryOperator::Create(), llvm::IRBuilderBase::CreateUnaryIntrinsic(), llvm::PatternMatch::m_BitwiseLogic(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), X, and Y.

◆ foldClampRangeOfTwo()

static Instruction * foldClampRangeOfTwo ( IntrinsicInst II,
InstCombiner::BuilderTy Builder 
)
static

◆ foldCtpop()

static Instruction * foldCtpop ( IntrinsicInst II,
InstCombinerImpl IC 
)
static

Definition at line 627 of file InstCombineCalls.cpp.

References assert(), llvm::BitWidth, llvm::InstCombiner::Builder, llvm::InstCombiner::computeKnownBits(), llvm::ConstantRange::contains(), llvm::KnownBits::countMaxPopulation(), llvm::KnownBits::countMinPopulation(), llvm::CallInst::Create(), llvm::CastInst::Create(), llvm::IRBuilderBase::CreateCall(), llvm::IRBuilderBase::CreateICmp(), llvm::IRBuilderBase::CreateSub(), llvm::IRBuilderBase::CreateUnaryIntrinsic(), F, llvm::Intrinsic::getDeclaration(), llvm::IRBuilderBase::getFalse(), llvm::Constant::getNullValue(), llvm::Type::getScalarSizeInBits(), llvm::InstCombiner::getSimplifyQuery(), llvm::SimplifyQuery::getWithInstruction(), llvm::APInt::getZero(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_NE, II, llvm::ConstantRange::intersectWith(), llvm::isKnownNonZero(), llvm::InstCombiner::isKnownToBeAPowerOfTwo(), llvm::Lower, llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_BitReverse(), llvm::PatternMatch::m_BSwap(), llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_c_Or(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_FShl(), llvm::PatternMatch::m_FShr(), llvm::PatternMatch::m_Neg(), llvm::PatternMatch::m_Not(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_ZExt(), llvm::PatternMatch::match(), Range, llvm::InstCombiner::replaceInstUsesWith(), llvm::InstCombiner::replaceOperand(), llvm::ConstantRange::Unsigned, llvm::Upper, X, Y, and llvm::KnownBits::Zero.

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

◆ foldCttzCtlz()

static Instruction * foldCttzCtlz ( IntrinsicInst II,
InstCombinerImpl IC 
)
static

Definition at line 479 of file InstCombineCalls.cpp.

References assert(), llvm::BitWidth, llvm::InstCombiner::Builder, llvm::CallingConv::C, llvm::InstCombiner::computeKnownBits(), llvm::KnownBits::countMaxLeadingZeros(), llvm::KnownBits::countMaxTrailingZeros(), llvm::KnownBits::countMinLeadingZeros(), llvm::KnownBits::countMinTrailingZeros(), llvm::CallInst::Create(), llvm::IRBuilderBase::CreateBinaryIntrinsic(), llvm::BinaryOperator::CreateNot(), llvm::IRBuilderBase::CreateZExt(), F, llvm::SelectPatternResult::Flavor, llvm::Intrinsic::getDeclaration(), llvm::Constant::getNullValue(), llvm::Type::getScalarSizeInBits(), llvm::InstCombiner::getSimplifyQuery(), llvm::IRBuilderBase::getTrue(), llvm::Value::getType(), llvm::SimplifyQuery::getWithInstruction(), II, llvm::isKnownNonZero(), llvm::APInt::isZero(), llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_AllOnes(), llvm::PatternMatch::m_BitReverse(), llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_Exact(), llvm::PatternMatch::m_ImmConstant(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Neg(), llvm::PatternMatch::m_NUWShl(), llvm::PatternMatch::m_One(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_SExt(), llvm::PatternMatch::m_Shift(), llvm::PatternMatch::m_Shl(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::m_ZExt(), llvm::PatternMatch::match(), llvm::matchSelectPattern(), llvm::KnownBits::One, Range, llvm::InstCombiner::replaceInstUsesWith(), llvm::InstCombiner::replaceOperand(), llvm::SPF_ABS, llvm::SPF_NABS, X, and Y.

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

◆ foldMinimumOverTrailingOrLeadingZeroCount()

template<Intrinsic::ID IntrID>
static Value * foldMinimumOverTrailingOrLeadingZeroCount ( Value I0,
Value I1,
const DataLayout DL,
InstCombiner::BuilderTy Builder 
)
static

Fold an unsigned minimum of trailing or leading zero bits counts: umin(cttz(CtOp, ZeroUndef), ConstOp) --> cttz(CtOp | (1 << ConstOp)) umin(ctlz(CtOp, ZeroUndef), ConstOp) --> ctlz(CtOp | (SignedMin >> ConstOp))

Definition at line 1475 of file InstCombineCalls.cpp.

References llvm::BitWidth, llvm::CallingConv::C, llvm::ConstantFoldBinaryOpOperands(), llvm::IRBuilderBase::CreateBinaryIntrinsic(), llvm::IRBuilderBase::CreateOr(), DL, llvm::APInt::getSignedMinValue(), llvm::ConstantInt::getTrue(), llvm::Value::getType(), llvm::PatternMatch::m_CheckedInt(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), and llvm::PatternMatch::match().

◆ foldShuffledIntrinsicOperands()

static Instruction * foldShuffledIntrinsicOperands ( IntrinsicInst II,
InstCombiner::BuilderTy Builder 
)
static

If all arguments of the intrinsic are unary shuffles with the same mask, try to shuffle after the intrinsic.

Definition at line 1356 of file InstCombineCalls.cpp.

References llvm::IRBuilderBase::CreateIntrinsic(), II, llvm::PatternMatch::m_Shuffle(), llvm::PatternMatch::m_Undef(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::none_of(), and X.

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

◆ fpclassTestIsFCmp0()

static FCmpInst::Predicate fpclassTestIsFCmp0 ( FPClassTest  Mask,
const Function F,
Type Ty 
)
static

◆ getKnownSign()

static std::optional< bool > getKnownSign ( Value Op,
const SimplifyQuery SQ 
)
static

◆ getKnownSignOrZero()

static std::optional< bool > getKnownSignOrZero ( Value Op,
const SimplifyQuery SQ 
)
static

◆ getPromotedType()

static Type * getPromotedType ( Type Ty)
static

Return the specified type promoted as it would be to pass though a va_arg area.

Definition at line 94 of file InstCombineCalls.cpp.

References llvm::Type::getContext(), and llvm::Type::getInt32Ty().

◆ hasUndefSource()

static bool hasUndefSource ( AnyMemTransferInst MI)
static

Recognize a memcpy/memmove from a trivially otherwise unused alloca.

TODO: This should probably be integrated with visitAllocSites, but that requires a deeper change to allow either unread or unwritten objects.

Definition at line 105 of file InstCombineCalls.cpp.

References MI.

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

◆ haveSameOperands()

static bool haveSameOperands ( const IntrinsicInst I,
const IntrinsicInst E,
unsigned  NumOperands 
)
static

◆ inputDenormalIsDAZ()

static bool inputDenormalIsDAZ ( const Function F,
const Type Ty 
)
static

Definition at line 848 of file InstCombineCalls.cpp.

References F, llvm::Type::getFltSemantics(), and llvm::Type::getScalarType().

Referenced by fpclassTestIsFCmp0().

◆ inputDenormalIsIEEE()

static bool inputDenormalIsIEEE ( const Function F,
const Type Ty 
)
static

◆ moveAddAfterMinMax()

static Instruction * moveAddAfterMinMax ( IntrinsicInst II,
InstCombiner::BuilderTy Builder 
)
static

◆ reassociateMinMaxWithConstantInOperand()

static Instruction * reassociateMinMaxWithConstantInOperand ( IntrinsicInst II,
InstCombiner::BuilderTy Builder 
)
static

◆ reassociateMinMaxWithConstants()

static Value * reassociateMinMaxWithConstants ( IntrinsicInst II,
IRBuilderBase Builder,
const SimplifyQuery SQ 
)
static

If this min/max has a constant operand and an operand that is a matching min/max with a constant operand, constant-fold the 2 constant operands.

Definition at line 1235 of file InstCombineCalls.cpp.

References llvm::IRBuilderBase::CreateICmp(), llvm::IRBuilderBase::CreateIntrinsic(), llvm::IRBuilderBase::CreateSelect(), llvm::MinMaxIntrinsic::getPredicate(), II, llvm::isKnownNonNegative(), LHS, llvm::PatternMatch::m_ImmConstant(), and llvm::PatternMatch::match().

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

◆ removeTriviallyEmptyRange()

static bool removeTriviallyEmptyRange ( IntrinsicInst EndI,
InstCombinerImpl IC,
std::function< bool(const IntrinsicInst &)>  IsStart 
)
static

◆ signBitMustBeTheSame()

static bool signBitMustBeTheSame ( Value Op0,
Value Op1,
const SimplifyQuery SQ 
)
static

Return true if two values Op0 and Op1 are known to have the same sign.

Definition at line 1081 of file InstCombineCalls.cpp.

References getKnownSign().

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

◆ simplifyInvariantGroupIntrinsic()

static Instruction * simplifyInvariantGroupIntrinsic ( IntrinsicInst II,
InstCombinerImpl IC 
)
static

This function transforms launder.invariant.group and strip.invariant.group like: launder(launder(x)) -> launder(x) (the result is not the argument) launder(strip(x)) -> launder(x) strip(strip(x)) -> strip(x) (the result is not the argument) strip(launder(x)) -> strip(x) This is legal because it preserves the most recent information about the presence or absence of invariant.group.

Definition at line 449 of file InstCombineCalls.cpp.

References llvm::InstCombiner::Builder, llvm::IRBuilderBase::CreateAddrSpaceCast(), llvm::IRBuilderBase::CreateLaunderInvariantGroup(), llvm::IRBuilderBase::CreateStripInvariantGroup(), II, Intr, and llvm_unreachable.

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

◆ simplifyNeonTbl1()

static Value * simplifyNeonTbl1 ( const IntrinsicInst II,
InstCombiner::BuilderTy Builder 
)
static

Convert a table lookup to shufflevector if the mask is constant.

This could benefit tbl1 if the mask is { 7,6,5,4,3,2,1,0 }, in which case we could lower the shufflevector with rev64 instructions as it's actually a byte reverse.

Definition at line 720 of file InstCombineCalls.cpp.

References llvm::CallingConv::C, llvm::IRBuilderBase::CreateShuffleVector(), llvm::Constant::getNullValue(), I, and II.

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

◆ simplifyReductionOperand()

static Value * simplifyReductionOperand ( Value Arg,
bool  CanReorderLanes 
)
static

◆ STATISTIC()

STATISTIC ( NumSimplified  ,
"Number of library calls simplified"   
)

Variable Documentation

◆ GuardWideningWindow

cl::opt< unsigned > GuardWideningWindow("instcombine-guard-widening-window", cl::init(3), cl::desc("How wide an instruction window to bypass looking for " "another guard")) ( "instcombine-guard-widening-window"  ,
cl::init(3)  ,
cl::desc("How wide an instruction window to bypass looking for " "another guard")   
)
static