On 5/6/25 10:50, Richard Henderson wrote:
+    *(uint64_t *)&x = 0x4ff0000000000000UL;
+    *(uint64_t *)&y = 0x4ff0000000000000UL;

  0x1.0p256

+    *(uint64_t *)&z = 0x2ff0000000000000UL;

  0x1.0p-256

+
+    fesetround(FE_DOWNWARD);
+    asm("fnmsub.d %[x], %[x], %[y], %[z]\n\t"
+        :[x]"+f"(x)
+        :[y]"f"(y), [z]"f"(z));
+
+    assert(*(uint64_t *)&x == 0xdfefffffffffffffUL);

   -(0x1.0p512 - epsilon)

That really should have worked as-is.  I'll have a quick look.

The negate_result is applied early, so we're computing rounding on the -(1p512 - epsilon), and since that's negative, round_down produces -1p512. Whereas what the ISA wants is the rounding on (1p512 - epsilon), rounding down to 1.fffffffffffffp511, and only afterward negating.

I'm thinking that the current placement of the float_muladd_negate_result test is incorrect, since we're not negating the result, we're negating the unrounded intermediate.

There are only 3 targets which use float_muladd_negate_result: loongarch, ppc, and sparc. I will use this test case to test those other targets as well.


r~

Reply via email to