@@ -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
+ // which do not support Inf or NaN values.
74
+ FiniteOnly,
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::FiniteOnly};
148
+ static constexpr fltSemantics semFloat6E2M3FN = {
149
+ 2 , 0 , 4 , 6 , fltNonfiniteBehavior::FiniteOnly};
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,9 @@ 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::FiniteOnly)
900
+ llvm_unreachable (" This floating point format does not support NaN" );
901
+
881
902
category = fcNaN;
882
903
sign = Negative;
883
904
exponent = exponentNaN ();
@@ -1499,16 +1520,18 @@ static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts,
1499
1520
/* Handle overflow. Sign is preserved. We either become infinity or
1500
1521
the largest finite number. */
1501
1522
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);
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
+ }
1512
1535
}
1513
1536
1514
1537
/* Otherwise we become the largest finite number. */
@@ -3518,13 +3541,15 @@ APInt IEEEFloat::convertIEEEFloatToAPInt() const {
3518
3541
myexponent = ::exponentZero (S) + bias;
3519
3542
mysignificand.fill (0 );
3520
3543
} else if (category == fcInfinity) {
3521
- if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
3544
+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
3545
+ S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
3522
3546
llvm_unreachable (" semantics don't support inf!" );
3523
- }
3524
3547
myexponent = ::exponentInf (S) + bias;
3525
3548
mysignificand.fill (0 );
3526
3549
} else {
3527
3550
assert (category == fcNaN && " Unknown category!" );
3551
+ if (S.nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
3552
+ llvm_unreachable (" semantics don't support NaN!" );
3528
3553
myexponent = ::exponentNaN (S) + bias;
3529
3554
std::copy_n (significandParts (), mysignificand.size (),
3530
3555
mysignificand.begin ());
@@ -3605,6 +3630,16 @@ APInt IEEEFloat::convertFloatTF32APFloatToAPInt() const {
3605
3630
return convertIEEEFloatToAPInt<semFloatTF32>();
3606
3631
}
3607
3632
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
+
3608
3643
// This function creates an APInt that is just a bit map of the floating
3609
3644
// point constant as it would appear in memory. It is not a conversion,
3610
3645
// and treating the result as a normal integer is unlikely to be useful.
@@ -3646,6 +3681,12 @@ APInt IEEEFloat::bitcastToAPInt() const {
3646
3681
if (semantics == (const llvm::fltSemantics *)&semFloatTF32)
3647
3682
return convertFloatTF32APFloatToAPInt ();
3648
3683
3684
+ if (semantics == (const llvm::fltSemantics *)&semFloat6E3M2FN)
3685
+ return convertFloat6E3M2FNAPFloatToAPInt ();
3686
+
3687
+ if (semantics == (const llvm::fltSemantics *)&semFloat6E2M3FN)
3688
+ return convertFloat6E2M3FNAPFloatToAPInt ();
3689
+
3649
3690
assert (semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
3650
3691
" unknown format!" );
3651
3692
return convertF80LongDoubleAPFloatToAPInt ();
@@ -3862,6 +3903,14 @@ void IEEEFloat::initFromFloatTF32APInt(const APInt &api) {
3862
3903
initFromIEEEAPInt<semFloatTF32>(api);
3863
3904
}
3864
3905
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
+
3865
3914
// / Treat api as containing the bits of a floating point number.
3866
3915
void IEEEFloat::initFromAPInt (const fltSemantics *Sem, const APInt &api) {
3867
3916
assert (api.getBitWidth () == Sem->sizeInBits );
@@ -3891,6 +3940,10 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
3891
3940
return initFromFloat8E4M3B11FNUZAPInt (api);
3892
3941
if (Sem == &semFloatTF32)
3893
3942
return initFromFloatTF32APInt (api);
3943
+ if (Sem == &semFloat6E3M2FN)
3944
+ return initFromFloat6E3M2FNAPInt (api);
3945
+ if (Sem == &semFloat6E2M3FN)
3946
+ return initFromFloat6E2M3FNAPInt (api);
3894
3947
3895
3948
llvm_unreachable (nullptr );
3896
3949
}
@@ -4328,7 +4381,8 @@ int IEEEFloat::getExactLog2Abs() const {
4328
4381
bool IEEEFloat::isSignaling () const {
4329
4382
if (!isNaN ())
4330
4383
return false ;
4331
- if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly)
4384
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly ||
4385
+ semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
4332
4386
return false ;
4333
4387
4334
4388
// 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) {
4387
4441
// nextUp(getLargest()) == NAN
4388
4442
makeNaN ();
4389
4443
break ;
4444
+ } else if (semantics->nonFiniteBehavior ==
4445
+ fltNonfiniteBehavior::FiniteOnly) {
4446
+ // nextUp(getLargest()) == getLargest()
4447
+ break ;
4390
4448
} else {
4391
4449
// nextUp(getLargest()) == INFINITY
4392
4450
APInt::tcSet (significandParts (), 0 , partCount ());
@@ -4477,6 +4535,9 @@ APFloatBase::ExponentType IEEEFloat::exponentZero() const {
4477
4535
}
4478
4536
4479
4537
void IEEEFloat::makeInf (bool Negative) {
4538
+ if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::FiniteOnly)
4539
+ llvm_unreachable (" This floating point format does not support Inf" );
4540
+
4480
4541
if (semantics->nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
4481
4542
// There is no Inf, so make NaN instead.
4482
4543
makeNaN (false , Negative);
0 commit comments