LLVM 17.0.0git
Namespaces | 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/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.

Namespaces

namespace  llvm
 This is an optimization pass for GlobalISel generic memory operations.
 

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 fpclassTestIsFCmp0 (FPClassTest Mask, const Function &F, Type *Ty)
 
static std::optional< boolgetKnownSign (Value *Op, Instruction *CxtI, const DataLayout &DL, AssumptionCache *AC, DominatorTree *DT)
 
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)
 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.
 
static bool isSafeToEliminateVarargsCast (const CallBase &Call, const DataLayout &DL, const CastInst *const CI, const int ix)
 If this cast does not affect the value passed through the varargs area, we can eliminate the use of the cast.
 
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 77 of file InstCombineCalls.cpp.

Function Documentation

◆ canonicalizeConstantArg0ToArg1()

static CallInst * canonicalizeConstantArg0ToArg1 ( CallInst Call)
static

Definition at line 784 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 797 of file InstCombineCalls.cpp.

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

◆ factorizeMinMaxTree()

static Instruction * factorizeMinMaxTree ( IntrinsicInst II)
static

◆ findInitTrampoline()

static IntrinsicInst * findInitTrampoline ( Value Callee)
static

◆ findInitTrampolineFromAlloca()

static IntrinsicInst * findInitTrampolineFromAlloca ( Value TrampMem)
static

◆ findInitTrampolineFromBB()

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

◆ foldClampRangeOfTwo()

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

◆ foldCtpop()

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

Definition at line 608 of file InstCombineCalls.cpp.

References assert(), llvm::BitWidth, llvm::InstCombiner::Builder, llvm::InstCombiner::computeKnownBits(), 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::ConstantAsMetadata::get(), llvm::MDNode::get(), llvm::ConstantInt::get(), llvm::CallBase::getArgOperand(), llvm::Value::getContext(), llvm::Intrinsic::getDeclaration(), llvm::IRBuilderBase::getFalse(), llvm::IntrinsicInst::getIntrinsicID(), llvm::Instruction::getMetadata(), llvm::Instruction::getModule(), llvm::Constant::getNullValue(), llvm::Type::getScalarSizeInBits(), llvm::Type::getScalarType(), llvm::Value::getType(), llvm::Value::hasOneUse(), llvm::CmpInst::ICMP_NE, llvm::InstCombiner::isKnownToBeAPowerOfTwo(), IT, LowAndHigh, 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(), llvm::InstCombiner::replaceInstUsesWith(), llvm::InstCombiner::replaceOperand(), llvm::Instruction::setMetadata(), X, Y, and llvm::KnownBits::Zero.

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

◆ foldCttzCtlz()

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

Definition at line 508 of file InstCombineCalls.cpp.

References assert(), 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::ConstantAsMetadata::get(), llvm::MDNode::get(), llvm::ConstantInt::get(), llvm::CallBase::getArgOperand(), llvm::InstCombiner::getAssumptionCache(), llvm::Value::getContext(), llvm::InstCombiner::getDataLayout(), llvm::Intrinsic::getDeclaration(), llvm::InstCombiner::getDominatorTree(), llvm::IntrinsicInst::getIntrinsicID(), llvm::Instruction::getMetadata(), llvm::Instruction::getModule(), llvm::Constant::getNullValue(), llvm::Type::getScalarType(), llvm::IRBuilderBase::getTrue(), llvm::Value::getType(), llvm::Type::isIntOrIntVectorTy(), llvm::isKnownNonZero(), llvm::APInt::isZero(), IT, LowAndHigh, llvm::PatternMatch::m_BitReverse(), llvm::PatternMatch::m_Neg(), llvm::PatternMatch::m_One(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_SExt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::m_ZExt(), llvm::PatternMatch::match(), llvm::matchSelectPattern(), llvm::KnownBits::One, llvm::InstCombiner::replaceInstUsesWith(), llvm::InstCombiner::replaceOperand(), llvm::Instruction::setMetadata(), llvm::SPF_ABS, llvm::SPF_NABS, X, and Y.

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

◆ foldShuffledIntrinsicOperands()

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

◆ fpclassTestIsFCmp0()

static bool fpclassTestIsFCmp0 ( FPClassTest  Mask,
const Function F,
Type Ty 
)
static
Returns
true if the test performed by llvm.is.fpclass(x, Mask) is equivalent to fcmp oeq x, 0.0 with the floating-point environment assumed for F for type Ty

Definition at line 819 of file InstCombineCalls.cpp.

References F, llvm::fcSubnormal, llvm::fcZero, llvm::Type::getFltSemantics(), llvm::Type::getScalarType(), llvm::DenormalMode::IEEE, llvm::DenormalMode::PositiveZero, and llvm::DenormalMode::PreserveSign.

◆ getKnownSign()

static std::optional< bool > getKnownSign ( Value Op,
Instruction CxtI,
const DataLayout DL,
AssumptionCache AC,
DominatorTree DT 
)
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 99 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 110 of file InstCombineCalls.cpp.

References MI.

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

◆ haveSameOperands()

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

Definition at line 729 of file InstCombineCalls.cpp.

References assert(), E, and I.

Referenced by removeTriviallyEmptyRange().

◆ isSafeToEliminateVarargsCast()

static bool isSafeToEliminateVarargsCast ( const CallBase Call,
const DataLayout DL,
const CastInst *const  CI,
const int  ix 
)
static

If this cast does not affect the value passed through the varargs area, we can eliminate the use of the cast.

Definition at line 3131 of file InstCombineCalls.cpp.

References DL, llvm::User::getOperand(), llvm::Value::getType(), llvm::CastInst::isLosslessCast(), and llvm::Type::isSized().

◆ 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 
)
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 1118 of file InstCombineCalls.cpp.

References Builder, llvm::CallBase::getArgOperand(), llvm::IntrinsicInst::getIntrinsicID(), llvm::MinMaxIntrinsic::getPredicate(), llvm::Value::getType(), 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

◆ 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 476 of file InstCombineCalls.cpp.

References Arg, llvm::InstCombiner::Builder, llvm::IRBuilderBase::CreateAddrSpaceCast(), llvm::IRBuilderBase::CreateBitCast(), llvm::IRBuilderBase::CreateLaunderInvariantGroup(), llvm::IRBuilderBase::CreateStripInvariantGroup(), llvm::CallBase::getArgOperand(), llvm::IntrinsicInst::getIntrinsicID(), llvm::Type::getPointerAddressSpace(), llvm::Value::getType(), 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 693 of file InstCombineCalls.cpp.

References Builder, llvm::CallingConv::C, llvm::CallBase::getArgOperand(), llvm::Constant::getNullValue(), llvm::Value::getType(), and I.

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

◆ 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