@@ -68,6 +68,10 @@ enum class fltNonfiniteBehavior {
68
68
// `fltNanEncoding` enum. We treat all NaNs as quiet, as the available
69
69
// encodings do not distinguish between signalling and quiet NaN.
70
70
NanOnly,
71
+
72
+ // This behavior is present in Float6E3M2FN and Float6E2M3FN types.
73
+ // There is no representation for Inf or NaN.
74
+ NoNanInf,
71
75
};
72
76
73
77
// How NaN values are represented. This is curently only used in combination
@@ -139,6 +143,10 @@ static constexpr fltSemantics semFloat8E4M3FNUZ = {
139
143
static constexpr fltSemantics semFloat8E4M3B11FNUZ = {
140
144
4 , -10 , 4 , 8 , fltNonfiniteBehavior::NanOnly, fltNanEncoding::NegativeZero};
141
145
static constexpr fltSemantics semFloatTF32 = {127 , -126 , 11 , 19 };
146
+ static constexpr fltSemantics semFloat6E3M2FN = {
147
+ 4 , -2 , 3 , 6 , fltNonfiniteBehavior::NoNanInf};
148
+ static constexpr fltSemantics semFloat6E2M3FN = {
149
+ 2 , 0 , 4 , 6 , fltNonfiniteBehavior::NoNanInf};
142
150
static constexpr fltSemantics semX87DoubleExtended = {16383 , -16382 , 64 , 80 };
143
151
static constexpr fltSemantics semBogus = {0 , 0 , 0 , 0 };
144
152
@@ -206,6 +214,10 @@ const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
206
214
return Float8E4M3B11FNUZ ();
207
215
case S_FloatTF32:
208
216
return FloatTF32 ();
217
+ case S_Float6E3M2FN:
218
+ return Float6E3M2FN ();
219
+ case S_Float6E2M3FN:
220
+ return Float6E2M3FN ();
209
221
case S_x87DoubleExtended:
210
222
return x87DoubleExtended ();
211
223
}
@@ -238,6 +250,10 @@ APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
238
250
return S_Float8E4M3B11FNUZ;
239
251
else if (&Sem == &llvm::APFloat::FloatTF32 ())
240
252
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;
241
257
else if (&Sem == &llvm::APFloat::x87DoubleExtended ())
242
258
return S_x87DoubleExtended;
243
259
else
@@ -260,6 +276,8 @@ const fltSemantics &APFloatBase::Float8E4M3B11FNUZ() {
260
276
return semFloat8E4M3B11FNUZ;
261
277
}
262
278
const fltSemantics &APFloatBase::FloatTF32 () { return semFloatTF32; }
279
+ const fltSemantics &APFloatBase::Float6E3M2FN () { return semFloat6E3M2FN; }
280
+ const fltSemantics &APFloatBase::Float6E2M3FN () { return semFloat6E2M3FN; }
263
281
const fltSemantics &APFloatBase::x87DoubleExtended () {
264
282
return semX87DoubleExtended;
265
283
}
@@ -878,6 +896,10 @@ void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
878
896
for the significand. If double or longer, this is a signalling NaN,
879
897
which may not be ideal. If float, this is QNaN(0). */
880
898
void IEEEFloat::makeNaN (bool SNaN, bool Negative, const APInt *fill) {
899
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NoNanInf) {
900
+ assert (false && " This floating point format does not support NaN\n " );
901
+ return ;
902
+ }
881
903
category = fcNaN;
882
904
sign = Negative;
883
905
exponent = exponentNaN ();
@@ -1499,16 +1521,18 @@ static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts,
1499
1521
/* Handle overflow. Sign is preserved. We either become infinity or
1500
1522
the largest finite number. */
1501
1523
IEEEFloat::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);
1524
+ if (semantics->nonFiniteBehavior != fltNonfiniteBehavior::NoNanInf) {
1525
+ /* Infinity? */
1526
+ if (rounding_mode == rmNearestTiesToEven ||
1527
+ rounding_mode == rmNearestTiesToAway ||
1528
+ (rounding_mode == rmTowardPositive && !sign) ||
1529
+ (rounding_mode == rmTowardNegative && sign)) {
1530
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
1531
+ makeNaN (false , sign);
1532
+ else
1533
+ category = fcInfinity;
1534
+ return (opStatus)(opOverflow | opInexact);
1535
+ }
1512
1536
}
1513
1537
1514
1538
/* Otherwise we become the largest finite number. */
@@ -3518,13 +3542,17 @@ APInt IEEEFloat::convertIEEEFloatToAPInt() const {
3518
3542
myexponent = ::exponentZero (S) + bias;
3519
3543
mysignificand.fill (0 );
3520
3544
} else if (category == fcInfinity) {
3521
- if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
3545
+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
3546
+ S.nonFiniteBehavior == fltNonfiniteBehavior::NoNanInf) {
3522
3547
llvm_unreachable (" semantics don't support inf!" );
3523
3548
}
3524
3549
myexponent = ::exponentInf (S) + bias;
3525
3550
mysignificand.fill (0 );
3526
3551
} else {
3527
3552
assert (category == fcNaN && " Unknown category!" );
3553
+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::NoNanInf) {
3554
+ llvm_unreachable (" semantics don't support NaN!" );
3555
+ }
3528
3556
myexponent = ::exponentNaN (S) + bias;
3529
3557
std::copy_n (significandParts (), mysignificand.size (),
3530
3558
mysignificand.begin ());
@@ -3605,6 +3633,16 @@ APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const {
3605
3633
return convertIEEEFloatToAPInt<semFloatTF32>();
3606
3634
}
3607
3635
3636
+ APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt () const {
3637
+ assert (partCount () == 1 );
3638
+ return convertIEEEFloatToAPInt<semFloat6E3M2FN>();
3639
+ }
3640
+
3641
+ APInt IEEEFloat::convertFloat6E2M3FNAPFloatToAPInt () const {
3642
+ assert (partCount () == 1 );
3643
+ return convertIEEEFloatToAPInt<semFloat6E2M3FN>();
3644
+ }
3645
+
3608
3646
// This function creates an APInt that is just a bit map of the floating
3609
3647
// point constant as it would appear in memory. It is not a conversion,
3610
3648
// and treating the result as a normal integer is unlikely to be useful.
@@ -3646,6 +3684,12 @@ APInt IEEEFloat::bitcastToAPInt() const {
3646
3684
if (semantics == (const llvm::fltSemantics *)&semFloatTF32)
3647
3685
return convertFloatTF32APFloatToAPInt ();
3648
3686
3687
+ if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN)
3688
+ return convertFloat6E3M2FNAPFloatToAPInt ();
3689
+
3690
+ if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN)
3691
+ return convertFloat6E2M3FNAPFloatToAPInt ();
3692
+
3649
3693
assert (semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
3650
3694
" unknown format!" );
3651
3695
return convertF80LongDoubleAPFloatToAPInt ();
@@ -3862,6 +3906,14 @@ void IEEEFloat::initFromFloatTF32APInt(const APInt &api) {
3862
3906
initFromIEEEAPInt<semFloatTF32>(api);
3863
3907
}
3864
3908
3909
+ void IEEEFloat::initFromFloat6E3M2FNAPInt (const APInt &api) {
3910
+ initFromIEEEAPInt<semFloat6E3M2FN>(api);
3911
+ }
3912
+
3913
+ void IEEEFloat::initFromFloat6E2M3FNAPInt (const APInt &api) {
3914
+ initFromIEEEAPInt<semFloat6E2M3FN>(api);
3915
+ }
3916
+
3865
3917
// / Treat api as containing the bits of a floating point number.
3866
3918
void IEEEFloat::initFromAPInt (const fltSemantics *Sem, const APInt &api) {
3867
3919
assert (api.getBitWidth () == Sem->sizeInBits );
@@ -3891,6 +3943,10 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
3891
3943
return initFromFloat8E4M3B11FNUZAPInt (api);
3892
3944
if (Sem == &semFloatTF32)
3893
3945
return initFromFloatTF32APInt (api);
3946
+ if (Sem == &semFloat6E3M2FN)
3947
+ return initFromFloat6E3M2FNAPInt (api);
3948
+ if (Sem == &semFloat6E2M3FN)
3949
+ return initFromFloat6E2M3FNAPInt (api);
3894
3950
3895
3951
llvm_unreachable (nullptr );
3896
3952
}
@@ -4328,7 +4384,8 @@ int IEEEFloat::getExactLog2Abs() const {
4328
4384
bool IEEEFloat::isSignaling () const {
4329
4385
if (!isNaN ())
4330
4386
return false ;
4331
- if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
4387
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
4388
+ semantics->nonFiniteBehavior == fltNonfiniteBehavior::NoNanInf)
4332
4389
return false ;
4333
4390
4334
4391
// IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
@@ -4387,6 +4444,10 @@ IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
4387
4444
// nextUp(getLargest()) == NAN
4388
4445
makeNaN ();
4389
4446
break ;
4447
+ } else if (semantics->nonFiniteBehavior ==
4448
+ fltNonfiniteBehavior::NoNanInf) {
4449
+ // nextUp(getLargest()) == getLargest()
4450
+ break ;
4390
4451
} else {
4391
4452
// nextUp(getLargest()) == INFINITY
4392
4453
APInt::tcSet (significandParts (), 0 , partCount ());
@@ -4477,6 +4538,10 @@ APFloatBase::ExponentType IEEEFloat::exponentZero() const {
4477
4538
}
4478
4539
4479
4540
void IEEEFloat::makeInf (bool Negative) {
4541
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NoNanInf) {
4542
+ assert (false && " This floating point format does not support Inf\n " );
4543
+ return ;
4544
+ }
4480
4545
if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4481
4546
// There is no Inf, so make NaN instead.
4482
4547
makeNaN (false , Negative);
0 commit comments