https://bugs.llvm.org/show_bug.cgi?id=43711
Connor Abbott <[email protected]> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
CC| |[email protected]
Resolution|INVALID |---
--- Comment #3 from Connor Abbott <[email protected]> ---
nir_op_fneg in Mesa canonicalizes the result because that's what Vulkan
requires. Specifically VK_KHR_floating_point_controls requires that the SPIR-V
OpFNeg flushes denorms to 0 when flushing denorms is enabled for the shader.
We currently map nir_op_fneg to "fsub -0, x" using LLVMBuildFNeg(). This should
produce a canonical result, the same as if I say "fsub y, x" and y happens to
be -0, and be identical to a normal fneg otherwise except maybe with funky
rounding modes. In the past this was what Clang also did, even though C/C++'s
negate operator maps to the standard IEEE sign bit operation that you quoted,
so it was wrong, and only recently has there been a native FNeg instruction
added which does just sign bit fiddling (and I don't even know if Clang uses it
yet). Backends then detected "fsub -0, x" and turned it back into an xor
instruction, which fixes the original clang bug but introduces a new one for
things like "float x = -0, y = ...; return x - y;" This is still happening with
AMDGPU, and now that we're trying to support DX games where DX expects that you
consistently flush denorms when adding/subtracting, that's not great.
I'm not sure moving forward what the canonical way is for an LLVM frontend to
emit a negate that also canonicalizes, "fsub -0, x" or "canonicalize(fneg(x))".
But the current LLVM behavior where "fsub -0, x" gets remapped to "fneg(x)" is
definitely wrong.
--
You are receiving this mail because:
You are on the CC list for the bug._______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs