diff options
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 2 | ||||
-rw-r--r-- | llvm/unittests/ADT/APFloatTest.cpp | 17 |
2 files changed, 18 insertions, 1 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index ada392c519b..a8e14d6c08b 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -3984,6 +3984,8 @@ APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) { // Clamp to one past the range ends to let normalize handle overlflow. X.exponent += std::min(std::max(Exp, -MaxIncrement - 1), MaxIncrement); X.normalize(RoundingMode, lfExactlyZero); + if (X.isNaN()) + X.makeQuiet(); return X; } diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index 01dcffa1148..d884c8a2707 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -2890,7 +2890,22 @@ TEST(APFloatTest, scalbn) { EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM))); EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM))); EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM))); - EXPECT_TRUE(SNaN.bitwiseIsEqual(scalbn(SNaN, 0, RM))); + EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling()); + + APFloat ScalbnSNaN = scalbn(SNaN, 1, RM); + EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling()); + + // Make sure highest bit of payload is preserved. + const APInt Payload(64, (UINT64_C(1) << 50) | + (UINT64_C(1) << 49) | + (UINT64_C(1234) << 32) | + 1); + + APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble, false, + &Payload); + APFloat QuietPayload = scalbn(SNaNWithPayload, 1, RM); + EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling()); + EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51)); EXPECT_TRUE(PInf.bitwiseIsEqual( scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 128, RM))); |