diff options
author | David Majnemer <david.majnemer@gmail.com> | 2023-03-29 21:44:11 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2023-04-04 19:12:10 +0000 |
commit | 3d11652bbee4cd6782c474e28cb2ab58fc93f245 (patch) | |
tree | c359c497d0a7fd788257816e4bb5adc77517ea19 /llvm/unittests/ADT/APFloatTest.cpp | |
parent | 0507448d829818e29f7d8df6652002c8cc5683d1 (diff) | |
download | llvm-3d11652bbee4cd6782c474e28cb2ab58fc93f245.zip llvm-3d11652bbee4cd6782c474e28cb2ab58fc93f245.tar.gz llvm-3d11652bbee4cd6782c474e28cb2ab58fc93f245.tar.bz2 |
[APFloat] Refactor common code for APFloat<->APInt conversion
All the IEEE formats are quite similar, we can merge their code
effectively by writing it parametrically via the fltSemantics object.
We can metaprogram the implementation such that this parametricity is
zero-cost.
Diffstat (limited to 'llvm/unittests/ADT/APFloatTest.cpp')
-rw-r--r-- | llvm/unittests/ADT/APFloatTest.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index cbf59ac..2d79d34 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -5915,7 +5915,8 @@ TEST(APFloatTest, ConvertE4M3FNUZToE5M2FNUZ) { TEST(APFloatTest, F8ToString) { for (APFloat::Semantics S : {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, - APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ}) { + APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, + APFloat::S_Float8E4M3B11FNUZ}) { SCOPED_TRACE("Semantics=" + std::to_string(S)); for (int i = 0; i < 256; i++) { SCOPED_TRACE("i=" + std::to_string(i)); @@ -5933,6 +5934,46 @@ TEST(APFloatTest, F8ToString) { } } +TEST(APFloatTest, BitsToF8ToBits) { + for (APFloat::Semantics S : + {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, + APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, + APFloat::S_Float8E4M3B11FNUZ}) { + SCOPED_TRACE("Semantics=" + std::to_string(S)); + for (int i = 0; i < 256; i++) { + SCOPED_TRACE("i=" + std::to_string(i)); + APInt bits_in = APInt(8, i); + APFloat test(APFloat::EnumToSemantics(S), bits_in); + APInt bits_out = test.bitcastToAPInt(); + EXPECT_EQ(bits_in, bits_out); + } + } +} + +TEST(APFloatTest, F8ToBitsToF8) { + for (APFloat::Semantics S : + {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, + APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, + APFloat::S_Float8E4M3B11FNUZ}) { + SCOPED_TRACE("Semantics=" + std::to_string(S)); + auto &Sem = APFloat::EnumToSemantics(S); + for (bool negative : {false, true}) { + SCOPED_TRACE("negative=" + std::to_string(negative)); + APFloat test = APFloat::getZero(Sem, /*Negative=*/negative); + for (int i = 0; i < 128; i++, test.next(/*nextDown=*/negative)) { + SCOPED_TRACE("i=" + std::to_string(i)); + APInt bits = test.bitcastToAPInt(); + APFloat test2 = APFloat(Sem, bits); + if (test.isNaN()) { + EXPECT_TRUE(test2.isNaN()); + } else { + EXPECT_TRUE(test.bitwiseIsEqual(test2)); + } + } + } + } +} + TEST(APFloatTest, IEEEdoubleToDouble) { APFloat DPosZero(0.0); APFloat DPosZeroToDouble(DPosZero.convertToDouble()); |