41 uint64_t NumBits =
IT->getSizeInBits().getFixedValue();
45 std::max<uint64_t>(8, std::min<uint64_t>(64,
llvm::bit_ceil(NumBits)));
56 if (Width & (Width - 1))
69 return Ty->getSizeInBits().getFixedValue();
79 bool Has64BitPointers;
83 void postMerge(
unsigned AggregateSize,
Class &
Lo,
Class &
Hi)
const;
86 bool IsNamedArg,
bool IsRegCall =
false)
const;
88 const Type *getIntegerTypeAtOffset(
const Type *IRType,
unsigned IROffset,
90 unsigned SourceOffset,
91 bool InMemory =
false)
const;
93 const Type *getSSETypeAtOffset(
const Type *ABIType,
unsigned ABIOffset,
95 unsigned SourceOffset)
const;
96 bool isIllegalVectorType(
const Type *Ty)
const;
97 bool containsMatrixField(
const RecordType *RT)
const;
100 ArgInfo getIndirectReturnResult(
const Type *Ty)
const;
101 const Type *getFPTypeAtOffset(
const Type *Ty,
unsigned Offset)
const;
103 const Type *isSingleElementStruct(
const Type *Ty)
const;
104 const Type *getByteVectorType(
const Type *Ty)
const;
107 ArgInfo getIndirectResult(
const Type *Ty,
unsigned FreeIntRegs)
const;
109 ArgInfo classifyReturnType(
const Type *RetTy)
const;
111 ArgInfo classifyArgumentType(
const Type *Ty,
unsigned FreeIntRegs,
112 unsigned &NeededInt,
unsigned &NeededSse,
113 bool IsNamedArg,
bool IsRegCall =
false)
const;
114 const Type *useFirstFieldIfTransparentUnion(
const Type *Ty)
const;
120 Has64BitPointers(Has64BitPtrs) {}
131 if (Fields.
empty()) {
135 const Type *StorageType =
nullptr;
137 for (
const auto &
Field : Fields) {
138 if (
Field.IsBitField &&
Field.IsUnnamedBitfield &&
139 Field.BitFieldWidth == 0) {
146 StorageType = FieldType;
152 (FieldType->getAlignment() == StorageType->
getAlignment() &&
155 StorageType = FieldType;
161void X86_64TargetInfo::postMerge(
unsigned AggregateSize, Class &
Lo,
218 "Invalid accumulated classification during merge.");
239bool X86_64TargetInfo::containsMatrixField(
const RecordType *RT)
const {
240 for (
const auto &
Field : RT->getFields()) {
244 if (AT->isMatrixType())
250 if (containsMatrixField(NestedRT))
256void X86_64TargetInfo::classify(
const Type *
T, uint64_t OffsetBase, Class &
Lo,
257 Class &
Hi,
bool IsNamedArg,
258 bool IsRegCall)
const {
260 Class &Current = OffsetBase < 64 ?
Lo :
Hi;
269 auto BitWidth =
IT->getSizeInBits().getFixedValue();
283 const auto *FltSem = FT->getSemantics();
301 if (
T->isPointer()) {
307 if (MPT->isFunctionPointer()) {
308 if (Has64BitPointers) {
311 uint64_t EbFuncPtr = OffsetBase / 64;
312 uint64_t EbThisAdj = (OffsetBase + 64 - 1) / 64;
313 if (EbFuncPtr != EbThisAdj) {
326 auto Size = VT->getSizeInBits().getFixedValue();
337 uint64_t EbLo = (OffsetBase) / 64;
338 uint64_t EbHi = (OffsetBase +
Size - 1) / 64;
341 }
else if (
Size == 64) {
352 uint64_t ElemBits =
IT->getSizeInBits().getFixedValue();
364 if (OffsetBase && OffsetBase != 64)
366 }
else if (
Size == 128 ||
369 uint64_t ElemBits =
IT->getSizeInBits().getFixedValue();
372 ElemBits == 128 && !
IT->isBitInt())
398 uint64_t
Size =
T->getSizeInBits().getFixedValue();
403 else if (
Size <= 128)
406 const auto *FltSem = EFT->getSemantics();
421 uint64_t ElementSize =
ElementType->getSizeInBits().getFixedValue();
424 uint64_t EbReal = OffsetBase / 64;
425 uint64_t EbImag = (OffsetBase + ElementSize) / 64;
437 if (AT->isMatrixType())
441 uint64_t
Size = AT->getSizeInBits().getFixedValue();
447 if (!IsRegCall &&
Size > 512)
455 uint64_t ElemAlign =
ElementType->getAlignment().value() * 8;
456 if (OffsetBase % ElemAlign)
462 uint64_t EltSize =
ElementType->getSizeInBits().getFixedValue();
463 uint64_t ArraySize = AT->getNumElements();
473 for (uint64_t
I = 0,
Offset = OffsetBase;
I < ArraySize;
475 Class FieldLo, FieldHi;
476 classify(ElementType,
Offset, FieldLo, FieldHi, IsNamedArg);
477 Lo = merge(
Lo, FieldLo);
478 Hi = merge(
Hi, FieldHi);
488 uint64_t
Size = RT->getSizeInBits().getFixedValue();
490 if (containsMatrixField(RT)) {
507 if (RT->hasFlexibleArrayMember())
514 if (RT->isCXXRecord()) {
515 for (
const auto &
Base : RT->getBaseClasses()) {
522 Class FieldLo, FieldHi;
523 uint64_t
Offset = OffsetBase +
Base.OffsetInBits;
524 classify(
Base.FieldType,
Offset, FieldLo, FieldHi, IsNamedArg);
525 Lo = merge(
Lo, FieldLo);
526 Hi = merge(
Hi, FieldHi);
530 (
Size !=
Base.FieldType->getSizeInBits().getFixedValue() ||
544 for (
const auto &
Field : RT->getFields()) {
548 if (BitField &&
Field.IsUnnamedBitfield)
553 Size !=
Field.FieldType->getSizeInBits().getFixedValue()) ||
560 bool IsInMemory =
Offset % (
Field.FieldType->getAlignment().value() * 8);
561 if (!BitField && IsInMemory) {
567 Class FieldLo, FieldHi;
570 uint64_t BitFieldSize =
Field.BitFieldWidth;
571 uint64_t EbLo =
Offset / 64;
572 uint64_t EbHi = (
Offset + BitFieldSize - 1) / 64;
575 assert(EbHi == EbLo &&
"Invalid classification, type > 16 bytes.");
583 classify(
Field.FieldType,
Offset, FieldLo, FieldHi, IsNamedArg);
586 Lo = merge(
Lo, FieldLo);
587 Hi = merge(
Hi, FieldHi);
600X86_64TargetInfo::useFirstFieldIfTransparentUnion(
const Type *Ty)
const {
602 if (RT->isUnion() && RT->isTransparentUnion()) {
603 auto Fields = RT->getFields();
604 assert(!Fields.empty() &&
"transparent union cannot be empty");
605 return Fields.front().FieldType;
612X86_64TargetInfo::classifyArgumentType(
const Type *Ty,
unsigned FreeIntRegs,
613 unsigned &NeededInt,
unsigned &NeededSSE,
614 bool IsNamedArg,
bool IsRegCall)
const {
616 Ty = useFirstFieldIfTransparentUnion(Ty);
619 classify(Ty, 0,
Lo,
Hi, IsNamedArg, IsRegCall);
627 const Type *ResType =
nullptr;
636 "Unknown missing lo part");
648 return getIndirectResult(Ty, FreeIntRegs);
661 ResType = getIntegerTypeAtOffset(Ty, 0, Ty, 0);
665 if (
Hi ==
NoClass && ResType->isInteger()) {
670 if (ResType->isInteger() && ResType->getSizeInBits() == 128) {
681 ResType = getSSETypeAtOffset(Ty, 0, Ty, 0);
686 const Type *HighPart =
nullptr;
702 HighPart = getIntegerTypeAtOffset(Ty, 8, Ty, 8);
713 HighPart = getSSETypeAtOffset(Ty, 8, Ty, 8);
723 assert(
Lo ==
Sse &&
"Unexpected SseUp classification");
724 ResType = getByteVectorType(Ty);
732 ResType = createPairType(ResType, HighPart);
737ArgInfo X86_64TargetInfo::classifyReturnType(
const Type *RetTy)
const {
742 classify(RetTy, 0,
Lo,
Hi,
true);
748 const Type *ResType =
nullptr;
756 "Unknown missing lo part");
765 return getIndirectReturnResult(RetTy);
770 ResType = getIntegerTypeAtOffset(RetTy, 0, RetTy, 0);
773 if (
Hi ==
NoClass && ResType->isInteger()) {
779 if (ResType->isInteger() && ResType->getSizeInBits() == 128) {
788 ResType = getSSETypeAtOffset(RetTy, 0, RetTy, 0);
803 const Type *X87Type =
805 FieldInfo Fields[] = {FieldInfo(X87Type, 0), FieldInfo(X87Type, 80)};
811 const Type *HighPart =
nullptr;
824 HighPart = getIntegerTypeAtOffset(RetTy, 8, RetTy, 8);
830 HighPart = getSSETypeAtOffset(RetTy, 8, RetTy, 8);
841 assert(
Lo ==
Sse &&
"Unexpected SseUp classification.");
842 ResType = getByteVectorType(RetTy);
853 HighPart = getSSETypeAtOffset(RetTy, 8, RetTy, 8);
864 ResType = createPairType(ResType, HighPart);
874const Type *X86_64TargetInfo::createPairType(
const Type *
Lo,
881 llvm::Align HiAlign =
Hi->getAlignment();
882 unsigned HiStart =
alignTo(LoSize, HiAlign);
884 assert(HiStart != 0 && HiStart <= 8 &&
"Invalid x86-64 argument pair!");
890 const Type *AdjustedLo =
Lo;
905 else if (
Lo->isInteger() ||
Lo->isPointer())
906 AdjustedLo = TB.getIntegerType(64,
Align(8),
false);
908 assert((
Lo->isInteger() ||
Lo->isPointer()) &&
909 "Invalid/unknown low type in pair");
910 unsigned AdjustedLoSize = AdjustedLo->getSizeInBits().getFixedValue() / 8;
911 HiStart =
alignTo(AdjustedLoSize, HiAlign);
915 FieldInfo Fields[] = {FieldInfo(AdjustedLo, 0), FieldInfo(
Hi, HiStart * 8)};
918 assert((8 * 8) == Fields[1].OffsetInBits &&
919 "High part must be at offset 8 bytes");
921 uint64_t PairSizeInBits =
922 Fields[1].OffsetInBits +
Hi->getSizeInBits().getFixedValue();
930 unsigned TySize = Ty->getSizeInBits().getFixedValue();
931 if (TySize <= StartBit)
936 const Type *EltTy = AT->getElementType();
939 for (
unsigned I = 0;
I < AT->getNumElements(); ++
I) {
940 unsigned EltOffset =
I * EltSize;
941 if (EltOffset >= EndBit)
944 unsigned EltStart = (EltOffset < StartBit) ? StartBit - EltOffset : 0;
955 if (RT->isCXXRecord()) {
956 for (
unsigned I = 0;
I < RT->getNumBaseClasses(); ++
I) {
958 if (
Base.OffsetInBits >= EndBit)
962 (
Base.OffsetInBits < StartBit) ? StartBit -
Base.OffsetInBits : 0;
964 EndBit -
Base.OffsetInBits))
969 for (
unsigned I = 0;
I < RT->getNumFields(); ++
I) {
971 if (
Field.OffsetInBits >= EndBit)
974 unsigned FieldStart =
975 (
Field.OffsetInBits < StartBit) ? StartBit -
Field.OffsetInBits : 0;
977 EndBit -
Field.OffsetInBits))
987const Type *X86_64TargetInfo::getIntegerTypeAtOffset(
const Type *ABIType,
989 const Type *SourceTy,
990 unsigned SourceOffset,
991 bool InMemory)
const {
993 const Type *WorkingType = ABIType;
994 if (InMemory && ABIType->isInteger()) {
996 unsigned OriginalBitWidth =
IT->getSizeInBits().getFixedValue();
998 unsigned WidenedBitWidth = OriginalBitWidth;
999 if (OriginalBitWidth <= 8) {
1000 WidenedBitWidth = 8;
1005 if (WidenedBitWidth != OriginalBitWidth) {
1006 WorkingType = TB.getIntegerType(WidenedBitWidth,
ABIType->getAlignment(),
1012 if (ABIOffset == 0) {
1017 if ((WorkingType->isPointer() && Has64BitPointers) ||
1018 (WorkingType->isInteger() &&
1028 if ((WorkingType->isInteger() &&
1033 (WorkingType->isPointer() && !Has64BitPointers)) {
1035 unsigned BitWidth = WorkingType->isPointer()
1040 SourceOffset * 8 + 64))
1046 if (RTy->isUnion()) {
1049 return getIntegerTypeAtOffset(ReducedType, ABIOffset, SourceTy,
1050 SourceOffset,
true);
1052 if (
const FieldInfo *Element =
1053 RTy->getElementContainingOffset(ABIOffset * 8)) {
1055 unsigned ElementOffsetBytes = Element->OffsetInBits / 8;
1056 return getIntegerTypeAtOffset(Element->FieldType,
1057 ABIOffset - ElementOffsetBytes, SourceTy,
1058 SourceOffset,
true);
1063 const Type *EltTy = ATy->getElementType();
1064 unsigned EltSize = EltTy->getSizeInBits() / 8;
1066 unsigned EltOffset = (ABIOffset / EltSize) * EltSize;
1067 return getIntegerTypeAtOffset(EltTy, ABIOffset - EltOffset, SourceTy,
1068 SourceOffset,
true);
1079 unsigned TySizeInBytes =
1084 alignTo(SourceTy->getSizeInBits().getFixedValue(), 64) / 8;
1086 assert(TySizeInBytes != SourceOffset &&
"Empty field?");
1087 unsigned AvailableSize = TySizeInBytes - SourceOffset;
1088 return TB.getIntegerType(std::min(AvailableSize, 8U) * 8,
Align(1),
false);
1092const Type *X86_64TargetInfo::getFPTypeAtOffset(
const Type *Ty,
1095 if (
Offset == 0 && Ty->isFloat())
1100 unsigned ElementSize =
ElementType->getSizeInBits().getFixedValue() / 8;
1109 if (
const FieldInfo *Element = RT->getElementContainingOffset(
Offset * 8)) {
1110 unsigned ElementOffsetBytes = Element->OffsetInBits / 8;
1111 return getFPTypeAtOffset(Element->FieldType,
Offset - ElementOffsetBytes);
1117 const Type *EltTy = AT->getElementType();
1118 unsigned EltSize = EltTy->getSizeInBits() / 8;
1119 unsigned EltIndex =
Offset / EltSize;
1121 return getFPTypeAtOffset(EltTy,
Offset - (EltIndex * EltSize));
1139const Type *X86_64TargetInfo::getSSETypeAtOffset(
const Type *ABIType,
1141 const Type *SourceTy,
1142 unsigned SourceOffset)
const {
1145 if (RTy->isUnion()) {
1148 return getSSETypeAtOffset(ReducedType, ABIOffset, SourceTy,
1154 auto Is16bitFpTy = [](
const Type *
T) {
1160 const Type *T0 = getFPTypeAtOffset(ABIType, ABIOffset);
1165 unsigned SourceSize =
1166 (SourceTy->getSizeInBits().getFixedValue() / 8) - SourceOffset;
1169 const Type *
T1 =
nullptr;
1171 alignTo(T0->getSizeInBits().getFixedValue(), T0->getAlignment().value()) /
1173 if (SourceSize > T0Size)
1174 T1 = getFPTypeAtOffset(ABIType, ABIOffset + T0Size);
1176 if (
T1 ==
nullptr) {
1177 if (Is16bitFpTy(T0) && SourceSize > 4)
1178 T1 = getFPTypeAtOffset(ABIType, ABIOffset + 4);
1188 if (Is16bitFpTy(T0) && Is16bitFpTy(
T1)) {
1189 const Type *T2 =
nullptr;
1191 T2 = getFPTypeAtOffset(ABIType, ABIOffset + 4);
1198 if (Is16bitFpTy(T0) || Is16bitFpTy(
T1))
1208const Type *X86_64TargetInfo::getByteVectorType(
const Type *Ty)
const {
1211 if (
const Type *InnerTy = isSingleElementStruct(Ty))
1219 VT->getElementType()->isInteger() &&
1221 unsigned Size = VT->getSizeInBits().getFixedValue();
1222 return TB.getVectorType(TB.getIntegerType(64,
Align(8),
false),
1234 unsigned Size = Ty->getSizeInBits().getFixedValue();
1242const Type *X86_64TargetInfo::isSingleElementStruct(
const Type *Ty)
const {
1247 if (RT->hasFlexibleArrayMember())
1250 const Type *Found =
nullptr;
1252 for (
const auto &
Base : RT->getBaseClasses()) {
1253 const Type *BaseTy =
Base.FieldType;
1256 if (!BaseRT || BaseRT->isEmpty())
1259 const Type *Elem = isSingleElementStruct(BaseTy);
1265 for (
const auto &FI : RT->getFields()) {
1269 const Type *FTy = FI.FieldType;
1272 if (AT->getNumElements() != 1)
1274 FTy = AT->getElementType();
1279 Elem = isSingleElementStruct(InnerRT);
1289 if (Found->getSizeInBits() != Ty->getSizeInBits())
1295bool X86_64TargetInfo::isIllegalVectorType(
const Type *Ty)
const {
1297 uint64_t
Size = VecTy->getSizeInBits().getFixedValue();
1305 const Type *EltTy = VecTy->getElementType();
1308 if (IntTy->getSizeInBits().getFixedValue() == 128)
1315ArgInfo X86_64TargetInfo::getIndirectResult(
const Type *Ty,
1316 unsigned FreeIntRegs)
const {
1339 uint64_t AlignVal = std::max<uint64_t>(Ty->getAlignment().value(), 8u);
1362 if (FreeIntRegs == 0) {
1370 if (AlignVal == 8 &&
Size <= 64) {
1372 TB.getIntegerType(
Size, llvm::Align(8),
false);
1380ArgInfo X86_64TargetInfo::getIndirectReturnResult(
const Type *Ty)
const {
1384 if (IntTy->isBitInt())
1399 if (!RT->canPassInRegisters()) {
1413void X86_64TargetInfo::computeInfo(FunctionInfo &FI)
const {
1424 "calling convention not supported by the LLVMABI X86_64 classifier");
1427 unsigned FreeIntRegs = 6;
1428 unsigned FreeSSERegs = 8;
1429 unsigned NeededInt = 0, NeededSSE = 0;
1432 const Type *RetTy = FI.getReturnType();
1433 FI.getReturnInfo() = classifyReturnType(RetTy);
1436 if (FI.getReturnInfo().isIndirect())
1439 unsigned NumRequiredArgs = FI.getNumRequiredArgs();
1442 for (
auto IT = FI.arg_begin(), IE = FI.arg_end();
IT != IE; ++
IT, ++ArgNo) {
1443 bool IsNamedArg = ArgNo < NumRequiredArgs;
1444 const Type *ArgTy =
IT->ABIType;
1448 ArgInfo AI = classifyArgumentType(ArgTy, FreeIntRegs, NeededInt, NeededSSE,
1455 if (FreeIntRegs >= NeededInt && FreeSSERegs >= NeededSSE) {
1456 FreeIntRegs -= NeededInt;
1457 FreeSSERegs -= NeededSSE;
1461 IT->Info = getIndirectResult(ArgTy, FreeIntRegs);
1466std::unique_ptr<TargetInfo>
1469 return std::make_unique<X86_64TargetInfo>(TB, AVXLevel, Has64BitPointers,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
OptimizedStructLayoutField Field
FunctionLoweringInfo::StatepointRelocationRecord RecordType
Target-specific ABI information and factory functions.
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEquad()
static const fltSemantics & IEEEdouble()
static const fltSemantics & x87DoubleExtended()
static const fltSemantics & IEEEhalf()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
Check if the array is empty.
static constexpr ElementCount getFixed(ScalarTy MinVal)
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
Helper class to encapsulate information about how a specific type should be passed to or returned fro...
static ArgInfo getDirect(const Type *T=nullptr, unsigned Offset=0, MaybeAlign Align=std::nullopt)
static ArgInfo getIgnore()
static ArgInfo getExtend(const Type *T)
static ArgInfo getIndirect(Align Align, bool ByVal, unsigned AddrSpace=0, bool Realign=false)
Realign: the caller couldn't guarantee sufficient alignment - the callee must copy the argument to a ...
const fltSemantics * getSemantics() const
ArgInfo & getReturnInfo()
const Type * getReturnType() const
ArrayRef< FieldInfo > getFields() const
bool isTransparentUnion() const
LLVM_ABI ArgInfo getNaturalAlignIndirect(const Type *Ty, bool ByVal=true) const
const ABICompatInfo & getABICompatInfo() const
LLVM_ABI bool isPromotableInteger(const IntegerType *IT) const
LLVM_ABI bool isAggregateTypeForABI(const Type *Ty) const
LLVM_ABI RecordArgABI getRecordArgABI(const RecordType *RT) const
TypeBuilder manages the lifecycle of ABI types using bump pointer allocation.
Represents the ABI-specific view of a type in LLVM.
TypeSize getTypeAllocSize() const
TypeSize getSizeInBits() const
Align getAlignment() const
ElementCount getNumElements() const
const Type * getElementType() const
X86_64TargetInfo(TypeBuilder &TypeBuilder, X86AVXABILevel AVXABILevel, bool Has64BitPtrs, const ABICompatInfo &Compat)
bool has64BitPointers() const
constexpr ScalarTy getFixedValue() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
This class provides various memory handling functions that manipulate MemoryBlock instances.
This file defines the type system for the LLVMABI library, which mirrors ABI-relevant aspects of fron...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
CallingConv Namespace - This namespace contains an enum with a value for the well-known calling conve...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
static bool classifyCXXReturnType(FunctionInfo &FI)
static uint64_t getClangTypeWidthInBits(const Type *Ty)
static unsigned getNativeVectorSizeForAVXABI(X86AVXABILevel AVXLevel)
X86AVXABILevel
The AVX ABI level for X86 targets.
static const Type * reduceUnionForX8664(const RecordType *UnionType, TypeBuilder &TB)
static bool bitsContainNoUserData(const Type *Ty, unsigned StartBit, unsigned EndBit)
LLVM_ABI std::unique_ptr< TargetInfo > createX86_64TargetInfo(TypeBuilder &TB, X86AVXABILevel AVXLevel, bool Has64BitPointers, const ABICompatInfo &Compat)
static uint64_t getClangVectorWidthInBits(const VectorType *VT)
static uint64_t getClangIntegerWidthInBits(const IntegerType *IT)
static bool isFloatTypeWithSemantics(const Type *Ty, const fltSemantics &Semantics)
Helper to check if a floating point type matches specific semantics.
@ RAA_Indirect
Pass it as a pointer to temporary memory.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
ElementType
The element type of an SRV or UAV resource.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Flags controlling target-specific ABI compatibility behaviour.