[llvm][NFC] APFloat: Add missing semantics to enum (#117291)
* Add missing semantics to the `Semantics` enum. * Move all documentation of the semantics to the header file. * Also rename some functions for consistency.
This commit is contained in:
committed by
GitHub
parent
2fea1ccb62
commit
f50ce316ec
@@ -155,7 +155,41 @@ struct APFloatBase {
|
||||
S_IEEEsingle,
|
||||
S_IEEEdouble,
|
||||
S_IEEEquad,
|
||||
// The IBM double-double semantics. Such a number consists of a pair of
|
||||
// IEEE 64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
|
||||
// (double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
|
||||
// Therefore it has two 53-bit mantissa parts that aren't necessarily
|
||||
// adjacent to each other, and two 11-bit exponents.
|
||||
//
|
||||
// Note: we need to make the value different from semBogus as otherwise
|
||||
// an unsafe optimization may collapse both values to a single address,
|
||||
// and we heavily rely on them having distinct addresses.
|
||||
S_PPCDoubleDouble,
|
||||
// These are legacy semantics for the fallback, inaccurate implementation
|
||||
// of IBM double-double, if the accurate semPPCDoubleDouble doesn't handle
|
||||
// the operation. It's equivalent to having an IEEE number with consecutive
|
||||
// 106 bits of mantissa and 11 bits of exponent.
|
||||
//
|
||||
// It's not equivalent to IBM double-double. For example, a legit IBM
|
||||
// double-double, 1 + epsilon:
|
||||
//
|
||||
// 1 + epsilon = 1 + (1 >> 1076)
|
||||
//
|
||||
// is not representable by a consecutive 106 bits of mantissa.
|
||||
//
|
||||
// Currently, these semantics are used in the following way:
|
||||
//
|
||||
// semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
|
||||
// (64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
|
||||
// semPPCDoubleDoubleLegacy -> IEEE operations
|
||||
//
|
||||
// We use bitcastToAPInt() to get the bit representation (in APInt) of the
|
||||
// underlying IEEEdouble, then use the APInt constructor to construct the
|
||||
// legacy IEEE float.
|
||||
//
|
||||
// TODO: Implement all operations in semPPCDoubleDouble, and delete these
|
||||
// semantics.
|
||||
S_PPCDoubleDoubleLegacy,
|
||||
// 8-bit floating point number following IEEE-754 conventions with bit
|
||||
// layout S1E5M2 as described in https://arxiv.org/abs/2209.05433.
|
||||
S_Float8E5M2,
|
||||
@@ -214,7 +248,7 @@ struct APFloatBase {
|
||||
// types, there are no infinity or NaN values. The format is detailed in
|
||||
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
|
||||
S_Float4E2M1FN,
|
||||
|
||||
// TODO: Documentation is missing.
|
||||
S_x87DoubleExtended,
|
||||
S_MaxSemantics = S_x87DoubleExtended,
|
||||
};
|
||||
@@ -228,6 +262,7 @@ struct APFloatBase {
|
||||
static const fltSemantics &IEEEdouble() LLVM_READNONE;
|
||||
static const fltSemantics &IEEEquad() LLVM_READNONE;
|
||||
static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
|
||||
static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
|
||||
static const fltSemantics &Float8E5M2() LLVM_READNONE;
|
||||
static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
|
||||
static const fltSemantics &Float8E4M3() LLVM_READNONE;
|
||||
@@ -688,7 +723,7 @@ private:
|
||||
APInt convertDoubleAPFloatToAPInt() const;
|
||||
APInt convertQuadrupleAPFloatToAPInt() const;
|
||||
APInt convertF80LongDoubleAPFloatToAPInt() const;
|
||||
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
|
||||
APInt convertPPCDoubleDoubleLegacyAPFloatToAPInt() const;
|
||||
APInt convertFloat8E5M2APFloatToAPInt() const;
|
||||
APInt convertFloat8E5M2FNUZAPFloatToAPInt() const;
|
||||
APInt convertFloat8E4M3APFloatToAPInt() const;
|
||||
@@ -709,7 +744,7 @@ private:
|
||||
void initFromDoubleAPInt(const APInt &api);
|
||||
void initFromQuadrupleAPInt(const APInt &api);
|
||||
void initFromF80LongDoubleAPInt(const APInt &api);
|
||||
void initFromPPCDoubleDoubleAPInt(const APInt &api);
|
||||
void initFromPPCDoubleDoubleLegacyAPInt(const APInt &api);
|
||||
void initFromFloat8E5M2APInt(const APInt &api);
|
||||
void initFromFloat8E5M2FNUZAPInt(const APInt &api);
|
||||
void initFromFloat8E4M3APInt(const APInt &api);
|
||||
|
||||
@@ -164,42 +164,7 @@ static constexpr fltSemantics semFloat4E2M1FN = {
|
||||
2, 0, 2, 4, fltNonfiniteBehavior::FiniteOnly};
|
||||
static constexpr fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80};
|
||||
static constexpr fltSemantics semBogus = {0, 0, 0, 0};
|
||||
|
||||
/* The IBM double-double semantics. Such a number consists of a pair of IEEE
|
||||
64-bit doubles (Hi, Lo), where |Hi| > |Lo|, and if normal,
|
||||
(double)(Hi + Lo) == Hi. The numeric value it's modeling is Hi + Lo.
|
||||
Therefore it has two 53-bit mantissa parts that aren't necessarily adjacent
|
||||
to each other, and two 11-bit exponents.
|
||||
|
||||
Note: we need to make the value different from semBogus as otherwise
|
||||
an unsafe optimization may collapse both values to a single address,
|
||||
and we heavily rely on them having distinct addresses. */
|
||||
static constexpr fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128};
|
||||
|
||||
/* These are legacy semantics for the fallback, inaccrurate implementation of
|
||||
IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the
|
||||
operation. It's equivalent to having an IEEE number with consecutive 106
|
||||
bits of mantissa and 11 bits of exponent.
|
||||
|
||||
It's not equivalent to IBM double-double. For example, a legit IBM
|
||||
double-double, 1 + epsilon:
|
||||
|
||||
1 + epsilon = 1 + (1 >> 1076)
|
||||
|
||||
is not representable by a consecutive 106 bits of mantissa.
|
||||
|
||||
Currently, these semantics are used in the following way:
|
||||
|
||||
semPPCDoubleDouble -> (IEEEdouble, IEEEdouble) ->
|
||||
(64-bit APInt, 64-bit APInt) -> (128-bit APInt) ->
|
||||
semPPCDoubleDoubleLegacy -> IEEE operations
|
||||
|
||||
We use bitcastToAPInt() to get the bit representation (in APInt) of the
|
||||
underlying IEEEdouble, then use the APInt constructor to construct the
|
||||
legacy IEEE float.
|
||||
|
||||
TODO: Implement all operations in semPPCDoubleDouble, and delete these
|
||||
semantics. */
|
||||
static constexpr fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
|
||||
53 + 53, 128};
|
||||
|
||||
@@ -217,6 +182,8 @@ const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
|
||||
return IEEEquad();
|
||||
case S_PPCDoubleDouble:
|
||||
return PPCDoubleDouble();
|
||||
case S_PPCDoubleDoubleLegacy:
|
||||
return PPCDoubleDoubleLegacy();
|
||||
case S_Float8E5M2:
|
||||
return Float8E5M2();
|
||||
case S_Float8E5M2FNUZ:
|
||||
@@ -261,6 +228,8 @@ APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
|
||||
return S_IEEEquad;
|
||||
else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
|
||||
return S_PPCDoubleDouble;
|
||||
else if (&Sem == &llvm::APFloat::PPCDoubleDoubleLegacy())
|
||||
return S_PPCDoubleDoubleLegacy;
|
||||
else if (&Sem == &llvm::APFloat::Float8E5M2())
|
||||
return S_Float8E5M2;
|
||||
else if (&Sem == &llvm::APFloat::Float8E5M2FNUZ())
|
||||
@@ -299,6 +268,9 @@ const fltSemantics &APFloatBase::IEEEquad() { return semIEEEquad; }
|
||||
const fltSemantics &APFloatBase::PPCDoubleDouble() {
|
||||
return semPPCDoubleDouble;
|
||||
}
|
||||
const fltSemantics &APFloatBase::PPCDoubleDoubleLegacy() {
|
||||
return semPPCDoubleDoubleLegacy;
|
||||
}
|
||||
const fltSemantics &APFloatBase::Float8E5M2() { return semFloat8E5M2; }
|
||||
const fltSemantics &APFloatBase::Float8E5M2FNUZ() { return semFloat8E5M2FNUZ; }
|
||||
const fltSemantics &APFloatBase::Float8E4M3() { return semFloat8E4M3; }
|
||||
@@ -3574,7 +3546,7 @@ APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const {
|
||||
return APInt(80, words);
|
||||
}
|
||||
|
||||
APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
|
||||
APInt IEEEFloat::convertPPCDoubleDoubleLegacyAPFloatToAPInt() const {
|
||||
assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy);
|
||||
assert(partCount()==2);
|
||||
|
||||
@@ -3796,7 +3768,7 @@ APInt IEEEFloat::bitcastToAPInt() const {
|
||||
return convertQuadrupleAPFloatToAPInt();
|
||||
|
||||
if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleLegacy)
|
||||
return convertPPCDoubleDoubleAPFloatToAPInt();
|
||||
return convertPPCDoubleDoubleLegacyAPFloatToAPInt();
|
||||
|
||||
if (semantics == (const llvm::fltSemantics *)&semFloat8E5M2)
|
||||
return convertFloat8E5M2APFloatToAPInt();
|
||||
@@ -3900,7 +3872,7 @@ void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
|
||||
}
|
||||
}
|
||||
|
||||
void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) {
|
||||
void IEEEFloat::initFromPPCDoubleDoubleLegacyAPInt(const APInt &api) {
|
||||
uint64_t i1 = api.getRawData()[0];
|
||||
uint64_t i2 = api.getRawData()[1];
|
||||
opStatus fs;
|
||||
@@ -4119,7 +4091,7 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
|
||||
if (Sem == &semIEEEquad)
|
||||
return initFromQuadrupleAPInt(api);
|
||||
if (Sem == &semPPCDoubleDoubleLegacy)
|
||||
return initFromPPCDoubleDoubleAPInt(api);
|
||||
return initFromPPCDoubleDoubleLegacyAPInt(api);
|
||||
if (Sem == &semFloat8E5M2)
|
||||
return initFromFloat8E5M2APInt(api);
|
||||
if (Sem == &semFloat8E5M2FNUZ)
|
||||
@@ -4145,7 +4117,7 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
|
||||
if (Sem == &semFloat4E2M1FN)
|
||||
return initFromFloat4E2M1FNAPInt(api);
|
||||
|
||||
llvm_unreachable(nullptr);
|
||||
llvm_unreachable("unsupported semantics");
|
||||
}
|
||||
|
||||
/// Make this number the largest magnitude normal number in the given
|
||||
|
||||
Reference in New Issue
Block a user