APFloat: x87DoubleExtended pseudo-NaNs (integer_bit==0) not handled as always-signalling. · Issue #63938 · llvm/llvm-project (original) (raw)

Based on https://reviews.llvm.org/D41868 (cc @labath @stephentyrone) and these snippets of APFloat.cpp:

/// Integer bit is explicit in this format. Intel hardware (387 and later)
/// does not support these bit patterns:
/// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
/// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
/// exponent!=0 nor all 1's, integer bit 0 ("unnormal")
/// exponent = 0, integer bit 1 ("pseudodenormal")
/// At the moment, the first three are treated as NaNs, the last one as Normal.
// For x87 extended precision, we want to make a NaN, not a
// pseudo-NaN. Maybe we should expose the ability to make
// pseudo-NaNs?
if (semantics == &semX87DoubleExtended)
APInt::tcSetBit(significand, QNaNBit + 1);

I would expect the following:

Or in other words, I'd expect this test to pass (currently it fails to even generate an opInvalidOp status):

TEST(APFloatTest, x87PseudoNaN) { APFloat PseudoNaN(APFloat::x87DoubleExtended(), APInt(80, {1ULL << 62, 0x7fff})); EXPECT_TRUE(PseudoNaN.isNaN()); EXPECT_TRUE(PseudoNaN.isSignaling()); // FAIL: pseudo-NaNs aren't detected as SNaNs

// Any operation (which propagates input SNaNs while quieting them), // roundToIntegral just happened to have similar tests already. APFloat test = PseudoNaN; APFloat::opStatus St = test.roundToIntegral(APFloat::rmTowardZero); EXPECT_TRUE(test.isNaN()); EXPECT_FALSE(test.isSignaling()); // would FAIL if pseudo-NaNs were detected as SNaNs, // and makeQuiet wasn't also updated EXPECT_FALSE(test.isNegative()); EXPECT_EQ(APFloat::opInvalidOp, St); // FAIL: pseudo-NaNs aren't detected as SNaNs }