Skip to content

Add support for DFP IR type. #69718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions llvm/docs/BitCodeFormat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,30 @@ The operand fields are

* *int_params*: Numbers that correspond to the integer parameters.

TYPE_CODE_DECIMAL32 Record
^^^^^^^^^^^^^^^^^^^^^^^^^^

``[DECIMAL32]``

The ``DECIMAL32`` record (code 27) adds a ``decimal32`` (32-bit
decimal floating point) type to the type table.

TYPE_CODE_DECIMAL64 Record
^^^^^^^^^^^^^^^^^^^^^^^^^^

``[DECIMAL64]``

The ``DECIMAL64`` record (code 28) adds a ``decimal64`` (64-bit
decimal floating point) type to the type table.

TYPE_CODE_DECIMAL128 Record
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``[DECIMAL128]``

The ``DECIMAL128`` record (code 29) adds a ``decimal128`` (128-bit
decimal floating point) type to the type table.

.. _CONSTANTS_BLOCK:

CONSTANTS_BLOCK Contents
Expand Down
9 changes: 9 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3672,6 +3672,15 @@ Floating-Point Types
* - ``ppc_fp128``
- 128-bit floating-point value (two 64-bits)

* - ``decimal32``
- 32-bit decimal floating-point value

* - ``decimal64``
- 64-bit decimal floating-point value

* - ``decimal128``
- 128-bit decimal floating-point value

The binary format of half, float, double, and fp128 correspond to the
IEEE-754-2008 specifications for binary16, binary32, binary64, and binary128
respectively.
Expand Down
21 changes: 21 additions & 0 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,13 @@ typedef enum {
LLVMVoidTypeKind, /**< type with no size */
LLVMHalfTypeKind, /**< 16 bit floating point type */
LLVMFloatTypeKind, /**< 32 bit floating point type */
LLVMDecimal32TypeKind, /**< 32 bit decimal floating point type */
LLVMDoubleTypeKind, /**< 64 bit floating point type */
LLVMDecimal64TypeKind, /**< 64 bit decimal floating point type */
LLVMX86_FP80TypeKind, /**< 80 bit floating point type (X87) */
LLVMFP128TypeKind, /**< 128 bit floating point type (112-bit mantissa)*/
LLVMPPC_FP128TypeKind, /**< 128 bit floating point type (two 64-bits) */
LLVMDecimal128TypeKind,/**< 128 bit decimal floating point type */
LLVMLabelTypeKind, /**< Labels */
LLVMIntegerTypeKind, /**< Arbitrary bit width integers */
LLVMFunctionTypeKind, /**< Functions */
Expand Down Expand Up @@ -1269,11 +1272,21 @@ LLVMTypeRef LLVMBFloatTypeInContext(LLVMContextRef C);
*/
LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C);

/**
* Obtain a 32-bit decimal floating point type from a context.
*/
LLVMTypeRef LLVMDecimal32TypeInContext(LLVMContextRef C);

/**
* Obtain a 64-bit floating point type from a context.
*/
LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C);

/**
* Obtain a 64-bit decimal floating point type from a context.
*/
LLVMTypeRef LLVMDecimal64TypeInContext(LLVMContextRef C);

/**
* Obtain a 80-bit floating point type (X87) from a context.
*/
Expand All @@ -1290,6 +1303,11 @@ LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C);
*/
LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C);

/**
* Obtain a 128-bit decimal floating point type from a context.
*/
LLVMTypeRef LLVMDecimal128TypeInContext(LLVMContextRef C);

