37 cl::desc(
"fp convert instructions on integers with "
38 "more than <N> bits are expanded."));
99 unsigned FPMantissaWidth = FloatVal->getType()->getFPMantissaWidth() - 1;
104 if (FloatVal->getType()->isHalfTy()) {
105 if (FPToI->
getOpcode() == Instruction::FPToUI) {
120 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
121 unsigned FloatWidth =
122 PowerOf2Ceil(FloatVal->getType()->getScalarSizeInBits());
123 unsigned ExponentWidth = FloatWidth - FPMantissaWidth - 1;
124 unsigned ExponentBias = (1 << (ExponentWidth - 1)) - 1;
127 Value *SignificandMask =
137 Entry->setName(
Twine(Entry->getName(),
"fp-to-i-entry"));
139 Entry->splitBasicBlock(Builder.
GetInsertPoint(),
"fp-to-i-cleanup");
151 Entry->getTerminator()->eraseFromParent();
155 Value *FloatVal0 = FloatVal;
158 if (FloatVal->getType()->isX86_FP80Ty())
182 IntTy, -
static_cast<int64_t
>(ExponentBias +
BitWidth)));
211 IntTy, -
static_cast<int64_t
>(ExponentBias + FPMantissaWidth)));
318 IntegerType *IntTy = cast<IntegerType>(IntVal->getType());
320 unsigned BitWidth = IntVal->getType()->getIntegerBitWidth();
324 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
327 FPMantissaWidth = FPMantissaWidth == 10 ? 23 : FPMantissaWidth;
328 FPMantissaWidth = FPMantissaWidth == 7 ? 23 : FPMantissaWidth;
330 bool IsSigned = IToFP->
getOpcode() == Instruction::SIToFP;
332 assert(
BitWidth > FloatWidth &&
"Unexpected conversion. expandIToFP() "
333 "assumes integer width is larger than fp.");
341 Entry->setName(
Twine(Entry->getName(),
"itofp-entry"));
361 Entry->getTerminator()->eraseFromParent();
380 int BitWidthNew = FloatWidth == 128 ?
BitWidth : 32;
382 FloatWidth == 128 ? Call : Cast);
384 FloatWidth == 128 ? Call : Cast);
386 Sub1, Builder.
getIntN(BitWidthNew, FPMantissaWidth + 1));
392 SI->addCase(Builder.
getIntN(BitWidthNew, FPMantissaWidth + 2), SwBB);
393 SI->addCase(Builder.
getIntN(BitWidthNew, FPMantissaWidth + 3), SwEpilog);
405 FloatWidth == 128 ? Call : Cast);
408 FloatWidth == 128 ? Sub5 : ShProm);
410 Builder.
CreateAdd(FloatWidth == 128 ? Call : Cast,
411 Builder.
getIntN(BitWidthNew, FPMantissaWidth + 3));
414 FloatWidth == 128 ? Sub8 : ShProm9);
433 Value *Shr18 =
nullptr;
442 Value *ExtractT64 =
nullptr;
451 Value *Shr21 =
nullptr;
458 Value *ExtractT62 =
nullptr;
468 FloatWidth == 128 ? Call : Cast,
470 -(
BitWidth - FPMantissaWidth - 1)));
473 FloatWidth == 128 ? Sub24 : ShProm25);
476 Value *ExtractT66 =
nullptr;
489 PHINode *AAddr1Off32 =
nullptr;
490 if (FloatWidth > 32) {
498 if (FloatWidth <= 80) {
504 Value *And29 =
nullptr;
505 if (FloatWidth > 80) {
508 And29 = Builder.
CreateAnd(Shr, Temp2,
"and29");
514 unsigned TempMod = FPMantissaWidth % 32;
515 Value *And34 =
nullptr;
516 Value *Shl30 =
nullptr;
517 if (FloatWidth > 80) {
521 Add, Builder.
getInt64(((1ull << (62ull - TempMod)) - 1ull) << TempMod));
526 Add, Builder.
getInt32(((1 << (30 - TempMod)) - 1) << TempMod));
527 And34 = Builder.
CreateAnd(FloatWidth > 32 ? AAddr1Off32 : AAddr1Off0,
528 Builder.
getInt32((1 << TempMod) - 1));
530 Value *Or35 =
nullptr;
531 if (FloatWidth > 80) {
536 Builder.
getIntN(128, FPMantissaWidth));
542 Or35 = Builder.
CreateOr(IsSigned ? Or31 : And34, Shl30);
578 VectorType *VTy = cast<FixedVectorType>(
I->getType());
582 unsigned NumElements = VTy->getElementCount().getFixedValue();
584 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
587 I->getType()->getScalarType());
589 if (isa<Instruction>(Cast))
590 Replace.
push_back(cast<Instruction>(Cast));
592 I->replaceAllUsesWith(Result);
593 I->dropAllReferences();
594 I->eraseFromParent();
602 unsigned MaxLegalFpConvertBitWidth =
611 switch (
I.getOpcode()) {
612 case Instruction::FPToUI:
613 case Instruction::FPToSI: {
615 if (
I.getOperand(0)->getType()->isScalableTy())
618 auto *IntTy = cast<IntegerType>(
I.getType()->getScalarType());
619 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
622 if (
I.getOperand(0)->getType()->isVectorTy())
629 case Instruction::UIToFP:
630 case Instruction::SIToFP: {
632 if (
I.getOperand(0)->getType()->isScalableTy())
636 cast<IntegerType>(
I.getOperand(0)->getType()->getScalarType());
637 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
640 if (
I.getOperand(0)->getType()->isVectorTy())
652 while (!ReplaceVector.
empty()) {
660 while (!Replace.
empty()) {
662 if (
I->getOpcode() == Instruction::FPToUI ||
663 I->getOpcode() == Instruction::FPToSI) {
684 auto *TLI =
TM->getSubtargetImpl(
F)->getTargetLowering();
702char ExpandFpLegacyPass::ID = 0;
704 "Expand certain fp instructions",
false,
false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static void expandIToFP(Instruction *IToFP)
Generate code to convert a fp number to integer, replacing S(U)IToFP with the generated code.
static void expandFPToI(Instruction *FPToI)
Generate code to convert a fp number to integer, replacing FPToS(U)I with the generated code.
static void scalarize(Instruction *I, SmallVectorImpl< Instruction * > &Replace)
static cl::opt< unsigned > ExpandFpConvertBits("expand-fp-convert-bits", cl::Hidden, cl::init(llvm::IntegerType::MAX_INT_BITS), cl::desc("fp convert instructions on integers with " "more than <N> bits are expanded."))
static bool runImpl(Function &F, const TargetLowering &TLI)
static Expected< BitVector > expand(StringRef S, StringRef Original)
This is the interface for a simple mod/ref and alias analysis over globals.
This header defines various interfaces for pass management in LLVM.
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static LLVM_ABI Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Legacy wrapper pass to provide the GlobalsAAResult object.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Value * CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
ConstantInt * getTrue()
Get the constant value for i1 true.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateFPToUI(Value *V, Type *DestTy, const Twine &Name="")
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
BasicBlock * GetInsertBlock() const
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt128Ty()
Fetch the type representing a 128-bit integer.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateFPExt(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateFPToSI(Value *V, Type *DestTy, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Class to represent integer types.
@ MAX_INT_BITS
Maximum number of bits that can be specified.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getMaxLargeFPConvertBitWidthSupported() const
Returns the size in bits of the maximum fp to/from int conversion the backend supports.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Target-Independent Code Generator Pass Configuration Options.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getFP128Ty(LLVMContext &C)
bool isX86_FP80Ty() const
Return true if this is x86 long double.
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
LLVM_ABI unsigned getIntegerBitWidth() const
void dropAllReferences()
Drop all references to operands.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
LLVM_ABI void initializeExpandFpLegacyPassPass(PassRegistry &)
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
constexpr unsigned BitWidth
LLVM_ABI FunctionPass * createExpandFpPass()