diff options
author | Lang Hames <lhames@gmail.com> | 2014-11-19 19:15:41 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-11-19 19:15:41 +0000 |
commit | 56c0eb2d90de68978c280ab7b08377af6de03fd0 (patch) | |
tree | 53e4618c12694ca6e20dc087bd1250b034fd4010 /llvm/unittests/ADT/APFloatTest.cpp | |
parent | dce60a747cb7ecad9a6b34e6f6be71cf73c055ec (diff) | |
download | bcm5719-llvm-56c0eb2d90de68978c280ab7b08377af6de03fd0.tar.gz bcm5719-llvm-56c0eb2d90de68978c280ab7b08377af6de03fd0.zip |
[ADT] Fix PR20728 - Incorrect APFloat::fusedMultiplyAdd results for x86_fp80.
As detailed at http://llvm.org/PR20728, due to an internal overflow in
APFloat::multiplySignificand the APFloat::fusedMultiplyAdd method can return
incorrect results for x87DoubleExtended (x86_fp80) values. This commonly
manifests as incorrect constant folding of libm fmal calls on x86. E.g.
fmal(1.0L, 1.0L, 3.0L) == 0.0L (should be 4.0L)
This patch fixes PR20728 by adding an extra bit to the significand for
intermediate results of APFloat::multiplySignificand, avoiding the overflow.
llvm-svn: 222374
Diffstat (limited to 'llvm/unittests/ADT/APFloatTest.cpp')
-rw-r--r-- | llvm/unittests/ADT/APFloatTest.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index a86be5af375..c7ec16ba803 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -474,6 +474,18 @@ TEST(APFloatTest, FMA) { f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven); EXPECT_EQ(12.0f, f1.convertToFloat()); } + + { + APFloat M1(APFloat::x87DoubleExtended, 1.0); + APFloat M2(APFloat::x87DoubleExtended, 1.0); + APFloat A(APFloat::x87DoubleExtended, 3.0); + + bool losesInfo = false; + M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven); + M1.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo); + EXPECT_FALSE(losesInfo); + EXPECT_EQ(4.0f, M1.convertToFloat()); + } } TEST(APFloatTest, MinNum) { |