LLVM 20.0.0git
Macros | Functions
InstCombineCasts.cpp File Reference
#include "InstCombineInternal.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <optional>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "instcombine"
 

Functions

static bool canAlwaysEvaluateInType (Value *V, Type *Ty)
 Constants and extensions/truncates from the destination type are always free to be evaluated in that type.
 
static bool canNotEvaluateInType (Value *V, Type *Ty)
 Filter out values that we can not evaluate in the destination type for free.
 
static bool canEvaluateTruncated (Value *V, Type *Ty, InstCombinerImpl &IC, Instruction *CxtI)
 Return true if we can evaluate the specified expression tree as type Ty instead of its larger type, and arrive with the same value.
 
static InstructionfoldVecTruncToExtElt (TruncInst &Trunc, InstCombinerImpl &IC)
 Given a vector that is bitcast to an integer, optionally logically right-shifted, and truncated, convert it to an extractelement.
 
static InstructionshrinkSplatShuffle (TruncInst &Trunc, InstCombiner::BuilderTy &Builder)
 Try to narrow the width of a splat shuffle.
 
static InstructionshrinkInsertElt (CastInst &Trunc, InstCombiner::BuilderTy &Builder)
 Try to narrow the width of an insert element.
 
static bool canEvaluateZExtd (Value *V, Type *Ty, unsigned &BitsToClear, InstCombinerImpl &IC, Instruction *CxtI)
 Determine if the specified value can be computed in the specified wider type and produce the same low bits.
 
static bool canEvaluateSExtd (Value *V, Type *Ty)
 Return true if we can take the specified value and return it as type Ty without inserting any new casts and without changing the value of the common low bits.
 
static bool fitsInFPType (ConstantFP *CFP, const fltSemantics &Sem)
 Return a Constant* for the specified floating-point constant if it fits in the specified FP type without changing its value.
 
static TypeshrinkFPConstant (ConstantFP *CFP, bool PreferBFloat)
 
static TypeshrinkFPConstantVector (Value *V, bool PreferBFloat)
 
static TypegetMinimumFPType (Value *V, bool PreferBFloat)
 Find the minimum FP type we can safely truncate to.
 
static bool isKnownExactCastIntToFP (CastInst &I, InstCombinerImpl &IC)
 Return true if the cast from integer to FP can be proven to be exact for all possible inputs (the conversion does not lose any precision).
 
static InstructionfoldFPtoI (Instruction &FI, InstCombiner &IC)
 
static InstructionoptimizeVectorResizeWithIntegerBitCasts (Value *InVal, VectorType *DestTy, InstCombinerImpl &IC)
 This input value (which is known to have vector type) is being zero extended or truncated to the specified vector type.
 
static bool isMultipleOfTypeSize (unsigned Value, Type *Ty)
 
static unsigned getTypeSizeIndex (unsigned Value, Type *Ty)
 
static bool collectInsertionElements (Value *V, unsigned Shift, SmallVectorImpl< Value * > &Elements, Type *VecEltTy, bool isBigEndian)
 V is a value which is inserted into a vector of VecEltTy.
 
static ValueoptimizeIntegerToVectorInsertions (BitCastInst &CI, InstCombinerImpl &IC)
 If the input is an 'or' instruction, we may be doing shifts and ors to assemble the elements of the vector manually.
 
static InstructioncanonicalizeBitCastExtElt (BitCastInst &BitCast, InstCombinerImpl &IC)
 Canonicalize scalar bitcasts of extracted elements into a bitcast of the vector followed by extract element.
 
static InstructionfoldBitCastBitwiseLogic (BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)
 Change the type of a bitwise logic operation if we can eliminate a bitcast.
 
static InstructionfoldBitCastSelect (BitCastInst &BitCast, InstCombiner::BuilderTy &Builder)
 Change the type of a select if we can eliminate a bitcast.
 
static bool hasStoreUsersOnly (CastInst &CI)
 Check if all users of CI are StoreInsts.
 
static ValuefoldCopySignIdioms (BitCastInst &CI, InstCombiner::BuilderTy &Builder, const SimplifyQuery &SQ)
 Fold (bitcast (or (and (bitcast X to int), signmask), nneg Y) to fp) to copysign((bitcast Y to fp), X)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "instcombine"

Definition at line 26 of file InstCombineCasts.cpp.

Function Documentation

◆ canAlwaysEvaluateInType()

static bool canAlwaysEvaluateInType ( Value V,
Type Ty 
)
static

Constants and extensions/truncates from the destination type are always free to be evaluated in that type.

