-
Notifications
You must be signed in to change notification settings - Fork 769
known_identity has wrong values with -ffast-math #13813
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
cc @andykaylor any thoughts on this? Your patch linked is NFC so I don't really see how it would have changed the behavior, but maybe you have ideas on the best way to fix this, or why it only started failing recently. |
There was a discussion of this in the original PR: llvm/llvm-project#81173 (comment) Regardless of whether it was this PR or another in the upstream pull-down which changed the behaviour, it looks to me like the change was correct, i.e. the current behaviour matches the documentation: The |
I'm afraid https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#table.identities mandates that |
Does BTW, this is (rightly) triggering the test.cpp: #include <sycl/known_identity.hpp>
float foo() {return sycl::known_identity<sycl::minimum<float>,float>::value;} command:
|
I don't think we should do this. Imagine a "min" reduction where all the values are INF (and the application is not compiled with Therefore, I think we should do one of the following:
I presume the effect on SYCL reductions is the same for either of these options. Obviously, changing the definition of If we do not decide to change the definition of I think it is OK if the definition of SYCL's There is a similar case for "max" reductions, where the known identity is |
I don't think we can even detect it...
|
I assume we could change the compiler to predefine a macro when |
What if we use |
I agree that it's a bit weird for the |
We can try using pragmas to disable FP optimizations in SYCL library code using |
I suppose the SYCL RT could just ignore |
I've opened a PR to fix this: #17028 . It uses the |
…17028) Technically a workaround, this fixes the problem with `known_identity<minOp/maxOp>` being incorrect when using `-ffast-math`. It works because we have a `__FAST_MATH__` macro that is defined when that flag is used. Better, would be to detect `-fno-honor-infinities`. Opening a JIRA/discussion for that, but this is a big improvement in the interim. See discussion #13813
Describe the bug
The initial value for
sycl::minimum<float>
is set toinf
which gets turned into0
with-ffast-math
. More generally, both min and max are affected for any type whichhas_infinity
.The issue is here:
llvm/sycl/include/sycl/known_identity.hpp
Lines 262 to 271 in 7271d61
std::numeric_limits<T>::infinity()
should not be used here when-fno-honor-infinities
is enabled (e.g. by-ffast-math
). This causes the value to be evaluated as zero when used (at least in some cases) and subsequently leads to incorrect results of a program. Note thatstd::numeric_limits<float>::has_infinity
evaluates to true regardless of thehonor-infinities
option.This started failing in the nightly-2024-02-16 tag. The code in question hasn't changed in months, but it seems that the behaviour of
-ffast-math
has changed, possibly due to 73159a9So it seems the code has been problematic earlier, but it was hidden by the
-fno-honor-infinities
not being set in this context.I think there could be three solutions:
std::numeric_limits<T>::max()
in all cases. What's the benefit of using infinity here?-fno-honor-infinities
is used.std::numeric_limits<T>::has_infinity
evaluates to false when-fno-honor-infinities
is enabled.To reproduce
This is a minimal example of
sycl::joint_reduce
computing the minimum for a vector of 4 positive floats:When compiled with
-O3 -ffast-math
this prints 0.0 instead of the expected 1.0:$ clang++ -fsycl -o test test.cpp -O3 -ffast-math ./test Result: 0.000000
It can be worked around with
-fhonor-infinities
:$ clang++ -fsycl -o test test.cpp -O3 -ffast-math -fhonor-infinities ./test Result: 1.000000
Note this example doesn't directly use
sycl::known_identity
. It presents that the issue breaks a high-level feature. I didn't manage to create a small enough reproducer directly using the value, as it tends to get inlined / evaluated at compile time, and therefore not showing the issue. I have seen the value directly evaluating to zero in a larger project though.Environment
Additional context
No response
The text was updated successfully, but these errors were encountered: