Index: lib/Support/APFloat.cpp =================================================================== --- lib/Support/APFloat.cpp +++ lib/Support/APFloat.cpp @@ -3984,6 +3984,8 @@ // 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; } Index: unittests/ADT/APFloatTest.cpp =================================================================== --- unittests/ADT/APFloatTest.cpp +++ unittests/ADT/APFloatTest.cpp @@ -2890,7 +2890,7 @@ 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()); EXPECT_TRUE(PInf.bitwiseIsEqual( scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 128, RM))); @@ -3020,6 +3020,22 @@ APFloat ScalbnSNaN = scalbn(SNaN, 0, RM); EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling()); + + 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)); } TEST(APFloatTest, frexp) {