This is a helper for canEvaluate*.

Definition at line 231 of file InstCombineCasts.cpp.

References llvm::PatternMatch::m_ImmConstant(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_ZExtOrSExt(), llvm::PatternMatch::match(), and X.

Referenced by canEvaluateSExtd(), canEvaluateTruncated(), and canEvaluateZExtd().

◆ canEvaluateSExtd()

static bool canEvaluateSExtd ( Value V,
Type Ty 
)
static

Return true if we can take the specified value and return it as type Ty without inserting any new casts and without changing the value of the common low bits.

This is used by code that tries to promote integer operations to a wider types will allow us to eliminate the extension.

This function works on both vectors and scalars.

Definition at line 1380 of file InstCombineCasts.cpp.

References assert(), canAlwaysEvaluateInType(), canEvaluateSExtd(), canNotEvaluateInType(), llvm::Type::getScalarSizeInBits(), I, and llvm::PHINode::incoming_values().

Referenced by canEvaluateSExtd(), and llvm::InstCombinerImpl::visitSExt().

◆ canEvaluateTruncated()

static bool canEvaluateTruncated ( Value V,
Type Ty,
InstCombinerImpl IC,
Instruction CxtI 
)
static

Return true if we can evaluate the specified expression tree as type Ty instead of its larger type, and arrive with the same value.

This is used by code that tries to eliminate truncates.

Ty will always be a type smaller than V. We should return true if trunc(V) can be computed by computing V in the smaller type. If V is an instruction, then trunc(inst(x,y)) can be computed as inst(trunc(x),trunc(y)), which only makes sense if x and y can be efficiently truncated.

This function works on both vectors and scalars.

Definition at line 267 of file InstCombineCasts.cpp.

References assert(), llvm::BitWidth, canAlwaysEvaluateInType(), canEvaluateTruncated(), canNotEvaluateInType(), llvm::computeKnownBits(), llvm::InstCombiner::ComputeNumSignBits(), llvm::APInt::getBitsSetFrom(), llvm::InstCombiner::getDataLayout(), llvm::Type::getFltSemantics(), llvm::KnownBits::getMaxValue(), llvm::Type::getScalarSizeInBits(), I, llvm::PHINode::incoming_values(), llvm::InstCombiner::MaskedValueIsZero(), llvm::APFloatBase::semanticsIntSizeInBits(), and llvm::APInt::ult().

Referenced by canEvaluateTruncated(), and llvm::InstCombinerImpl::visitTrunc().

◆ canEvaluateZExtd()

static bool canEvaluateZExtd ( Value V,
Type Ty,
unsigned BitsToClear,
InstCombinerImpl IC,
Instruction CxtI 
)
static

Determine if the specified value can be computed in the specified wider type and produce the same low bits.

If not, return false.

If this function returns true, it can also return a non-zero number of bits (in BitsToClear) which indicates that the value it computes is correct for the zero extend, but that the additional BitsToClear bits need to be zero'd out. For example, to promote something like:

B = trunc i64 A to i32 C = lshr i32 B, 8 E = zext i32 C to i64

CanEvaluateZExtd for the 'lshr' will return true, and BitsToClear will be set to 8 to indicate that the promoted value needs to have bits 24-31 cleared in addition to bits 32-63. Since an 'and' will be generated to clear the top bits anyway, doing this has no extra cost.

This function works on both vectors and scalars.

Definition at line 1025 of file InstCombineCasts.cpp.

References canAlwaysEvaluateInType(), canEvaluateZExtd(), canNotEvaluateInType(), llvm::APInt::getHighBitsSet(), llvm::PHINode::getIncomingValue(), llvm::PHINode::getNumIncomingValues(), llvm::APInt::getZExtValue(), I, II, llvm::PatternMatch::m_APInt(), llvm::InstCombiner::MaskedValueIsZero(), and llvm::PatternMatch::match().

Referenced by canEvaluateZExtd(), and llvm::InstCombinerImpl::visitZExt().

◆ canNotEvaluateInType()

static bool canNotEvaluateInType ( Value V,
Type Ty 
)
static

Filter out values that we can not evaluate in the destination type for free.

This is a helper for canEvaluate*.

Definition at line 245 of file InstCombineCasts.cpp.

Referenced by canEvaluateSExtd(), canEvaluateTruncated(), and canEvaluateZExtd().

◆ canonicalizeBitCastExtElt()

static Instruction * canonicalizeBitCastExtElt ( BitCastInst BitCast,
InstCombinerImpl IC 
)
static

Canonicalize scalar bitcasts of extracted elements into a bitcast of the vector followed by extract element.

The backend tends to handle bitcasts of vectors better than bitcasts of scalars because vector registers are usually not type-specific like scalar integer or scalar floating-point.

Definition at line 2343 of file InstCombineCasts.cpp.

References llvm::InstCombiner::Builder, llvm::CastInst::Create(), llvm::ExtractElementInst::Create(), llvm::IRBuilderBase::CreateBitCast(), llvm::VectorType::get(), llvm::User::getOperand(), llvm::Value::getType(), llvm::VectorType::isValidElementType(), llvm::Type::isVectorTy(), llvm::PatternMatch::m_ExtractElt(), llvm::PatternMatch::m_OneUse(), llvm::PatternMatch::m_Value(), and llvm::PatternMatch::match().

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

◆ collectInsertionElements()

static bool collectInsertionElements ( Value V,
unsigned  Shift,
SmallVectorImpl< Value * > &  Elements,
Type VecEltTy,
bool  isBigEndian 
)
static

V is a value which is inserted into a vector of VecEltTy.

Look through the value to see if we can decompose it into insertions into the vector. See the example in the comment for OptimizeIntegerToVectorInsertions for the pattern this handles. The type of V is always a non-zero multiple of VecEltTy's size. Shift is the number of bits between the lsb of V and the lsb of the vector.

This returns false if the pattern can't be matched or true if it can, filling in Elements with the elements found here.

Definition at line 2200 of file InstCombineCasts.cpp.

References assert(), llvm::CallingConv::C, collectInsertionElements(), llvm::ConstantFoldBinaryInstruction(), llvm::IntegerType::get(), llvm::ConstantExpr::getBitCast(), llvm::Type::getPrimitiveSizeInBits(), llvm::ConstantExpr::getTrunc(), getTypeSizeIndex(), llvm::ConstantInt::getZExtValue(), I, isBigEndian(), and isMultipleOfTypeSize().

Referenced by collectInsertionElements(), and optimizeIntegerToVectorInsertions().

◆ fitsInFPType()

static bool fitsInFPType ( ConstantFP CFP,
const fltSemantics Sem 
)
static

Return a Constant* for the specified floating-point constant if it fits in the specified FP type without changing its value.

Definition at line 1571 of file InstCombineCasts.cpp.

References F, llvm::ConstantFP::getValueAPF(), and llvm::APFloatBase::rmNearestTiesToEven.

Referenced by shrinkFPConstant().

◆ foldBitCastBitwiseLogic()

static Instruction * foldBitCastBitwiseLogic ( BitCastInst BitCast,
InstCombiner::BuilderTy Builder 
)
static

◆ foldBitCastSelect()

static Instruction * foldBitCastSelect ( BitCastInst BitCast,
InstCombiner::BuilderTy Builder 
)
static

◆ foldCopySignIdioms()

static Value * foldCopySignIdioms ( BitCastInst CI,
InstCombiner::BuilderTy Builder,
const SimplifyQuery SQ 
)
static

◆ foldFPtoI()

static Instruction * foldFPtoI ( Instruction FI,
InstCombiner IC 
)
static

◆ foldVecTruncToExtElt()

static Instruction * foldVecTruncToExtElt ( TruncInst Trunc,
InstCombinerImpl IC 
)
static

◆ getMinimumFPType()

static Type * getMinimumFPType ( Value V,
bool  PreferBFloat 
)
static

Find the minimum FP type we can safely truncate to.

Definition at line 1635 of file InstCombineCasts.cpp.

References shrinkFPConstant(), and shrinkFPConstantVector().

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

◆ getTypeSizeIndex()

static unsigned getTypeSizeIndex ( unsigned  Value,
Type Ty 
)
static

Definition at line 2186 of file InstCombineCasts.cpp.

References llvm::Type::getPrimitiveSizeInBits().

Referenced by collectInsertionElements().

◆ hasStoreUsersOnly()

static bool hasStoreUsersOnly ( CastInst CI)
static

Check if all users of CI are StoreInsts.

Definition at line 2485 of file InstCombineCasts.cpp.

References llvm::Value::users().

◆ isKnownExactCastIntToFP()

static bool isKnownExactCastIntToFP ( CastInst I,
InstCombinerImpl IC 
)
static

◆ isMultipleOfTypeSize()

static bool isMultipleOfTypeSize ( unsigned  Value,
Type Ty 
)
static

Definition at line 2182 of file InstCombineCasts.cpp.

References llvm::Type::getPrimitiveSizeInBits().

Referenced by collectInsertionElements().

◆ optimizeIntegerToVectorInsertions()

static Value * optimizeIntegerToVectorInsertions ( BitCastInst CI,
InstCombinerImpl IC 
)
static

If the input is an 'or' instruction, we may be doing shifts and ors to assemble the elements of the vector manually.

Try to rip the code out and replace it with insertelements. This is to optimize code like this:

tmp37 = bitcast float inc to i32 tmp38 = zext i32 tmp37 to i64 tmp31 = bitcast float inc5 to i32 tmp32 = zext i32 tmp31 to i64 tmp33 = shl i64 tmp32, 32 ins35 = or i64 tmp33, tmp38 tmp43 = bitcast i64 ins35 to <2 x float>

Into two insertelements that do "buildvector{%inc, %inc5}".

Definition at line 2314 of file InstCombineCasts.cpp.

References llvm::InstCombiner::Builder, collectInsertionElements(), llvm::IRBuilderBase::CreateInsertElement(), llvm::InstCombiner::getDataLayout(), llvm::IRBuilderBase::getInt32(), llvm::Constant::getNullValue(), llvm::User::getOperand(), llvm::Value::getType(), and llvm::DataLayout::isBigEndian().

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

◆ optimizeVectorResizeWithIntegerBitCasts()

static Instruction * optimizeVectorResizeWithIntegerBitCasts ( Value InVal,
VectorType DestTy,
InstCombinerImpl IC 
)
static

This input value (which is known to have vector type) is being zero extended or truncated to the specified vector type.

Since the zext/trunc is done using an integer type, we have a (bitcast(cast(bitcast))) pattern, endianness will impact which end of the vector that is extended or truncated.

A vector is always stored with index 0 at the lowest address, which corresponds to the most significant bits for a big endian stored integer and the least significant bits for little endian. A trunc/zext of an integer impacts the big end of the integer. Thus, we need to add/remove elements at the front of the vector for big endian targets, and the back of the vector for little endian targets.

Try to replace it with a shuffle (and vector/vector bitcast) if possible.

The source and destination vector types may have different element types.

Definition at line 2112 of file InstCombineCasts.cpp.

References assert(), llvm::InstCombiner::Builder, llvm::IRBuilderBase::CreateBitCast(), llvm::FixedVectorType::get(), llvm::PoisonValue::get(), llvm::InstCombiner::getDataLayout(), llvm::Constant::getNullValue(), llvm::Value::getType(), llvm::DataLayout::isBigEndian(), llvm::ArrayRef< T >::take_back(), and llvm::ArrayRef< T >::take_front().

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

◆ shrinkFPConstant()

static Type * shrinkFPConstant ( ConstantFP CFP,
bool  PreferBFloat 
)
static

◆ shrinkFPConstantVector()

static Type * shrinkFPConstantVector ( Value V,
bool  PreferBFloat 
)
static

◆ shrinkInsertElt()

static Instruction * shrinkInsertElt ( CastInst Trunc,
InstCombiner::BuilderTy Builder 
)
static

Try to narrow the width of an insert element.

This could be generalized for any vector constant, but we limit the transform to insertion into undef to avoid potential backend problems from unsupported insertion widths. This could also be extended to handle the case of inserting a scalar constant into a vector variable.

Definition at line 650 of file InstCombineCasts.cpp.

References assert(), llvm::InsertElementInst::Create(), llvm::IRBuilderBase::CreateCast(), llvm::UndefValue::get(), llvm::CastInst::getOpcode(), llvm::User::getOperand(), llvm::Type::getScalarType(), llvm::Value::getType(), llvm::PatternMatch::m_Undef(), and llvm::PatternMatch::match().

Referenced by llvm::InstCombinerImpl::visitFPTrunc(), and llvm::InstCombinerImpl::visitTrunc().

◆ shrinkSplatShuffle()

static Instruction * shrinkSplatShuffle ( TruncInst Trunc,
InstCombiner::BuilderTy Builder 
)
static

Try to narrow the width of a splat shuffle.

This could be generalized to any shuffle with a constant operand, but we limit the transform to avoid creating a shuffle type that targets may not be able to lower effectively.

Definition at line 630 of file InstCombineCasts.cpp.

References llvm::all_equal(), llvm::IRBuilderBase::CreateTrunc(), llvm::User::getOperand(), llvm::Value::getType(), llvm::PatternMatch::m_Undef(), and llvm::PatternMatch::match().

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