Skip to content

Commit 99f527d

Browse files
authored
[APFloat] Add APFloat support for E8M0 type (#107127)
This patch adds an APFloat type for unsigned E8M0 format. This format is used for representing the "scale-format" in the MX specification: (section 5.4) https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf This format does not support {Inf, denorms, zeroes}. Like FP32, this format's exponents are 8-bits (all bits here) and the bias value is 127. However, it differs from IEEE-FP32 in that the minExponent is -127 (instead of -126). There are updates done in the APFloat utility functions to handle these constraints for this format. * The bias calculation is different and convertIEEE* APIs are updated to handle this. * Since there are no significand bits, the isSignificandAll{Zeroes/Ones} methods are updated accordingly. * Although the format does not have any precision, the precision bit in the fltSemantics is set to 1 for consistency with APFloat's internal representation. * Many utility functions are updated to handle the fact that this format does not support Zero. * Provide a separate initFromAPInt() implementation to handle the quirks of the format. * Add specific tests to verify the range of values for this format. Signed-off-by: Durgadoss R <[email protected]>
1 parent 5e92bfe commit 99f527d

File tree

3 files changed

+653
-30
lines changed

3 files changed

+653
-30
lines changed

llvm/include/llvm/ADT/APFloat.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@ struct APFloatBase {
195195
// improved range compared to half (16-bit) formats, at (potentially)
196196
// greater throughput than single precision (32-bit) formats.
197197
S_FloatTF32,
198+
// 8-bit floating point number with (all the) 8 bits for the exponent
199+
// like in FP32. There are no zeroes, no infinities, and no denormal values.
200+
// This format has unsigned representation only. (U -> Unsigned only).
201+
// NaN is represented with all bits set to 1. Bias is 127.
202+
// This format represents the scale data type in the MX specification from:
203+
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
204+
S_Float8E8M0FNU,
198205
// 6-bit floating point number with bit layout S1E3M2. Unlike IEEE-754
199206
// types, there are no infinity or NaN values. The format is detailed in
200207
// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
@@ -229,6 +236,7 @@ struct APFloatBase {
229236
static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
230237
static const fltSemantics &Float8E3M4() LLVM_READNONE;
231238
static const fltSemantics &FloatTF32() LLVM_READNONE;
239+
static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
232240
static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
233241
static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
234242
static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
@@ -581,7 +589,8 @@ class IEEEFloat final : public APFloatBase {
581589
integerPart addSignificand(const IEEEFloat &);
582590
integerPart subtractSignificand(const IEEEFloat &, integerPart);
583591
lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract);
584-
lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat);
592+
lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat,
593+
bool ignoreAddend = false);
585594
lostFraction multiplySignificand(const IEEEFloat&);
586595
lostFraction divideSignificand(const IEEEFloat &);
587596
void incrementSignificand();
@@ -591,6 +600,7 @@ class IEEEFloat final : public APFloatBase {
591600
unsigned int significandLSB() const;
592601
unsigned int significandMSB() const;
593602
void zeroSignificand();
603+
unsigned int getNumHighBits() const;
594604
/// Return true if the significand excluding the integral bit is all ones.
595605
bool isSignificandAllOnes() const;
596606
bool isSignificandAllOnesExceptLSB() const;
@@ -652,6 +662,7 @@ class IEEEFloat final : public APFloatBase {
652662
APInt convertFloat8E4M3B11FNUZAPFloatToAPInt() const;
653663
APInt convertFloat8E3M4APFloatToAPInt() const;
654664
APInt convertFloatTF32APFloatToAPInt() const;
665+
APInt convertFloat8E8M0FNUAPFloatToAPInt() const;
655666
APInt convertFloat6E3M2FNAPFloatToAPInt() const;
656667
APInt convertFloat6E2M3FNAPFloatToAPInt() const;
657668
APInt convertFloat4E2M1FNAPFloatToAPInt() const;
@@ -672,6 +683,7 @@ class IEEEFloat final : public APFloatBase {
672683
void initFromFloat8E4M3B11FNUZAPInt(const APInt &api);
673684
void initFromFloat8E3M4APInt(const APInt &api);
674685
void initFromFloatTF32APInt(const APInt &api);
686+
void initFromFloat8E8M0FNUAPInt(const APInt &api);
675687
void initFromFloat6E3M2FNAPInt(const APInt &api);
676688
void initFromFloat6E2M3FNAPInt(const APInt &api);
677689
void initFromFloat4E2M1FNAPInt(const APInt &api);
@@ -1079,6 +1091,9 @@ class APFloat : public APFloatBase {
10791091
/// \param Semantics - type float semantics
10801092
static APFloat getAllOnesValue(const fltSemantics &Semantics);
10811093

1094+
/// Returns true if the given semantics supports either NaN or Infinity.
1095+
///
1096+
/// \param Sem - type float semantics
10821097
static bool hasNanOrInf(const fltSemantics &Sem) {
10831098
switch (SemanticsToEnum(Sem)) {
10841099
default:
@@ -1091,6 +1106,13 @@ class APFloat : public APFloatBase {
10911106
}
10921107
}
10931108

1109+
/// Returns true if the given semantics has actual significand.
1110+
///
1111+
/// \param Sem - type float semantics
1112+
static bool hasSignificand(const fltSemantics &Sem) {
1113+
return &Sem != &Float8E8M0FNU();
1114+
}
1115+
10941116
/// Used to insert APFloat objects, or objects that contain APFloat objects,
10951117
/// into FoldingSets.
10961118
void Profile(FoldingSetNodeID &NID) const;

0 commit comments

Comments
 (0)