[clang] [llvm] [LLVM][APFloat] Add APFloat support for 8-bit UE5M3 type (PR #210720)
Pradeep Kumar via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 20 11:57:33 PDT 2026
https://github.com/schwarzschild-radius updated https://github.com/llvm/llvm-project/pull/210720
>From e5312ce9472c1ca8986ca09bc65ad2d6c40d0cc9 Mon Sep 17 00:00:00 2001
From: Pradeep Kumar <pradeepku at nvidia.com>
Date: Thu, 16 Jul 2026 02:52:46 +0000
Subject: [PATCH 1/4] [LLVM][APFloat] Add APFloat support for 8-bit UE5M3 type
This commit adds APFloat support for UE5M3 type and the associated tests. It is an 8 bit FP type with no sign bit, 5 exponent and 3 mantissa bits
| Property | Value |
|-----------------|------------|
| Max exponent | 31 |
| Bias | 15 |
| Zero encoding | 00000 000 |
| Smallest denorm | 00000 001 |
| Largest denorm | 00000 111 |
| Smallest norm | 00001 000 |
| Largest norm | 11111 110 |
| Canonical NaN | 11111 111 |
Assisted by: Claude Code (Opus 4.8)
---
llvm/include/llvm/ADT/APFloat.h | 10 +
llvm/lib/Support/APFloat.cpp | 32 +-
llvm/unittests/ADT/APFloatTest.cpp | 450 +++++++++++++++++++++++++++--
3 files changed, 461 insertions(+), 31 deletions(-)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index ce94e0bacbeca..a9a3dc89a1730 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -256,6 +256,12 @@ class 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,
+ // 8-bit floating point number mostly following IEEE-754 conventions with
+ // bit layout S0E5M3 as described in PTX ISA page.
+ // https://docs.nvidia.com/cuda/developer-preview/13.4/parallel-thread-execution/index.html#alternate-floating-point-data-formats
+ // Unlike IEEE-754 types, there are no infinity values, and NaN is
+ // represented with the exponent and mantissa bits set to all 1s.
+ S_Float8E5M3FNU,
// TODO: Documentation is missing.
S_x87DoubleExtended,
S_MaxSemantics = S_x87DoubleExtended,
@@ -279,6 +285,7 @@ class APFloatBase {
LLVM_ABI static const fltSemantics semFloat8E3M4;
LLVM_ABI static const fltSemantics semFloatTF32;
LLVM_ABI static const fltSemantics semFloat8E8M0FNU;
+ LLVM_ABI static const fltSemantics semFloat8E5M3FNU;
LLVM_ABI static const fltSemantics semFloat6E3M2FN;
LLVM_ABI static const fltSemantics semFloat6E2M3FN;
LLVM_ABI static const fltSemantics semFloat4E2M1FN;
@@ -312,6 +319,7 @@ class APFloatBase {
static const fltSemantics &Float8E3M4() { return semFloat8E3M4; }
static const fltSemantics &FloatTF32() { return semFloatTF32; }
static const fltSemantics &Float8E8M0FNU() { return semFloat8E8M0FNU; }
+ static const fltSemantics &Float8E5M3FNU() { return semFloat8E5M3FNU; }
static const fltSemantics &Float6E3M2FN() { return semFloat6E3M2FN; }
static const fltSemantics &Float6E2M3FN() { return semFloat6E2M3FN; }
static const fltSemantics &Float4E2M1FN() { return semFloat4E2M1FN; }
@@ -778,6 +786,7 @@ class IEEEFloat final {
APInt convertFloat8E3M4APFloatToAPInt() const;
APInt convertFloatTF32APFloatToAPInt() const;
APInt convertFloat8E8M0FNUAPFloatToAPInt() const;
+ APInt convertFloat8E5M3FNUAPFloatToAPInt() const;
APInt convertFloat6E3M2FNAPFloatToAPInt() const;
APInt convertFloat6E2M3FNAPFloatToAPInt() const;
APInt convertFloat4E2M1FNAPFloatToAPInt() const;
@@ -799,6 +808,7 @@ class IEEEFloat final {
void initFromFloat8E3M4APInt(const APInt &api);
void initFromFloatTF32APInt(const APInt &api);
void initFromFloat8E8M0FNUAPInt(const APInt &api);
+ void initFromFloat8E5M3FNUAPInt(const APInt &api);
void initFromFloat6E3M2FNAPInt(const APInt &api);
void initFromFloat6E2M3FNAPInt(const APInt &api);
void initFromFloat4E2M1FNAPInt(const APInt &api);
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp
index 74f7803c43e67..2fe1ede16fda4 100644
--- a/llvm/lib/Support/APFloat.cpp
+++ b/llvm/lib/Support/APFloat.cpp
@@ -97,6 +97,17 @@ constexpr fltSemantics APFloatBase::semFloat8E8M0FNU = {
false,
false};
+constexpr fltSemantics APFloatBase::semFloat8E5M3FNU = {
+ 16,
+ -14,
+ 4,
+ 8,
+ fltNonfiniteBehavior::NanOnly,
+ fltNanEncoding::AllOnes,
+ true,
+ false,
+ false};
+
constexpr fltSemantics APFloatBase::semFloat6E3M2FN = {
4, -2, 3, 6, fltNonfiniteBehavior::FiniteOnly};
constexpr fltSemantics APFloatBase::semFloat6E2M3FN = {
@@ -154,6 +165,8 @@ const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
return FloatTF32();
case S_Float8E8M0FNU:
return Float8E8M0FNU();
+ case S_Float8E5M3FNU:
+ return Float8E5M3FNU();
case S_Float6E3M2FN:
return Float6E3M2FN();
case S_Float6E2M3FN:
@@ -200,6 +213,8 @@ APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
return S_FloatTF32;
else if (&Sem == &llvm::APFloat::Float8E8M0FNU())
return S_Float8E8M0FNU;
+ else if (&Sem == &llvm::APFloat::Float8E5M3FNU())
+ return S_Float8E5M3FNU;
else if (&Sem == &llvm::APFloat::Float6E3M2FN())
return S_Float6E3M2FN;
else if (&Sem == &llvm::APFloat::Float6E2M3FN())
@@ -319,7 +334,7 @@ exponentNaN(const fltSemantics &semantics) {
if (semantics.nonFiniteBehavior == fltNonfiniteBehavior::NanOnly) {
if (semantics.nanEncoding == fltNanEncoding::NegativeZero)
return exponentZero(semantics);
- if (semantics.hasSignedRepr)
+ if (semantics.hasSignedRepr || semantics.precision > 1)
return semantics.maxExponent;
}
return semantics.maxExponent + 1;
@@ -3575,6 +3590,11 @@ APInt IEEEFloat::convertFloat8E8M0FNUAPFloatToAPInt() const {
return convertIEEEFloatToAPInt<APFloatBase::semFloat8E8M0FNU>();
}
+APInt IEEEFloat::convertFloat8E5M3FNUAPFloatToAPInt() const {
+ assert(partCount() == 1);
+ return convertIEEEFloatToAPInt<APFloatBase::semFloat8E5M3FNU>();
+}
+
APInt IEEEFloat::convertFloat6E3M2FNAPFloatToAPInt() const {
assert(partCount() == 1);
return convertIEEEFloatToAPInt<APFloatBase::semFloat6E3M2FN>();
@@ -3642,6 +3662,9 @@ APInt IEEEFloat::bitcastToAPInt() const {
if (semantics == (const llvm::fltSemantics *)&APFloatBase::semFloat8E8M0FNU)
return convertFloat8E8M0FNUAPFloatToAPInt();
+ if (semantics == (const llvm::fltSemantics *)&APFloatBase::semFloat8E5M3FNU)
+ return convertFloat8E5M3FNUAPFloatToAPInt();
+
if (semantics == (const llvm::fltSemantics *)&APFloatBase::semFloat6E3M2FN)
return convertFloat6E3M2FNAPFloatToAPInt();
@@ -3716,6 +3739,10 @@ void IEEEFloat::initFromFloat8E8M0FNUAPInt(const APInt &api) {
initFromIEEEAPInt<APFloatBase::semFloat8E8M0FNU>(api);
}
+void IEEEFloat::initFromFloat8E5M3FNUAPInt(const APInt &api) {
+ initFromIEEEAPInt<APFloatBase::semFloat8E5M3FNU>(api);
+}
+
template <const fltSemantics &S>
void IEEEFloat::initFromIEEEAPInt(const APInt &api) {
assert(api.getBitWidth() == S.sizeInBits);
@@ -3953,6 +3980,8 @@ void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
return initFromFloatTF32APInt(api);
if (Sem == &APFloatBase::semFloat8E8M0FNU)
return initFromFloat8E8M0FNUAPInt(api);
+ if (Sem == &APFloatBase::semFloat8E5M3FNU)
+ return initFromFloat8E5M3FNUAPInt(api);
if (Sem == &APFloatBase::semFloat6E3M2FN)
return initFromFloat6E3M2FNAPInt(api);
if (Sem == &APFloatBase::semFloat6E2M3FN)
@@ -6030,6 +6059,7 @@ unsigned APFloatBase::getArbitraryFPFormatSizeInBits(StringRef Format) {
.Case("Float6E3M2FN", getSizeInBits(semFloat6E3M2FN))
.Case("Float6E2M3FN", getSizeInBits(semFloat6E2M3FN))
.Case("Float4E2M1FN", getSizeInBits(semFloat4E2M1FN))
+ .Case("Float8E5M3FNU", getSizeInBits(semFloat8E5M3FNU))
.Default(0);
}
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 456a7a5ffefb9..8b80b46e3c3a8 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -1046,37 +1046,40 @@ TEST(APFloatTest, IsSmallestNormalized) {
if (I == APFloat::S_Float8E8M0FNU)
continue;
- EXPECT_FALSE(APFloat::getZero(Semantics, false).isSmallestNormalized());
- EXPECT_FALSE(APFloat::getZero(Semantics, true).isSmallestNormalized());
+ EXPECT_FALSE(APFloat::getZero(Semantics).isSmallestNormalized());
+ if (Semantics.hasSignedRepr)
+ EXPECT_FALSE(APFloat::getZero(Semantics, /* Negative */ true)
+ .isSmallestNormalized());
if (APFloat::semanticsHasNaN(Semantics)) {
// Types that do not support Inf will return NaN when asked for Inf.
// (But only if they support NaN.)
- EXPECT_FALSE(APFloat::getInf(Semantics, false).isSmallestNormalized());
- EXPECT_FALSE(APFloat::getInf(Semantics, true).isSmallestNormalized());
+ EXPECT_FALSE(APFloat::getInf(Semantics).isSmallestNormalized());
+ if (Semantics.hasSignedRepr)
+ EXPECT_FALSE(APFloat::getInf(Semantics, /* Negative */ true)
+ .isSmallestNormalized());
EXPECT_FALSE(APFloat::getQNaN(Semantics).isSmallestNormalized());
EXPECT_FALSE(APFloat::getSNaN(Semantics).isSmallestNormalized());
}
EXPECT_FALSE(APFloat::getLargest(Semantics).isSmallestNormalized());
- EXPECT_FALSE(APFloat::getLargest(Semantics, true).isSmallestNormalized());
+ if (Semantics.hasSignedRepr)
+ EXPECT_FALSE(APFloat::getLargest(Semantics, /* Negative */ true)
+ .isSmallestNormalized());
EXPECT_FALSE(APFloat::getSmallest(Semantics).isSmallestNormalized());
- EXPECT_FALSE(APFloat::getSmallest(Semantics, true).isSmallestNormalized());
+ if (Semantics.hasSignedRepr)
+ EXPECT_FALSE(APFloat::getSmallest(Semantics, /* Negative */ true)
+ .isSmallestNormalized());
EXPECT_FALSE(APFloat::getAllOnesValue(Semantics).isSmallestNormalized());
- APFloat PosSmallestNormalized =
- APFloat::getSmallestNormalized(Semantics, false);
- APFloat NegSmallestNormalized =
- APFloat::getSmallestNormalized(Semantics, true);
+ APFloat PosSmallestNormalized = APFloat::getSmallestNormalized(Semantics);
EXPECT_TRUE(PosSmallestNormalized.isSmallestNormalized());
- EXPECT_TRUE(NegSmallestNormalized.isSmallestNormalized());
EXPECT_EQ(fcPosNormal, PosSmallestNormalized.classify());
- EXPECT_EQ(fcNegNormal, NegSmallestNormalized.classify());
- for (APFloat *Val : {&PosSmallestNormalized, &NegSmallestNormalized}) {
+ auto SmallestNormalized = [&](APFloat *Val) {
bool OldSign = Val->isNegative();
// Step down, make sure it's still not smallest normalized.
@@ -1094,6 +1097,15 @@ TEST(APFloatTest, IsSmallestNormalized) {
EXPECT_EQ(APFloat::opOK, Val->next(true));
EXPECT_FALSE(Val->isSmallestNormalized());
EXPECT_EQ(OldSign, Val->isNegative());
+ };
+
+ SmallestNormalized(&PosSmallestNormalized);
+ if (Semantics.hasSignedRepr) {
+ APFloat NegSmallestNormalized =
+ APFloat::getSmallestNormalized(Semantics, /* Negative */ true);
+ EXPECT_TRUE(NegSmallestNormalized.isSmallestNormalized());
+ EXPECT_EQ(fcNegNormal, NegSmallestNormalized.classify());
+ SmallestNormalized(&NegSmallestNormalized);
}
}
}
@@ -2308,6 +2320,8 @@ TEST(APFloatTest, getLargest) {
APFloat::getLargest(APFloat::FloatTF32()).convertToFloat());
EXPECT_EQ(1.701411834e+38f,
APFloat::getLargest(APFloat::Float8E8M0FNU()).convertToDouble());
+ EXPECT_EQ(0x1.cp016,
+ APFloat::getLargest(APFloat::Float8E5M3FNU()).convertToDouble());
EXPECT_EQ(28, APFloat::getLargest(APFloat::Float6E3M2FN()).convertToDouble());
EXPECT_EQ(7.5,
APFloat::getLargest(APFloat::Float6E2M3FN()).convertToDouble());
@@ -2398,6 +2412,13 @@ TEST(APFloatTest, getSmallest) {
EXPECT_TRUE(test.isFiniteNonZero());
EXPECT_FALSE(test.isDenormal());
EXPECT_TRUE(test.bitwiseIsEqual(expected));
+
+ test = APFloat::getSmallest(APFloat::Float8E5M3FNU(), false);
+ expected = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-17");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_TRUE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
}
TEST(APFloatTest, getSmallestNormalized) {
@@ -2512,6 +2533,14 @@ TEST(APFloatTest, getSmallestNormalized) {
EXPECT_FALSE(test.isDenormal());
EXPECT_TRUE(test.bitwiseIsEqual(expected));
EXPECT_TRUE(test.isSmallestNormalized());
+
+ test = APFloat::getSmallestNormalized(APFloat::Float8E5M3FNU(), false);
+ expected = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-14");
+ EXPECT_FALSE(test.isNegative());
+ EXPECT_TRUE(test.isFiniteNonZero());
+ EXPECT_FALSE(test.isDenormal());
+ EXPECT_TRUE(test.bitwiseIsEqual(expected));
+ EXPECT_TRUE(test.isSmallestNormalized());
}
TEST(APFloatTest, getZero) {
@@ -2538,6 +2567,7 @@ TEST(APFloatTest, getZero) {
{&APFloat::Float8E5M2(), true, true, {0x80ULL, 0}, 1},
{&APFloat::Float8E5M2FNUZ(), false, false, {0, 0}, 1},
{&APFloat::Float8E5M2FNUZ(), true, false, {0, 0}, 1},
+ {&APFloat::Float8E5M3FNU(), false, false, {0, 0}, 1},
{&APFloat::Float8E4M3(), false, true, {0, 0}, 1},
{&APFloat::Float8E4M3(), true, true, {0x80ULL, 0}, 1},
{&APFloat::Float8E4M3FN(), false, true, {0, 0}, 1},
@@ -9535,9 +9565,11 @@ TEST(APFloatTest, getExactLog2) {
EXPECT_EQ(0, One.getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2());
EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2Abs());
+ if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2());
+ EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2Abs());
+ }
if (I == APFloat::S_Float6E2M3FN || I == APFloat::S_Float4E2M1FN) {
EXPECT_EQ(2, APFloat(Semantics, "4.0").getExactLog2());
@@ -9546,32 +9578,52 @@ TEST(APFloatTest, getExactLog2) {
EXPECT_EQ(2, APFloat(Semantics, "-4.0").getExactLog2Abs());
} else {
EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat(Semantics, "-8.0").getExactLog2());
EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2());
EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25").getExactLog2());
- EXPECT_EQ(-2, APFloat(Semantics, "-0.25").getExactLog2Abs());
- EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());
- EXPECT_EQ(3, APFloat(Semantics, "-8.0").getExactLog2Abs());
+ if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(INT_MIN, APFloat(Semantics, "-8.0").getExactLog2());
+ EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25").getExactLog2());
+ EXPECT_EQ(-2, APFloat(Semantics, "-0.25").getExactLog2Abs());
+ EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());
+ EXPECT_EQ(3, APFloat(Semantics, "-8.0").getExactLog2Abs());
+ }
}
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs());
+ EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics).getExactLog2());
+ EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics).getExactLog2Abs());
+ if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getZero(Semantics, /* Negative */ true).getExactLog2());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getZero(Semantics, /* Negative */ true).getExactLog2Abs());
+ }
if (APFloat::semanticsHasNaN(Semantics)) {
// Types that do not support Inf will return NaN when asked for Inf.
// (But only if they support NaN.)
EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2());
+ EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics).getExactLog2());
+ if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getInf(Semantics, /* Negative */ true).getExactLog2());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getNaN(Semantics, /* Negative */ true).getExactLog2());
+ }
EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2Abs());
+ EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics).getExactLog2Abs());
+ if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getInf(Semantics, /* Negative */ true).getExactLog2Abs());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getNaN(Semantics, /* Negative */ true).getExactLog2Abs());
+ }
}
EXPECT_EQ(
@@ -9860,6 +9912,342 @@ TEST(APFloatTest, ConvertDoubleToE8M0FNU) {
EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);
}
+TEST(APFloatTest, Float8E5M3FNUValues) {
+ // High end of the range
+ auto test = APFloat(APFloat::Float8E5M3FNU(), "0x1.c0p16");
+ EXPECT_EQ(0x1.c0p16, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.c0p15");
+ EXPECT_EQ(0x1.cp15, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p14");
+ EXPECT_EQ(0x1.0p14, test.convertToDouble());
+
+ // tests the fix in makeLargest()
+ test = APFloat::getLargest(APFloat::Float8E5M3FNU());
+ EXPECT_EQ(0x1.cp16, test.convertToDouble());
+
+ // tests overflow to nan
+ APFloat nan = APFloat(APFloat::Float8E5M3FNU(), "nan");
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.e0p+16");
+ EXPECT_TRUE(test.bitwiseIsEqual(nan));
+
+ // Mid of the range
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p0");
+ EXPECT_EQ(1.0, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p1");
+ EXPECT_EQ(2.0, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p2");
+ EXPECT_EQ(4.0, test.convertToDouble());
+
+ // Low end of the range
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-12");
+ EXPECT_EQ(0x1.0p-12, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-13");
+ EXPECT_EQ(0x1.0p-13, test.convertToDouble());
+
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-14");
+ EXPECT_EQ(0x1.0p-14, test.convertToDouble());
+ EXPECT_TRUE(test.isSmallestNormalized());
+
+ // Smallest value
+ test = APFloat::getSmallest(APFloat::Float8E5M3FNU());
+ EXPECT_EQ(0x1.0p-17, test.convertToDouble());
+
+ // Value below the smallest, but clamped to the smallest
+ test = APFloat(APFloat::Float8E5M3FNU(), "0x1.0p-18");
+ EXPECT_EQ(0, test.convertToDouble());
+}
+
+TEST(APFloatTest, Float8E5M3FNUFromString) {
+ // Exactly representable
+ EXPECT_EQ(64, APFloat(APFloat::Float8E5M3FNU(), "64").convertToDouble());
+ // Overflow to NaN
+ EXPECT_TRUE(APFloat(APFloat::Float8E5M3FNU(), "0x1.0p17").isNaN());
+ // Inf converted to NaN
+ EXPECT_TRUE(APFloat(APFloat::Float8E5M3FNU(), "inf").isNaN());
+ // NaN converted to NaN
+ EXPECT_TRUE(APFloat(APFloat::Float8E5M3FNU(), "nan").isNaN());
+}
+
+TEST(APFloatTest, Float8E5M3FNUDivideByZero) {
+ APFloat x(APFloat::Float8E5M3FNU(), "1");
+ APFloat zero(APFloat::Float8E5M3FNU(), "0");
+ EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero);
+ EXPECT_TRUE(x.isNaN());
+}
+
+TEST(APFloatTest, Float8E5M3FNUGetSignedValues) {
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+ EXPECT_DEATH(APFloat(APFloat::Float8E5M3FNU(), "-64"),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat(APFloat::Float8E5M3FNU(), "-0x1.0p17"),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat(APFloat::Float8E5M3FNU(), "-inf"),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat::getNaN(APFloat::Float8E5M3FNU(), true),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat::getInf(APFloat::Float8E5M3FNU(), true),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat::getSmallest(APFloat::Float8E5M3FNU(), true),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat::getSmallestNormalized(APFloat::Float8E5M3FNU(), true),
+ "This floating point format does not support signed values");
+ EXPECT_DEATH(APFloat::getLargest(APFloat::Float8E5M3FNU(), true),
+ "This floating point format does not support signed values");
+ APFloat x = APFloat(APFloat::Float8E5M3FNU(), "4");
+ APFloat y = APFloat(APFloat::Float8E5M3FNU(), "8");
+ EXPECT_DEATH(x.subtract(y, APFloat::rmNearestTiesToEven),
+ "This floating point format does not support signed values");
+#endif // NDEBUG
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+TEST(APFloatTest, Float8E5M3FNUGetInf) {
+ // The Float8E5M3FNU format does not support infinity and the all ones
+ // representation is treated as NaN.
+ APFloat t = APFloat::getInf(APFloat::Float8E5M3FNU());
+ EXPECT_TRUE(t.isNaN());
+ EXPECT_FALSE(t.isInfinity());
+}
+
+TEST(APFloatTest, Float8E5M3FNUSmallest) {
+ APFloat test(APFloat::getSmallest(APFloat::Float8E5M3FNU()));
+ EXPECT_EQ(0x1.0p-17, test.convertToDouble());
+
+ EXPECT_TRUE(test.isSmallest());
+ EXPECT_EQ(fcPosSubnormal, test.classify());
+
+ test = APFloat::getAllOnesValue(APFloat::Float8E5M3FNU());
+ EXPECT_TRUE(test.isNaN());
+}
+
+TEST(APFloatTest, Float8E5M3FNUExhaustivePair) {
+ // Test each pair of 8-bit values for Float8E5M3FNU format.
+ // This format is unsigned, so subtraction is only tested when the result
+ // is non-negative (which corresponds to i >= j since the bit-pattern
+ // ordering matches the value ordering). IEEE remainder can produce
+ // negative results, so it is only tested when the reference result is
+ // non-negative.
+ APFloat::Semantics Sem = APFloat::S_Float8E5M3FNU;
+ const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);
+ for (int i = 0; i < 256; i++) {
+ for (int j = 0; j < 256; j++) {
+ SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +
+ ",j=" + std::to_string(j));
+ APFloat x(S, APInt(8, i));
+ APFloat y(S, APInt(8, j));
+
+ bool losesInfo;
+ APFloat xd = x;
+ xd.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+ &losesInfo);
+ EXPECT_FALSE(losesInfo);
+ APFloat yd = y;
+ yd.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+ &losesInfo);
+ EXPECT_FALSE(losesInfo);
+
+ // Add
+ APFloat z = x;
+ z.add(y, APFloat::rmNearestTiesToEven);
+ APFloat zd = xd;
+ zd.add(yd, APFloat::rmNearestTiesToEven);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+
+ // Subtract
+ if (i >= j) {
+ z = x;
+ z.subtract(y, APFloat::rmNearestTiesToEven);
+ zd = xd;
+ zd.subtract(yd, APFloat::rmNearestTiesToEven);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+ }
+
+ // Multiply
+ z = x;
+ z.multiply(y, APFloat::rmNearestTiesToEven);
+ zd = xd;
+ zd.multiply(yd, APFloat::rmNearestTiesToEven);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+
+ // Divide
+ z = x;
+ z.divide(y, APFloat::rmNearestTiesToEven);
+ zd = xd;
+ zd.divide(yd, APFloat::rmNearestTiesToEven);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+
+ // Mod
+ z = x;
+ z.mod(y);
+ zd = xd;
+ zd.mod(yd);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+
+ // Remainder: IEEE remainder can produce negative results, which this
+ // unsigned format cannot represent. Only test when the reference
+ // result is non-negative.
+ zd = xd;
+ zd.remainder(yd);
+ if (!zd.isNegative()) {
+ z = x;
+ z.remainder(y);
+ zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(z.bitwiseIsEqual(zd))
+ << "sem=" << Sem << ", i=" << i << ", j=" << j;
+ }
+ }
+ }
+}
+
+TEST(APFloatTest, Float8E5M3FNUExhaustive) {
+ // Test each of the 256 Float8E5M3FNU values.
+ // Layout: 5 exponent bits + 3 mantissa bits, bias = 15, NaN = 0xFF
+ // (all-ones).
+ for (int i = 0; i < 256; i++) {
+ APFloat test(APFloat::Float8E5M3FNU(), APInt(8, i));
+ SCOPED_TRACE("i=" + std::to_string(i));
+
+ // bitcastToAPInt
+ EXPECT_EQ(i, test.bitcastToAPInt());
+
+ // isLargest
+ if (i == 254) {
+ EXPECT_TRUE(test.isLargest());
+ EXPECT_EQ(test.convertToDouble(), 0x1.cp16);
+ } else {
+ EXPECT_FALSE(test.isLargest());
+ }
+
+ // isSmallest (smallest positive subnormal: bit pattern 0x01 = 2^-17)
+ if (i == 1) {
+ EXPECT_TRUE(test.isSmallest());
+ EXPECT_EQ(test.convertToDouble(), 0x1.0p-17);
+ } else {
+ EXPECT_FALSE(test.isSmallest());
+ }
+
+ // NaN is the all-ones bit pattern.
+ if (i == 255) {
+ EXPECT_TRUE(test.isNaN());
+ continue;
+ }
+
+ // convert to Double
+ bool losesInfo;
+ APFloat::opStatus status = test.convert(
+ APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_EQ(status, APFloat::opOK);
+ EXPECT_FALSE(losesInfo);
+
+ // Expected value:
+ // i == 0 -> +0
+ // 1..7 -> subnormal: i * 2^-17
+ // 8..254 -> normal: (1 + (i & 7)/8) * 2^((i >> 3) - 15)
+ double expected;
+ if (i == 0)
+ expected = 0.0;
+ else if (i < 8)
+ expected = std::ldexp(static_cast<double>(i), -17);
+ else
+ expected = std::ldexp(1.0 + (i & 7) / 8.0, (i >> 3) - 15);
+ EXPECT_EQ(test.convertToDouble(), expected);
+ }
+}
+
+TEST(APFloatTest, Float8E5M3FNUGetExactLog2) {
+ const fltSemantics &Semantics = APFloat::Float8E5M3FNU();
+ APFloat One(Semantics, "1.0");
+ EXPECT_EQ(0, One.getExactLog2());
+
+ // 3.0 is exactly representable (1.5 * 2^1) but not a power of two.
+ EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2());
+
+ // Exact power-of-two value.
+ EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2());
+ EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());
+
+ // Negative exponent value.
+ EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2());
+ EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs());
+
+ int MinExp = APFloat::semanticsMinExponent(Semantics);
+ int MaxExp = APFloat::semanticsMaxExponent(Semantics);
+ int Precision = APFloat::semanticsPrecision(Semantics);
+
+ // Values above the maxExp overflow to NaN, and getExactLog2() returns
+ // INT_MIN for these cases.
+ EXPECT_EQ(
+ INT_MIN,
+ scalbn(One, MaxExp + 1, APFloat::rmNearestTiesToEven).getExactLog2());
+
+ // This format can represent all powers of two in [MinExp - Precision + 1,
+ // MaxExp], including subnormal powers (2^-17, 2^-16, 2^-15).
+ for (int i = MinExp - Precision + 1; i <= MaxExp; ++i) {
+ EXPECT_EQ(i, scalbn(One, i, APFloat::rmNearestTiesToEven).getExactLog2());
+ }
+}
+
+TEST(APFloatTest, Float8E5M3FNUNext) {
+ APFloat test(APFloat::getSmallest(APFloat::Float8E5M3FNU()));
+ // Smallest positive value is the smallest subnormal: 2^-17.
+ EXPECT_EQ(0x1.0p-17, test.convertToDouble());
+
+ // Increment of 1 should reach the next subnormal: 2^-16.
+ EXPECT_EQ(APFloat::opOK, test.next(false));
+ EXPECT_FALSE(test.isSmallest());
+ EXPECT_EQ(0x1.0p-16, test.convertToDouble());
+
+ // Decrement of 1 should return to the smallest subnormal.
+ EXPECT_EQ(APFloat::opOK, test.next(true));
+ EXPECT_TRUE(test.isSmallest());
+
+ // Decrement again should reach +0.
+ EXPECT_EQ(APFloat::opOK, test.next(true));
+ EXPECT_TRUE(test.isPosZero());
+}
+
+TEST(APFloatTest, Float8E5M3FNUFMA) {
+ APFloat f1(APFloat::Float8E5M3FNU(), "4.0");
+ APFloat f2(APFloat::Float8E5M3FNU(), "2.0");
+ APFloat f3(APFloat::Float8E5M3FNU(), "8.0");
+
+ // Exact value: 4*2 + 8 = 16.
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(16.0, f1.convertToDouble());
+
+ // 4*2 + 4 = 12 (exactly representable with 3 mantissa bits).
+ f1 = APFloat(APFloat::Float8E5M3FNU(), "4.0");
+ f1.fusedMultiplyAdd(f2, f1, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(12.0, f1.convertToDouble());
+
+ // 4*8 + 2 = 34. At exponent 5 the step is 4, so 34 ties between 32 and
+ // 36 and rounds to 32 under round-to-nearest-even.
+ f1 = APFloat(APFloat::Float8E5M3FNU(), "4.0");
+ f1.fusedMultiplyAdd(f3, f2, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(32.0, f1.convertToDouble());
+
+ // All of them using the same value: 1*1 + 1 = 2.
+ f1 = APFloat(APFloat::Float8E5M3FNU(), "1.0");
+ f1.fusedMultiplyAdd(f1, f1, APFloat::rmNearestTiesToEven);
+ EXPECT_EQ(2.0, f1.convertToDouble());
+}
+
TEST(APFloatTest, Float6E3M2FNFromString) {
// Exactly representable
EXPECT_EQ(28, APFloat(APFloat::Float6E3M2FN(), "28").convertToDouble());
@@ -10369,6 +10757,7 @@ TEST(APFloatTest, hasSignBitInMSB) {
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::PPCDoubleDouble()));
EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::IEEEquad()));
EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));
+ EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E5M3FNU()));
}
TEST(APFloatTest, FrexpQuietSNaN) {
@@ -10391,6 +10780,7 @@ TEST(APFloatTest, isValidArbitraryFPFormat) {
EXPECT_TRUE(APFloat::isValidArbitraryFPFormat("Float6E3M2FN"));
EXPECT_TRUE(APFloat::isValidArbitraryFPFormat("Float6E2M3FN"));
EXPECT_TRUE(APFloat::isValidArbitraryFPFormat("Float4E2M1FN"));
+ EXPECT_TRUE(APFloat::isValidArbitraryFPFormat("Float8E5M3FNU"));
// Test invalid format strings.
EXPECT_FALSE(APFloat::isValidArbitraryFPFormat(""));
>From fa628dcb7a00e3c841096326146cb215c00c38ce Mon Sep 17 00:00:00 2001
From: Pradeep Kumar <pradeepku at nvidia.com>
Date: Mon, 20 Jul 2026 16:33:45 +0000
Subject: [PATCH 2/4] Fix clang build failure due to missing default case
---
clang/lib/AST/MicrosoftMangle.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 59732ff0fed11..5efbe3c3d8262 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1019,9 +1019,11 @@ void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
case APFloat::S_Float8E3M4:
case APFloat::S_FloatTF32:
case APFloat::S_Float8E8M0FNU:
+ case APFloat::S_Float8E5M3FNU:
case APFloat::S_Float6E3M2FN:
case APFloat::S_Float6E2M3FN:
case APFloat::S_Float4E2M1FN:
+ default:
llvm_unreachable("Tried to mangle unexpected APFloat semantics");
}
>From c4df068f79ea2865bb32a7070cd36255d58a614b Mon Sep 17 00:00:00 2001
From: Pradeep Kumar <pradeepku at nvidia.com>
Date: Mon, 20 Jul 2026 16:34:38 +0000
Subject: [PATCH 3/4] Fix formatting issues in APFloatTest file
---
llvm/unittests/ADT/APFloatTest.cpp | 71 +++++++++++++++++-------------
1 file changed, 41 insertions(+), 30 deletions(-)
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 8b80b46e3c3a8..342663297af6d 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -1046,36 +1046,41 @@ TEST(APFloatTest, IsSmallestNormalized) {
if (I == APFloat::S_Float8E8M0FNU)
continue;
- EXPECT_FALSE(APFloat::getZero(Semantics).isSmallestNormalized());
+ EXPECT_FALSE(
+ APFloat::getZero(Semantics, /*Negative=*/false).isSmallestNormalized());
if (Semantics.hasSignedRepr)
- EXPECT_FALSE(APFloat::getZero(Semantics, /* Negative */ true)
+ EXPECT_FALSE(APFloat::getZero(Semantics, /*Negative=*/true)
.isSmallestNormalized());
if (APFloat::semanticsHasNaN(Semantics)) {
// Types that do not support Inf will return NaN when asked for Inf.
// (But only if they support NaN.)
- EXPECT_FALSE(APFloat::getInf(Semantics).isSmallestNormalized());
+ EXPECT_FALSE(APFloat::getInf(Semantics, /*Negative=*/false)
+ .isSmallestNormalized());
if (Semantics.hasSignedRepr)
- EXPECT_FALSE(APFloat::getInf(Semantics, /* Negative */ true)
+ EXPECT_FALSE(APFloat::getInf(Semantics, /*Negative=*/true)
.isSmallestNormalized());
EXPECT_FALSE(APFloat::getQNaN(Semantics).isSmallestNormalized());
EXPECT_FALSE(APFloat::getSNaN(Semantics).isSmallestNormalized());
}
- EXPECT_FALSE(APFloat::getLargest(Semantics).isSmallestNormalized());
+ EXPECT_FALSE(APFloat::getLargest(Semantics, /*Negative=*/false)
+ .isSmallestNormalized());
if (Semantics.hasSignedRepr)
- EXPECT_FALSE(APFloat::getLargest(Semantics, /* Negative */ true)
+ EXPECT_FALSE(APFloat::getLargest(Semantics, /*Negative=*/true)
.isSmallestNormalized());
- EXPECT_FALSE(APFloat::getSmallest(Semantics).isSmallestNormalized());
+ EXPECT_FALSE(APFloat::getSmallest(Semantics, /*Negative=*/false)
+ .isSmallestNormalized());
if (Semantics.hasSignedRepr)
- EXPECT_FALSE(APFloat::getSmallest(Semantics, /* Negative */ true)
+ EXPECT_FALSE(APFloat::getSmallest(Semantics, /*Negative=*/true)
.isSmallestNormalized());
EXPECT_FALSE(APFloat::getAllOnesValue(Semantics).isSmallestNormalized());
- APFloat PosSmallestNormalized = APFloat::getSmallestNormalized(Semantics);
+ APFloat PosSmallestNormalized =
+ APFloat::getSmallestNormalized(Semantics, /*Negative=*/false);
EXPECT_TRUE(PosSmallestNormalized.isSmallestNormalized());
EXPECT_EQ(fcPosNormal, PosSmallestNormalized.classify());
@@ -1102,7 +1107,7 @@ TEST(APFloatTest, IsSmallestNormalized) {
SmallestNormalized(&PosSmallestNormalized);
if (Semantics.hasSignedRepr) {
APFloat NegSmallestNormalized =
- APFloat::getSmallestNormalized(Semantics, /* Negative */ true);
+ APFloat::getSmallestNormalized(Semantics, /*Negative=*/true);
EXPECT_TRUE(NegSmallestNormalized.isSmallestNormalized());
EXPECT_EQ(fcNegNormal, NegSmallestNormalized.classify());
SmallestNormalized(&NegSmallestNormalized);
@@ -9589,40 +9594,46 @@ TEST(APFloatTest, getExactLog2) {
}
}
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics).getExactLog2Abs());
+ EXPECT_EQ(INT_MIN,
+ APFloat::getZero(Semantics, /*Negative=*/false).getExactLog2());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getZero(Semantics, /*Negative=*/false).getExactLog2Abs());
if (Semantics.hasSignedRepr) {
+ EXPECT_EQ(INT_MIN,
+ APFloat::getZero(Semantics, /*Negative=*/true).getExactLog2());
EXPECT_EQ(
INT_MIN,
- APFloat::getZero(Semantics, /* Negative */ true).getExactLog2());
- EXPECT_EQ(
- INT_MIN,
- APFloat::getZero(Semantics, /* Negative */ true).getExactLog2Abs());
+ APFloat::getZero(Semantics, /*Negative=*/true).getExactLog2Abs());
}
if (APFloat::semanticsHasNaN(Semantics)) {
// Types that do not support Inf will return NaN when asked for Inf.
// (But only if they support NaN.)
- EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics).getExactLog2());
+ EXPECT_EQ(INT_MIN,
+ APFloat::getInf(Semantics, /*Negative=*/false).getExactLog2());
+ EXPECT_EQ(INT_MIN,
+ APFloat::getNaN(Semantics, /*Negative=*/false).getExactLog2());
if (Semantics.hasSignedRepr) {
- EXPECT_EQ(
- INT_MIN,
- APFloat::getInf(Semantics, /* Negative */ true).getExactLog2());
- EXPECT_EQ(
- INT_MIN,
- APFloat::getNaN(Semantics, /* Negative */ true).getExactLog2());
+ EXPECT_EQ(INT_MIN,
+ APFloat::getInf(Semantics, /*Negative=*/true).getExactLog2());
+ EXPECT_EQ(INT_MIN,
+ APFloat::getNaN(Semantics, /*Negative=*/true).getExactLog2());
}
- EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2Abs());
- EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics).getExactLog2Abs());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getInf(Semantics, /*Negative=*/false).getExactLog2Abs());
+ EXPECT_EQ(
+ INT_MIN,
+ APFloat::getNaN(Semantics, /*Negative=*/false).getExactLog2Abs());
if (Semantics.hasSignedRepr) {
EXPECT_EQ(
INT_MIN,
- APFloat::getInf(Semantics, /* Negative */ true).getExactLog2Abs());
+ APFloat::getInf(Semantics, /*Negative=*/true).getExactLog2Abs());
EXPECT_EQ(
INT_MIN,
- APFloat::getNaN(Semantics, /* Negative */ true).getExactLog2Abs());
+ APFloat::getNaN(Semantics, /*Negative=*/true).getExactLog2Abs());
}
}
@@ -10035,8 +10046,8 @@ TEST(APFloatTest, Float8E5M3FNUExhaustivePair) {
// non-negative.
APFloat::Semantics Sem = APFloat::S_Float8E5M3FNU;
const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);
- for (int i = 0; i < 256; i++) {
- for (int j = 0; j < 256; j++) {
+ for (int i = 0; i < 256; ++i) {
+ for (int j = 0; j < 256; ++j) {
SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +
",j=" + std::to_string(j));
APFloat x(S, APInt(8, i));
>From 67a125dbf4c6e5bf9e3772714eb5360717674cb7 Mon Sep 17 00:00:00 2001
From: Pradeep Kumar <pradeepku at nvidia.com>
Date: Mon, 20 Jul 2026 18:57:02 +0000
Subject: [PATCH 4/4] Remove default case from switch inside mangleFloat
---
clang/lib/AST/MicrosoftMangle.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 5efbe3c3d8262..a1f2b671d6216 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1023,7 +1023,6 @@ void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {
case APFloat::S_Float6E3M2FN:
case APFloat::S_Float6E2M3FN:
case APFloat::S_Float4E2M1FN:
- default:
llvm_unreachable("Tried to mangle unexpected APFloat semantics");
}
More information about the cfe-commits
mailing list