[Mlir-commits] [llvm] [mlir] [APFloat] Report the sign and the zero a conversion cannot represent (PR #216056)
Hung Kuan Tseng
llvmlistbot at llvm.org
Sun Aug 16 09:58:07 PDT 2026
================
@@ -2334,6 +2334,59 @@ TEST(APFloatTest, Float8E8M0FNUNaNConvert) {
}
}
+// Test that converting into a format that cannot represent the sign, or that
+// has no encoding for zero, reports the loss. Callers decide whether to keep
+// the result from losesInfo, and the value that comes out is not the value
+// that went in: the sign bit has nowhere to go, and zero is replaced by the
+// smallest normalized value.
+TEST(APFloatTest, ConvertLosesUnrepresentableSignAndZero) {
+ // Neither format has a sign; only Float8E8M0FNU also lacks a zero.
+ const fltSemantics *NoSignSemantics[] = {&APFloat::Float8E8M0FNU(),
+ &APFloat::Float8E5M3FNU()};
+
+ for (const fltSemantics *Sem : NoSignSemantics) {
+ for (double Value : {-2.0, -0.0}) {
+ APFloat test(Value);
+ bool losesInfo = false;
+ APFloat::opStatus status =
+ test.convert(*Sem, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_TRUE(losesInfo);
----------------
Tim096 wrote:
Done. Every conversion in the test now asserts the value it produced, and the
loop is split so that each case can state its own expectation.
For `-2.0` into either format the magnitude is exact, so the sign is the whole
of what is being reported: the result asserts `isNegative()` and
`convertToDouble() == -2.0`.
Zero moved out of the loop, because the two formats answer differently:
`Float8E8M0FNU` has no zero and substitutes 2^-127 for either sign
(`isSmallestNormalized()`, bit pattern `0x00`), while `Float8E5M3FNU` does have
one and keeps `-0.0` as `-0.0`, reporting only the sign.
I used `convertToDouble()` rather than `bitcastToAPInt()` for the signed cases:
these formats have no sign bit, so the encoding cannot show the sign that was
carried through, which is the thing under test.
https://github.com/llvm/llvm-project/pull/216056
More information about the Mlir-commits
mailing list