38 cl::desc(
"fp convert instructions on integers with "
39 "more than <N> bits are expanded."));
97 unsigned FPMantissaWidth = FloatVal->getType()->getFPMantissaWidth() - 1;
102 if (FloatVal->getType()->isHalfTy()) {
103 if (FPToI->
getOpcode() == Instruction::FPToUI) {
118 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
120 unsigned ExponentWidth = FloatWidth - FPMantissaWidth - 1;
121 unsigned ExponentBias = (1 << (ExponentWidth - 1)) - 1;
124 Value *SignificandMask =
134 Entry->setName(
Twine(Entry->getName(),
"fp-to-i-entry"));
136 Entry->splitBasicBlock(Builder.
GetInsertPoint(),
"fp-to-i-cleanup");
148 Entry->getTerminator()->eraseFromParent();
152 Value *FloatVal0 = FloatVal;
155 if (FloatVal->getType()->isX86_FP80Ty())
179 IntTy, -
static_cast<int64_t
>(ExponentBias +
BitWidth)));
208 IntTy, -
static_cast<int64_t
>(ExponentBias + FPMantissaWidth)));
312 IntegerType *IntTy = cast<IntegerType>(IntVal->getType());
314 unsigned BitWidth = IntVal->getType()->getIntegerBitWidth();
318 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
321 FPMantissaWidth = FPMantissaWidth == 10 ? 23 : FPMantissaWidth;
323 bool IsSigned = IToFP->
getOpcode() == Instruction::SIToFP;
325 assert(
BitWidth > FloatWidth &&
"Unexpected conversion. expandIToFP() "
326 "assumes integer width is larger than fp.");
334 Entry->setName(
Twine(Entry->getName(),
"itofp-entry"));
354 Entry->getTerminator()->eraseFromParent();
371 Value *Call = Builder.
CreateCall(CTLZ, {IsSigned ? Sub : IntVal, True});
373 int BitWidthNew = FloatWidth == 128 ?
BitWidth : 32;
375 FloatWidth == 128 ? Call : Cast);
377 FloatWidth == 128 ? Call : Cast);
379 Sub1, Builder.
getIntN(BitWidthNew, FPMantissaWidth + 1));
385 SI->addCase(Builder.
getIntN(BitWidthNew, FPMantissaWidth + 2), SwBB);
386 SI->addCase(Builder.
getIntN(BitWidthNew, FPMantissaWidth + 3), SwEpilog);
398 FloatWidth == 128 ? Call : Cast);
401 FloatWidth == 128 ? Sub5 : ShProm);
403 Builder.
CreateAdd(FloatWidth == 128 ? Call : Cast,
404 Builder.
getIntN(BitWidthNew, FPMantissaWidth + 3));
407 FloatWidth == 128 ? Sub8 : ShProm9);
418 AAddr0->
addIncoming(IsSigned ? Sub : IntVal, IfThen4);
426 Value *Shr18 =
nullptr;
435 Value *ExtractT64 =
nullptr;
444 Value *Shr21 =
nullptr;
451 Value *ExtractT62 =
nullptr;
461 FloatWidth == 128 ? Call : Cast,
463 -(
BitWidth - FPMantissaWidth - 1)));
466 FloatWidth == 128 ? Sub24 : ShProm25);
469 Value *ExtractT66 =
nullptr;
482 PHINode *AAddr1Off32 =
nullptr;
483 if (FloatWidth > 32) {
491 if (FloatWidth <= 80) {
497 Value *And29 =
nullptr;
498 if (FloatWidth > 80) {
501 And29 = Builder.
CreateAnd(Shr, Temp2,
"and29");
507 unsigned TempMod = FPMantissaWidth % 32;
508 Value *And34 =
nullptr;
509 Value *Shl30 =
nullptr;
510 if (FloatWidth > 80) {
515 Builder.
getIntN(64, ((1ull << (62ull - TempMod)) - 1ull) << TempMod));
520 Add, Builder.
getIntN(32, ((1 << (30 - TempMod)) - 1) << TempMod));
521 And34 = Builder.
CreateAnd(FloatWidth > 32 ? AAddr1Off32 : AAddr1Off0,
522 Builder.
getIntN(32, (1 << TempMod) - 1));
524 Value *Or35 =
nullptr;
525 if (FloatWidth > 80) {
530 Builder.
getIntN(128, FPMantissaWidth));
536 Or35 = Builder.
CreateOr(IsSigned ? Or31 : And34, Shl30);
575 unsigned MaxLegalFpConvertBitWidth =
584 switch (
I.getOpcode()) {
585 case Instruction::FPToUI:
586 case Instruction::FPToSI: {
588 if (
I.getOperand(0)->getType()->isVectorTy())
591 auto *IntTy = dyn_cast<IntegerType>(
I.getType());
592 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
599 case Instruction::UIToFP:
600 case Instruction::SIToFP: {
602 if (
I.getOperand(0)->getType()->isVectorTy())
605 auto *IntTy = dyn_cast<IntegerType>(
I.getOperand(0)->getType());
606 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
621 while (!Replace.
empty()) {
623 if (
I->getOpcode() == Instruction::FPToUI ||
624 I->getOpcode() == Instruction::FPToSI) {
635class ExpandLargeFpConvertLegacyPass :
public FunctionPass {
646 auto *TLI =
TM->getSubtargetImpl(
F)->getTargetLowering();
665char ExpandLargeFpConvertLegacyPass::ID = 0;
667 "Expand large fp convert",
false,
false)
672 return new ExpandLargeFpConvertLegacyPass();
Expand Atomic instructions
static bool runImpl(Function &F, const TargetLowering &TLI)
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 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.
FunctionAnalysisManager FAM
const char LLVMTargetMachineRef TM
This header defines various interfaces for pass management in LLVM.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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 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 * CreateTrunc(Value *V, Type *DestTy, 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="")
ConstantInt * getTrue()
Get the constant value for i1 true.
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.
BasicBlock * GetInsertBlock() const
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
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="")
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)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
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.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateFPExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
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...
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 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...
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.
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 larget fp convert 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...
unsigned getIntegerBitWidth() const
bool isX86_FP80Ty() const
Return true if this is x86 long double.
static Type * getFP128Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
int getFPMantissaWidth() const
Return the width of the mantissa of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static Type * getFloatTy(LLVMContext &C)
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.
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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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.
FunctionPass * createExpandLargeFpConvertPass()
void initializeExpandLargeFpConvertLegacyPassPass(PassRegistry &)
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
constexpr unsigned BitWidth