/**
* Obtain a floating point type from the global context.
*
Expand All @@ -1298,10 +1316,13 @@ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C);
LLVMTypeRef LLVMHalfType(void);
LLVMTypeRef LLVMBFloatType(void);
LLVMTypeRef LLVMFloatType(void);
LLVMTypeRef LLVMDecimal32Type(void);
LLVMTypeRef LLVMDoubleType(void);
LLVMTypeRef LLVMDecimal64Type(void);
LLVMTypeRef LLVMX86FP80Type(void);
LLVMTypeRef LLVMFP128Type(void);
LLVMTypeRef LLVMPPCFP128Type(void);
LLVMTypeRef LLVMDecimal128Type(void);

/**
* @}
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ enum TypeCodes {
TYPE_CODE_OPAQUE_POINTER = 25, // OPAQUE_POINTER: [addrspace]

TYPE_CODE_TARGET_TYPE = 26, // TARGET_TYPE

TYPE_CODE_DECIMAL32 = 27, // 32-bit decimal floating point
TYPE_CODE_DECIMAL64 = 28, // 64-bit decimal floating point
TYPE_CODE_DECIMAL128 = 29 // 128-bit decimal floating point
};

enum OperandBundleTagCode {
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/DataLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -690,12 +690,15 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
case Type::BFloatTyID:
return TypeSize::Fixed(16);
case Type::FloatTyID:
case Type::Decimal32TyID:
return TypeSize::Fixed(32);
case Type::DoubleTyID:
case Type::X86_MMXTyID:
case Type::Decimal64TyID:
return TypeSize::Fixed(64);
case Type::PPC_FP128TyID:
case Type::FP128TyID:
case Type::Decimal128TyID:
return TypeSize::Fixed(128);
case Type::X86_AMXTyID:
return TypeSize::Fixed(8192);
Expand Down
15 changes: 15 additions & 0 deletions llvm/include/llvm/IR/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,21 @@ class IRBuilderBase {
return Type::getDoubleTy(Context);
}

/// Fetch the type representing a 32-bit decimal floating point value.
Type *getDecimal32Ty() {
return Type::getDecimal32Ty(Context);
}

/// Fetch the type representing a 64-bit decimal floating point value.
Type *getDecimal64Ty() {
return Type::getDecimal64Ty(Context);
}

/// Fetch the type representing a 128-bit decimal floating point value.
Type *getDecimal128Ty() {
return Type::getDecimal128Ty(Context);
}

/// Fetch the type representing void.
Type *getVoidTy() {
return Type::getVoidTy(Context);
Expand Down
18 changes: 18 additions & 0 deletions llvm/include/llvm/IR/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ class Type {
// PrimitiveTypes
HalfTyID = 0, ///< 16-bit floating point type
BFloatTyID, ///< 16-bit floating point type (7-bit significand)
Decimal32TyID, ///< 32-bit decimal floating point type
FloatTyID, ///< 32-bit floating point type
Decimal64TyID, ///< 64-bit decimal floating point type
DoubleTyID, ///< 64-bit floating point type
X86_FP80TyID, ///< 80-bit floating point type (X87)
Decimal128TyID, ///< 128-bit decimal floating point type
FP128TyID, ///< 128-bit floating point type (112-bit significand)
PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
VoidTyID, ///< type with no size
Expand Down Expand Up @@ -165,6 +168,15 @@ class Type {
/// Return true if this is powerpc long double.
bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }

/// Return true if this is 'decimal32'.
bool isDecimal32Ty() const { return getTypeID() == Decimal32TyID; }

/// Return true if this is 'decimal64'.
bool isDecimal64Ty() const { return getTypeID() == Decimal64TyID; }

/// Return true if this is 'decimal128'.
bool isDecimal128Ty() const { return getTypeID() == Decimal128TyID; }

/// Return true if this is a well-behaved IEEE-like type, which has a IEEE
/// compatible layout as defined by isIEEE(), and does not have unnormal
/// values
Expand All @@ -175,6 +187,9 @@ class Type {
case HalfTyID:
case BFloatTyID:
case FP128TyID:
case Decimal32TyID:
case Decimal64TyID:
case Decimal128TyID:
return true;
default:
return false;
Expand Down Expand Up @@ -448,11 +463,14 @@ class Type {
static Type *getHalfTy(LLVMContext &C);
static Type *getBFloatTy(LLVMContext &C);
static Type *getFloatTy(LLVMContext &C);
static Type *getDecimal32Ty(LLVMContext &C);
static Type *getDoubleTy(LLVMContext &C);
static Type *getDecimal64Ty(LLVMContext &C);
static Type *getMetadataTy(LLVMContext &C);
static Type *getX86_FP80Ty(LLVMContext &C);
static Type *getFP128Ty(LLVMContext &C);
static Type *getPPC_FP128Ty(LLVMContext &C);
static Type *getDecimal128Ty(LLVMContext &C);
static Type *getX86_MMXTy(LLVMContext &C);
static Type *getX86_AMXTy(LLVMContext &C);
static Type *getTokenTy(LLVMContext &C);
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,10 +816,13 @@ lltok::Kind LLLexer::LexIdentifier() {
TYPEKEYWORD("half", Type::getHalfTy(Context));
TYPEKEYWORD("bfloat", Type::getBFloatTy(Context));
TYPEKEYWORD("float", Type::getFloatTy(Context));
TYPEKEYWORD("decimal32", Type::getDecimal32Ty(Context));
TYPEKEYWORD("double", Type::getDoubleTy(Context));
TYPEKEYWORD("decimal64", Type::getDecimal64Ty(Context));
TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context));
TYPEKEYWORD("fp128", Type::getFP128Ty(Context));
TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));
TYPEKEYWORD("decimal128", Type::getDecimal128Ty(Context));
TYPEKEYWORD("label", Type::getLabelTy(Context));
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
Expand Down Expand Up @@ -984,9 +987,16 @@ lltok::Kind LLLexer::LexIdentifier() {
/// HexPPC128Constant 0xM[0-9A-Fa-f]+
/// HexHalfConstant 0xH[0-9A-Fa-f]+
/// HexBFloatConstant 0xR[0-9A-Fa-f]+
/// FIXME: I have temporarily added these prefixes temporarly to mimic
/// the DFP attributes in C++. But this is just a placeholder for
/// the real prefix.
/// HexDecimal32Constant 0xSD[0-9A-Fa-f]+
/// HexDecimal64Constant 0xDD[0-9A-Fa-f]+
/// HexDecimal128Constant 0xTD[0-9A-Fa-f]+
lltok::Kind LLLexer::Lex0x() {
CurPtr = TokStart + 2;

// TODO: Handle the DFP type here.
char Kind;
if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H' ||
CurPtr[0] == 'R') {
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2306,9 +2306,15 @@ Error BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_FLOAT: // FLOAT
ResultTy = Type::getFloatTy(Context);
break;
case bitc::TYPE_CODE_DECIMAL32: // 32-bit DFP
ResultTy = Type::getDecimal32Ty(Context);
break;
case bitc::TYPE_CODE_DOUBLE: // DOUBLE
ResultTy = Type::getDoubleTy(Context);
break;
case bitc::TYPE_CODE_DECIMAL64: // 64-bit DFP
ResultTy = Type::getDecimal64Ty(Context);
break;
case bitc::TYPE_CODE_X86_FP80: // X86_FP80
ResultTy = Type::getX86_FP80Ty(Context);
break;
Expand All @@ -2318,6 +2324,9 @@ Error BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128
ResultTy = Type::getPPC_FP128Ty(Context);
break;
case bitc::TYPE_CODE_DECIMAL128: // 128-bit DFP
ResultTy = Type::getDecimal128Ty(Context);
break;
case bitc::TYPE_CODE_LABEL: // LABEL
ResultTy = Type::getLabelTy(Context);
break;
Expand Down
29 changes: 16 additions & 13 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,19 +968,22 @@ void ModuleBitcodeWriter::writeTypeTable() {
unsigned Code = 0;

switch (T->getTypeID()) {
case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
case Type::BFloatTyID: Code = bitc::TYPE_CODE_BFLOAT; break;
case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break;
case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break;
case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break;
case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break;
case Type::BFloatTyID: Code = bitc::TYPE_CODE_BFLOAT; break;
case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break;
case Type::Decimal32TyID: Code = bitc::TYPE_CODE_DECIMAL32; break;
case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break;
case Type::Decimal64TyID: Code = bitc::TYPE_CODE_DECIMAL64; break;
case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break;
case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break;
case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break;
case Type::Decimal128TyID: Code = bitc::TYPE_CODE_DECIMAL128; break;
case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break;
case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break;
case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break;
case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break;
case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break;
case Type::IntegerTyID:
// INTEGER: [width]
Code = bitc::TYPE_CODE_INTEGER;
Expand Down
29 changes: 16 additions & 13 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,19 +545,22 @@ void TypePrinting::incorporateTypes() {
/// names or up references to shorten the type name where possible.
void TypePrinting::print(Type *Ty, raw_ostream &OS) {
switch (Ty->getTypeID()) {
case Type::VoidTyID: OS << "void"; return;
case Type::HalfTyID: OS << "half"; return;
case Type::BFloatTyID: OS << "bfloat"; return;
case Type::FloatTyID: OS << "float"; return;
case Type::DoubleTyID: OS << "double"; return;
case Type::X86_FP80TyID: OS << "x86_fp80"; return;
case Type::FP128TyID: OS << "fp128"; return;
case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
case Type::X86_AMXTyID: OS << "x86_amx"; return;
case Type::TokenTyID: OS << "token"; return;
case Type::VoidTyID: OS << "void"; return;
case Type::HalfTyID: OS << "half"; return;
case Type::BFloatTyID: OS << "bfloat"; return;
case Type::FloatTyID: OS << "float"; return;
case Type::Decimal32TyID: OS << "decimal32"; return;
case Type::DoubleTyID: OS << "double"; return;
case Type::Decimal64TyID: OS << "decimal64"; return;
case Type::X86_FP80TyID: OS << "x86_fp80"; return;
case Type::FP128TyID: OS << "fp128"; return;
case Type::PPC_FP128TyID: OS << "ppc_fp128"; return;
case Type::Decimal128TyID: OS << "decimal128"; return;
case Type::LabelTyID: OS << "label"; return;
case Type::MetadataTyID: OS << "metadata"; return;
case Type::X86_MMXTyID: OS << "x86_mmx"; return;
case Type::X86_AMXTyID: OS << "x86_amx"; return;
case Type::TokenTyID: OS << "token"; return;
case Type::IntegerTyID:
OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
return;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,14 +555,20 @@ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) {
return LLVMBFloatTypeKind;
case Type::FloatTyID:
return LLVMFloatTypeKind;
case Type::Decimal32TyID:
return LLVMDecimal32TypeKind;
case Type::DoubleTyID:
return LLVMDoubleTypeKind;
case Type::Decimal64TyID:
return LLVMDecimal64TypeKind;
case Type::X86_FP80TyID:
return LLVMX86_FP80TypeKind;
case Type::FP128TyID:
return LLVMFP128TypeKind;
case Type::PPC_FP128TyID:
return LLVMPPC_FP128TypeKind;
case Type::Decimal128TyID:
return LLVMDecimal128TypeKind;
case Type::LabelTyID:
return LLVMLabelTypeKind;
case Type::MetadataTyID:
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/IR/LLVMContextImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
: DiagHandler(std::make_unique<DiagnosticHandler>()),
VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID),
HalfTy(C, Type::HalfTyID), BFloatTy(C, Type::BFloatTyID),
FloatTy(C, Type::FloatTyID), DoubleTy(C, Type::DoubleTyID),
FloatTy(C, Type::FloatTyID), Decimal32Ty(C, Type::Decimal32TyID),
DoubleTy(C, Type::DoubleTyID), Decimal64Ty(C, Type::Decimal64TyID),
MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID),
X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),
PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
PPC_FP128Ty(C, Type::PPC_FP128TyID),
Decimal128Ty(C, Type::Decimal128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {}

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/IR/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1520,9 +1520,9 @@ class LLVMContextImpl {
ConstantInt *TheFalseVal = nullptr;

// Basic type instances.
Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy,
TokenTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy;
Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, Decimal32Ty, DoubleTy;
Type Decimal64Ty, MetadataTy, TokenTy;
Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, Decimal128Ty, X86_MMXTy, X86_AMXTy;
IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty;

std::unique_ptr<ConstantTokenNone> TheNoneToken;
Expand Down
Loading