37 cl::desc(
"fp convert instructions on integers with "
38 "more than <N> bits are expanded."));
96 unsigned FPMantissaWidth = FloatVal->getType()->getFPMantissaWidth() - 1;
101 if (FloatVal->getType()->isHalfTy()) {
102 if (FPToI->
getOpcode() == Instruction::FPToUI) {
104 A1 =
Builder.CreateZExt(A0, IntTy);
107 A1 =
Builder.CreateSExt(A0, IntTy);
117 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
119 unsigned ExponentWidth = FloatWidth - FPMantissaWidth - 1;
120 unsigned ExponentBias = (1 << (ExponentWidth - 1)) - 1;
123 Value *SignificandMask =
133 Entry->setName(
Twine(Entry->getName(),
"fp-to-i-entry"));
135 Entry->splitBasicBlock(
Builder.GetInsertPoint(),
"fp-to-i-cleanup");
147 Entry->getTerminator()->eraseFromParent();
151 Value *FloatVal0 = FloatVal;
154 if (FloatVal->getType()->isX86_FP80Ty())
180 Builder.CreateCondBr(Cmp3, IfThen5, IfEnd9);
183 Builder.SetInsertPoint(IfThen5);
185 Value *Cond8 =
Builder.CreateSelect(PosOrNeg, PosInf, NegInf);
189 Builder.SetInsertPoint(IfEnd9);
192 Builder.CreateCondBr(Cmp10, IfThen12, IfElse);
195 Builder.SetInsertPoint(IfThen12);
203 Builder.SetInsertPoint(IfElse);
310 IntegerType *IntTy = cast<IntegerType>(IntVal->getType());
312 unsigned BitWidth = IntVal->getType()->getIntegerBitWidth();
316 FPMantissaWidth = FPMantissaWidth == 63 ? 112 : FPMantissaWidth;
319 FPMantissaWidth = FPMantissaWidth == 10 ? 23 : FPMantissaWidth;
321 bool IsSigned = IToFP->
getOpcode() == Instruction::SIToFP;
323 assert(
BitWidth > FloatWidth &&
"Unexpected conversion. expandIToFP() "
324 "assumes integer width is larger than fp.");
332 Entry->setName(
Twine(Entry->getName(),
"itofp-entry"));
334 Entry->splitBasicBlock(
Builder.GetInsertPoint(),
"itofp-return");
352 Entry->getTerminator()->eraseFromParent();
369 Value *Call =
Builder.CreateCall(CTLZ, {IsSigned ? Sub : IntVal, True});
371 int BitWidthNew = FloatWidth == 128 ?
BitWidth : 32;
373 FloatWidth == 128 ? Call : Cast);
375 FloatWidth == 128 ? Call : Cast);
377 Sub2,
Builder.getIntN(BitWidthNew, FPMantissaWidth + 1));
378 Builder.CreateCondBr(Cmp3, IfThen4, IfElse);
381 Builder.SetInsertPoint(IfThen4);
383 SI->addCase(
Builder.getIntN(BitWidthNew, FPMantissaWidth + 2), SwBB);
384 SI->addCase(
Builder.getIntN(BitWidthNew, FPMantissaWidth + 3), SwEpilog);
393 Builder.SetInsertPoint(SwDefault);
396 FloatWidth == 128 ? Call : Cast);
398 Value *Shr6 =
Builder.CreateLShr(IsSigned ? Sub : IntVal,
399 FloatWidth == 128 ? Sub5 : ShProm);
401 Builder.CreateAdd(FloatWidth == 128 ? Call : Cast,
402 Builder.getIntN(BitWidthNew, FPMantissaWidth + 3));
405 FloatWidth == 128 ? Sub8 : ShProm9);
413 Builder.SetInsertPoint(SwEpilog);
416 AAddr0->
addIncoming(IsSigned ? Sub : IntVal, IfThen4);
424 Value *Shr18 =
nullptr;
433 Value *ExtractT64 =
nullptr;
437 ExtractT64 =
Builder.CreateTrunc(Extract63,
Builder.getInt32Ty());
438 Builder.CreateCondBr(PosOrNeg, IfEnd26, IfThen20);
441 Builder.SetInsertPoint(IfThen20);
442 Value *Shr21 =
nullptr;
449 Value *ExtractT62 =
nullptr;
457 Builder.SetInsertPoint(IfElse);
459 FloatWidth == 128 ? Call : Cast,
461 -(
BitWidth - FPMantissaWidth - 1)));
463 Value *Shl26 =
Builder.CreateShl(IsSigned ? Sub : IntVal,
464 FloatWidth == 128 ? Sub24 : ShProm25);
467 Value *ExtractT66 =
nullptr;
471 ExtractT66 =
Builder.CreateTrunc(Extract65,
Builder.getInt32Ty());
475 Builder.SetInsertPoint(IfEnd26);
480 PHINode *AAddr1Off32 =
nullptr;
481 if (FloatWidth > 32) {
483 Builder.CreatePHI(
Builder.getIntNTy(FloatWidth > 80 ? 64 : 32), 3);
489 if (FloatWidth <= 80) {
495 Value *And29 =
nullptr;
496 if (FloatWidth > 80) {
499 And29 =
Builder.CreateAnd(Shr, Temp2,
"and29");
505 unsigned TempMod = FPMantissaWidth % 32;
506 Value *And34 =
nullptr;
507 Value *Shl30 =
nullptr;
508 if (FloatWidth > 80) {
513 Builder.getIntN(64, ((1ull << (62ull - TempMod)) - 1ull) << TempMod));
518 Add,
Builder.getIntN(32, ((1 << (30 - TempMod)) - 1) << TempMod));
519 And34 =
Builder.CreateAnd(FloatWidth > 32 ? AAddr1Off32 : AAddr1Off0,
520 Builder.getIntN(32, (1 << TempMod) - 1));
522 Value *Or35 =
nullptr;
523 if (FloatWidth > 80) {
528 Builder.getIntN(128, FPMantissaWidth));
531 Or35 =
Builder.CreateOr(Or34, A6);
534 Or35 =
Builder.CreateOr(IsSigned ? Or31 : And34, Shl30);
541 Builder.CreateAnd(AAddr1Off0,
Builder.getIntN(FloatWidth, 0xFFFFFFFF));
573 unsigned MaxLegalFpConvertBitWidth =
582 switch (
I.getOpcode()) {
583 case Instruction::FPToUI:
584 case Instruction::FPToSI: {
586 if (
I.getOperand(0)->getType()->isVectorTy())
589 auto *IntTy = dyn_cast<IntegerType>(
I.getType());
590 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
597 case Instruction::UIToFP:
598 case Instruction::SIToFP: {
600 if (
I.getOperand(0)->getType()->isVectorTy())
603 auto *IntTy = dyn_cast<IntegerType>(
I.getOperand(0)->getType());
604 if (IntTy->getIntegerBitWidth() <= MaxLegalFpConvertBitWidth)
619 while (!Replace.
empty()) {
621 if (
I->getOpcode() == Instruction::FPToUI ||
622 I->getOpcode() == Instruction::FPToSI) {
633class ExpandLargeFpConvertLegacyPass :
public FunctionPass {
644 auto *TLI =
TM->getSubtargetImpl(
F)->getTargetLowering();
656char ExpandLargeFpConvertLegacyPass::ID = 0;
658 "Expand large fp convert",
false,
false)
663 return new ExpandLargeFpConvertLegacyPass();
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.
print must be executed print the must be executed context for all instructions
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.
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.
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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
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...
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.
Target-Independent Code Generator Pass Configuration Options.
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