@@ -68,6 +68,10 @@ enum class fltNonfiniteBehavior {
6868 // `fltNanEncoding` enum. We treat all NaNs as quiet, as the available
6969 // encodings do not distinguish between signalling and quiet NaN.
7070 NanOnly,
71+
72+ // This behavior is present in Float6E3M2FN and Float6E2M3FN types,
73+ // which do not support Inf or NaN values.
74+ FiniteOnly,
7175};
7276
7377// How NaN values are represented. This is curently only used in combination
@@ -139,6 +143,10 @@ static constexpr fltSemantics semFloat8E4M3FNUZ = {
139143static constexpr fltSemantics semFloat8E4M3B11FNUZ = {
140144 4 , -10 , 4 , 8 , fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
141145static constexpr fltSemantics semFloatTF32 = {127 , -126 , 11 , 19 };
146+ static constexpr fltSemantics semFloat6E3M2FN = {
147+ 4 , -2 , 3 , 6 , fltNonfiniteBehavior::FiniteOnly};
148+ static constexpr fltSemantics semFloat6E2M3FN = {
149+ 2 , 0 , 4 , 6 , fltNonfiniteBehavior::FiniteOnly};
142150static constexpr fltSemantics semX87DoubleExtended = {16383 , -16382 , 64 , 80 };
143151static constexpr fltSemantics semBogus = {0 , 0 , 0 , 0 };
144152
@@ -206,6 +214,10 @@ const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
206214 return Float8E4M3B11FNUZ ();
207215 case S_FloatTF32:
208216 return FloatTF32 ();
217+ case S_Float6E3M2FN:
218+ return Float6E3M2FN ();
219+ case S_Float6E2M3FN:
220+ return Float6E2M3FN ();
209221 case S_x87DoubleExtended:
210222 return x87DoubleExtended ();
211223 }
@@ -238,6 +250,10 @@ APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
238250 return S_Float8E4M3B11FNUZ;
239251 else if (&Sem == &llvm::APFloat::FloatTF32 ())
240252 return S_FloatTF32;
253+ else if (&Sem == &llvm::APFloat::Float6E3M2FN ())
254+ return S_Float6E3M2FN;
255+ else if (&Sem == &llvm::APFloat::Float6E2M3FN ())
256+ return S_Float6E2M3FN;
241257 else if (&Sem == &llvm::APFloat::x87DoubleExtended ())
242258 return S_x87DoubleExtended;
243259 else
@@ -260,6 +276,8 @@ const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() {
260276 return semFloat8E4M3B11FNUZ;
261277}
262278const fltSemantics &APFloatBase::FloatTF32 () { return semFloatTF32; }
279+ const fltSemantics &APFloatBase::Float6E3M2FN () { return semFloat6E3M2FN; }
280+ const fltSemantics &APFloatBase::Float6E2M3FN () { return semFloat6E2M3FN; }
263281const fltSemantics &APFloatBase::x87DoubleExtended () {
264282 return semX87DoubleExtended;
265283}
@@ -878,6 +896,9 @@ void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
878896 for the significand. If double or longer, this is a signalling NaN,
879897 which may not be ideal. If float, this is QNaN(0). */
880898void IEEEFloat::makeNaN (bool SNaN, bool Negative, const APInt *fill) {
899+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
900+ llvm_unreachable (" This floating point format does not support NaN" );
901+
881902 category = fcNaN;
882903 sign = Negative;
883904 exponent = exponentNaN ();
@@ -1499,16 +1520,18 @@ static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts,
14991520/* Handle overflow. Sign is preserved. We either become infinity or
15001521 the largest finite number. */
15011522IEEEFloat::opStatus IEEEFloat::handleOverflow (roundingMode rounding_mode) {
1502- /* Infinity? */
1503- if (rounding_mode == rmNearestTiesToEven ||
1504- rounding_mode == rmNearestTiesToAway ||
1505- (rounding_mode == rmTowardPositive && !sign) ||
1506- (rounding_mode == rmTowardNegative && sign)) {
1507- if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1508- makeNaN (false , sign);
1509- else
1510- category = fcInfinity;
1511- return (opStatus) (opOverflow | opInexact);
1523+ if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::FiniteOnly) {
1524+ /* Infinity? */
1525+ if (rounding_mode == rmNearestTiesToEven ||
1526+ rounding_mode == rmNearestTiesToAway ||
1527+ (rounding_mode == rmTowardPositive && !sign) ||
1528+ (rounding_mode == rmTowardNegative && sign)) {
1529+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1530+ makeNaN (false , sign);
1531+ else
1532+ category = fcInfinity;
1533+ return static_cast <opStatus>(opOverflow | opInexact);
1534+ }
15121535 }
15131536
15141537 /* Otherwise we become the largest finite number. */
@@ -3518,13 +3541,15 @@ APInt IEEEFloat::convertIEEEFloatToAPInt() const {
35183541 myexponent = ::exponentZero (S) + bias;
35193542 mysignificand.fill (0 );
35203543 } else if (category == fcInfinity) {
3521- if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
3544+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
3545+ S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
35223546 llvm_unreachable (" semantics don't support inf!" );
3523- }
35243547 myexponent = ::exponentInf (S) + bias;
35253548 mysignificand.fill (0 );
35263549 } else {
35273550 assert (category == fcNaN && " Unknown category!" );
3551+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
3552+ llvm_unreachable (" semantics don't support NaN!" );
35283553 myexponent = ::exponentNaN (S) + bias;
35293554 std::copy_n (significandParts (), mysignificand.size (),
35303555 mysignificand.begin ());
@@ -3605,6 +3630,16 @@ APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const {
36053630 return convertIEEEFloatToAPInt<semFloatTF32>();
36063631}
36073632
3633+ APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt () const {
3634+ assert (partCount () == 1 );
3635+ return convertIEEEFloatToAPInt<semFloat6E3M2FN>();
3636+ }
3637+
3638+ APInt IEEEFloat::convertFloat6E2M3FNAPFloatToAPInt () const {
3639+ assert (partCount () == 1 );
3640+ return convertIEEEFloatToAPInt<semFloat6E2M3FN>();
3641+ }
3642+
36083643// This function creates an APInt that is just a bit map of the floating
36093644// point constant as it would appear in memory. It is not a conversion,
36103645// and treating the result as a normal integer is unlikely to be useful.
@@ -3646,6 +3681,12 @@ APInt IEEEFloat::bitcastToAPInt() const {
36463681 if (semantics == (const llvm::fltSemantics *)&semFloatTF32)
36473682 return convertFloatTF32APFloatToAPInt ();
36483683
3684+ if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN)
3685+ return convertFloat6E3M2FNAPFloatToAPInt ();
3686+
3687+ if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN)
3688+ return convertFloat6E2M3FNAPFloatToAPInt ();
3689+
36493690 assert (semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
36503691 " unknown format!" );
36513692 return convertF80LongDoubleAPFloatToAPInt ();
@@ -3862,6 +3903,14 @@ void IEEEFloat::initFromFloatTF32APInt(const APInt &api) {
38623903 initFromIEEEAPInt<semFloatTF32>(api);
38633904}
38643905
3906+ void IEEEFloat::initFromFloat6E3M2FNAPInt (const APInt &api) {
3907+ initFromIEEEAPInt<semFloat6E3M2FN>(api);
3908+ }
3909+
3910+ void IEEEFloat::initFromFloat6E2M3FNAPInt (const APInt &api) {
3911+ initFromIEEEAPInt<semFloat6E2M3FN>(api);
3912+ }
3913+
38653914// / Treat api as containing the bits of a floating point number.
38663915void IEEEFloat::initFromAPInt (const fltSemantics *Sem, const APInt &api) {
38673916 assert (api.getBitWidth () == Sem->sizeInBits );
@@ -3891,6 +3940,10 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
38913940 return initFromFloat8E4M3B11FNUZAPInt (api);
38923941 if (Sem == &semFloatTF32)
38933942 return initFromFloatTF32APInt (api);
3943+ if (Sem == &semFloat6E3M2FN)
3944+ return initFromFloat6E3M2FNAPInt (api);
3945+ if (Sem == &semFloat6E2M3FN)
3946+ return initFromFloat6E2M3FNAPInt (api);
38943947
38953948 llvm_unreachable (nullptr );
38963949}
@@ -4328,7 +4381,8 @@ int IEEEFloat::getExactLog2Abs() const {
43284381bool IEEEFloat::isSignaling () const {
43294382 if (!isNaN ())
43304383 return false ;
4331- if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
4384+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
4385+ semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
43324386 return false ;
43334387
43344388 // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
@@ -4387,6 +4441,10 @@ IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
43874441 // nextUp(getLargest()) == NAN
43884442 makeNaN ();
43894443 break ;
4444+ } else if (semantics->nonFiniteBehavior ==
4445+ fltNonfiniteBehavior::FiniteOnly) {
4446+ // nextUp(getLargest()) == getLargest()
4447+ break ;
43904448 } else {
43914449 // nextUp(getLargest()) == INFINITY
43924450 APInt::tcSet (significandParts (), 0 , partCount ());
@@ -4477,6 +4535,9 @@ APFloatBase::ExponentType IEEEFloat::exponentZero() const {
44774535}
44784536
44794537void IEEEFloat::makeInf (bool Negative) {
4538+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
4539+ llvm_unreachable (" This floating point format does not support Inf" );
4540+
44804541 if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
44814542 // There is no Inf, so make NaN instead.
44824543 makeNaN (false , Negative);
0 commit comments