-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[clang][X86] Wrong result for __builtin_elementwise_fma on _Float16 #128450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@llvm/issue-subscribers-clang-codegen Author: SEt (SEt-t)
Godbolt: https://godbolt.org/z/Ydj17K17b
Clang uses single-precision FMA to emulate half-precision FMA, what is wrong as it doesn't have enough precision. Example, round to even: 0x1.400p+8 * 0x1.008p+7 + 0x1.000p-24 Another example: 0x1.eb8p-12 * 0x1.9p-11 - 0x1p-11 To produce correct result single-precision multiplication, then double-precision addition seems to be enough. |
I want to work on this issue. Any input or suggestions on where to start would be really helpful! |
This bug is a duplicate of #98389. @akshaykumars614 AFAICT this is where the half FMA operation is lowered incorrectly: llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Lines 3396 to 3414 in 5cc2ae0
|
Are you sure this will always be enough for all inputs? |
Yes. Building off this paper, 16-bit floats have an 11-bit significand (including the implicit bit), meaning that the result of the multiplication requires 22 bits to store losslessly ( |
Okay so single precision is enough for the multiplication (24 >= 22) and then double-precision is enough for the total operation (53 >= 34)? |
Yes EDIT: see #128450 (comment) |
You are wrong about addition bits (see my example of 40 bits), but conclusion that double is enough for it is correct. |
Ah yes, I see where I messed up. |
Corrected explanation for
|
Godbolt: https://godbolt.org/z/Ydj17K17b
Clang uses single-precision FMA to emulate half-precision FMA, what is wrong as it doesn't have enough precision.
Example, round to even: 0x1.400p+8 * 0x1.008p+7 + 0x1.000p-24
Precise result: 0x1.40a0000002p+15
Half-precision FMA: 0x1.40cp+15
Single-precision FMA: 0x1.40a000p+15
(clang) Single-precision FMA -> half-precision: 0x1.408p+15
Another example: 0x1.eb8p-12 * 0x1.9p-11 - 0x1p-11
To produce correct result single-precision multiplication, then double-precision addition seems to be enough.
The text was updated successfully, but these errors were encountered: