diff options
| author | Stephen Canon <scanon@apple.com> | 2017-03-31 20:31:33 +0000 |
|---|---|---|
| committer | Stephen Canon <scanon@apple.com> | 2017-03-31 20:31:33 +0000 |
| commit | 157c86913a5d0a9ff9257455600689dc96333321 (patch) | |
| tree | a1d4575e6a5e1a32c309ad387e38668c11cf6c93 /llvm/unittests/ADT | |
| parent | 34da36e74f1f5ab5874f825074f04ecde2be50f4 (diff) | |
| download | bcm5719-llvm-157c86913a5d0a9ff9257455600689dc96333321.tar.gz bcm5719-llvm-157c86913a5d0a9ff9257455600689dc96333321.zip | |
Fix APFloat mod (committing for simonbyrne)
The previous version was prone to intermediate rounding or overflow.
Differential Revision: https://reviews.llvm.org/D29346
llvm-svn: 299256
Diffstat (limited to 'llvm/unittests/ADT')
| -rw-r--r-- | llvm/unittests/ADT/APFloatTest.cpp | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index 1cd98478fad..60a920bd3f7 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -3192,10 +3192,73 @@ TEST(APFloatTest, frexp) { EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac)); } +TEST(APFloatTest, mod) { + { + APFloat f1(APFloat::IEEEdouble(), "1.5"); + APFloat f2(APFloat::IEEEdouble(), "1.0"); + APFloat expected(APFloat::IEEEdouble(), "0.5"); + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "0.5"); + APFloat f2(APFloat::IEEEdouble(), "1.0"); + APFloat expected(APFloat::IEEEdouble(), "0.5"); + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2"); // 0.3 + APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7"); // 0.01 + APFloat expected(APFloat::IEEEdouble(), + "0x1.47ae147ae1471p-7"); // 0.009999999999999983 + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "0x1p64"); // 1.8446744073709552e19 + APFloat f2(APFloat::IEEEdouble(), "1.5"); + APFloat expected(APFloat::IEEEdouble(), "1.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "0x1p1000"); + APFloat f2(APFloat::IEEEdouble(), "0x1p-1000"); + APFloat expected(APFloat::IEEEdouble(), "0.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "0.0"); + APFloat f2(APFloat::IEEEdouble(), "1.0"); + APFloat expected(APFloat::IEEEdouble(), "0.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opOK); + EXPECT_TRUE(f1.bitwiseIsEqual(expected)); + } + { + APFloat f1(APFloat::IEEEdouble(), "1.0"); + APFloat f2(APFloat::IEEEdouble(), "0.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); + EXPECT_TRUE(f1.isNaN()); + } + { + APFloat f1(APFloat::IEEEdouble(), "0.0"); + APFloat f2(APFloat::IEEEdouble(), "0.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); + EXPECT_TRUE(f1.isNaN()); + } + { + APFloat f1 = APFloat::getInf(APFloat::IEEEdouble(), false); + APFloat f2(APFloat::IEEEdouble(), "1.0"); + EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); + EXPECT_TRUE(f1.isNaN()); + } +} + TEST(APFloatTest, PPCDoubleDoubleAddSpecial) { using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, - APFloat::fltCategory, APFloat::roundingMode>; - DataType Data[] = { + APFloat::fltCategory, APFloat::roundingMode>; DataType Data[] = { // (1 + 0) + (-1 + 0) = fcZero std::make_tuple(0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0, APFloat::fcZero, APFloat::rmNearestTiesToEven), |

