Chris Tetreault via llvm-dev
2021-Sep-13 16:45 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
Honestly, we can do this until the end of time. I think we both agree, that for either scheme, there exists workarounds. The question is which workarounds are more palatable, which is a matter of opinion. I think we’ve come to an impasse, so let me just state that my opinion on the question “Should isnan be optimized out in fast-math mode?” is “Yes”, which is what you asked to get in your original message. I think that the implementation of fast-math will be cleaner if we don’t special case a bunch of random constructs in order to do what the user meant instead of what they said. I think fast-math is a notorious footgun, and any attempts to mitigate this will only reduce the effectiveness of the tool, while not really improving the user experience. As a user, if I read that: ``` if (isnan(x)) { ``` … is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when: ``` if (isnan(x + 0)) { ``` … does not also work. I’m going to open a bug and complain, and the slide down the slippery slope will continue. You and I understand the difference, and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` isn’t, but Joe Coder just trying to figure out why he’s got NaN in his matrices despite his careful NaN handling code. Joe is not a compiler expert, and on the face of it, it seems like a silly limitation. This will never end until fast-math is gutted. Thanks, Chris Tetreault From: Serge Pavlov <sepavloff at gmail.com> Sent: Friday, September 10, 2021 9:21 PM To: Chris Tetreault <ctetreau at quicinc.com> Cc: Richard Smith <richard at metafoo.co.uk>; llvm-dev at lists.llvm.org; cfe-dev at lists.llvm.org Subject: Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode? WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: The problem is that math code is often templated, so `template <typename T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a header. No problem, the user can write: ``` #ifdef __FAST_MATH__ #undef isnan #define isnan(x) false #endif ``` and put it somewhere in the headers. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: Regardless, my position isn’t “there is no NaN”. My position is “you cannot count on operations on NaN working”. Exactly. Attempts to express the condition of -ffast-math as restrictions on types are not fruitful. I think it is the reason why GCC documentation does not use simple and clear "there is no NaN" but prefers more complicated wording about arithmetic. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: I think working around these sorts of issues is something that C and C++ developers are used to. These sorts of “inconsistent” between compilers behaviors is something we accept because we know it comes with improved performance. In this case, the fix is easy, so I don’t think this corner case is worth supporting. Especially when the fix is also just one line: ``` #define myIsNan(x) (reinterpret_cast<uint32_t>(x) == THE_BIT_PATTERN_OF_MY_SENTINEL_NAN) ``` It won't work in this way. If `x == 5.0`, then `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. Standard C does not have such. To emulate it a reinterpret_cast of memory can be used: `*reinterpret_cast<int *>(&x)`. Another way is to use a union. Both these solutions require operations with memory, which is not good for performance, especially on GPU and ML cores. Of course, a smart compiler can eliminate memory operation, but it does not have to do it always, as it is only optimization. Moving a value between float and integer pipelines also may incur a performance penalty. At the same time this check often may be done with a single instruction. Thanks, --Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210913/4e769d2f/attachment.html>
Aaron Ballman via llvm-dev
2021-Sep-13 17:05 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
On Mon, Sep 13, 2021 at 12:46 PM Chris Tetreault via cfe-dev <cfe-dev at lists.llvm.org> wrote:> > Honestly, we can do this until the end of time. I think we both agree, that for either scheme, there exists workarounds. The question is which workarounds are more palatable, which is a matter of opinion. I think we’ve come to an impasse, so let me just state that my opinion on the question “Should isnan be optimized out in fast-math mode?” is “Yes”, which is what you asked to get in your original message. I think that the implementation of fast-math will be cleaner if we don’t special case a bunch of random constructs in order to do what the user meant instead of what they said. I think fast-math is a notorious footgun, and any attempts to mitigate this will only reduce the effectiveness of the tool, while not really improving the user experience. > > > > As a user, if I read that: > > > > ``` > > if (isnan(x)) { > > ``` > > > > … is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when: > > > > ``` > > if (isnan(x + 0)) { > > ``` > > > > … does not also work. I’m going to open a bug and complain, and the slide down the slippery slope will continue. You and I understand the difference, and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` isn’t, but Joe Coder just trying to figure out why he’s got NaN in his matrices despite his careful NaN handling code. Joe is not a compiler expert, and on the face of it, it seems like a silly limitation. This will never end until fast-math is gutted. > > > > Thanks, > > Chris Tetreault > > > > From: Serge Pavlov <sepavloff at gmail.com> > Sent: Friday, September 10, 2021 9:21 PM > To: Chris Tetreault <ctetreau at quicinc.com> > Cc: Richard Smith <richard at metafoo.co.uk>; llvm-dev at lists.llvm.org; cfe-dev at lists.llvm.org > Subject: Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode? > > > > WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > The problem is that math code is often templated, so `template <typename T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a header. > > > > No problem, the user can write: > > ``` > > #ifdef __FAST_MATH__ > > #undef isnan > #define isnan(x) false > > #endif > > ``` > and put it somewhere in the headers. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > Regardless, my position isn’t “there is no NaN”. My position is “you cannot count on operations on NaN working”. > > > > Exactly. Attempts to express the condition of -ffast-math as restrictions on types are not fruitful. I think it is the reason why GCC documentation does not use simple and clear "there is no NaN" but prefers more complicated wording about arithmetic. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > I think working around these sorts of issues is something that C and C++ developers are used to. These sorts of “inconsistent” between compilers behaviors is something we accept because we know it comes with improved performance. In this case, the fix is easy, so I don’t think this corner case is worth supporting. Especially when the fix is also just one line: > ``` > #define myIsNan(x) (reinterpret_cast<uint32_t>(x) == THE_BIT_PATTERN_OF_MY_SENTINEL_NAN) > ``` > > > > It won't work in this way. If `x == 5.0`, then `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. Standard C does not have such. To emulate it a reinterpret_cast of memory can be used: `*reinterpret_cast<int *>(&x)`. Another way is to use a union. Both these solutions require operations with memory, which is not good for performance, especially on GPU and ML cores. Of course, a smart compiler can eliminate memory operation, but it does not have to do it always, as it is only optimization. Moving a value between float and integer pipelines also may incur a performance penalty. At the same time this check often may be done with a single instruction. > > > > Thanks, > --Serge > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Krzysztof Parzyszek via llvm-dev
2021-Sep-13 17:05 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
my opinion on the question “Should isnan be optimized out in fast-math mode?” is “Yes” […] +1 -- Krzysztof Parzyszek kparzysz at quicinc.com<mailto:kparzysz at quicinc.com> AI tools development From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Chris Tetreault via llvm-dev Sent: Monday, September 13, 2021 11:46 AM To: Serge Pavlov <sepavloff at gmail.com> Cc: llvm-dev at lists.llvm.org; cfe-dev at lists.llvm.org Subject: Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode? WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. Honestly, we can do this until the end of time. I think we both agree, that for either scheme, there exists workarounds. The question is which workarounds are more palatable, which is a matter of opinion. I think we’ve come to an impasse, so let me just state that my opinion on the question “Should isnan be optimized out in fast-math mode?” is “Yes”, which is what you asked to get in your original message. I think that the implementation of fast-math will be cleaner if we don’t special case a bunch of random constructs in order to do what the user meant instead of what they said. I think fast-math is a notorious footgun, and any attempts to mitigate this will only reduce the effectiveness of the tool, while not really improving the user experience. As a user, if I read that: ``` if (isnan(x)) { ``` … is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when: ``` if (isnan(x + 0)) { ``` … does not also work. I’m going to open a bug and complain, and the slide down the slippery slope will continue. You and I understand the difference, and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` isn’t, but Joe Coder just trying to figure out why he’s got NaN in his matrices despite his careful NaN handling code. Joe is not a compiler expert, and on the face of it, it seems like a silly limitation. This will never end until fast-math is gutted. Thanks, Chris Tetreault From: Serge Pavlov <sepavloff at gmail.com<mailto:sepavloff at gmail.com>> Sent: Friday, September 10, 2021 9:21 PM To: Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> Cc: Richard Smith <richard at metafoo.co.uk<mailto:richard at metafoo.co.uk>>; llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>; cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org> Subject: Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode? WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: The problem is that math code is often templated, so `template <typename T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a header. No problem, the user can write: ``` #ifdef __FAST_MATH__ #undef isnan #define isnan(x) false #endif ``` and put it somewhere in the headers. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: Regardless, my position isn’t “there is no NaN”. My position is “you cannot count on operations on NaN working”. Exactly. Attempts to express the condition of -ffast-math as restrictions on types are not fruitful. I think it is the reason why GCC documentation does not use simple and clear "there is no NaN" but prefers more complicated wording about arithmetic. On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com<mailto:ctetreau at quicinc.com>> wrote: I think working around these sorts of issues is something that C and C++ developers are used to. These sorts of “inconsistent” between compilers behaviors is something we accept because we know it comes with improved performance. In this case, the fix is easy, so I don’t think this corner case is worth supporting. Especially when the fix is also just one line: ``` #define myIsNan(x) (reinterpret_cast<uint32_t>(x) == THE_BIT_PATTERN_OF_MY_SENTINEL_NAN) ``` It won't work in this way. If `x == 5.0`, then `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. Standard C does not have such. To emulate it a reinterpret_cast of memory can be used: `*reinterpret_cast<int *>(&x)`. Another way is to use a union. Both these solutions require operations with memory, which is not good for performance, especially on GPU and ML cores. Of course, a smart compiler can eliminate memory operation, but it does not have to do it always, as it is only optimization. Moving a value between float and integer pipelines also may incur a performance penalty. At the same time this check often may be done with a single instruction. Thanks, --Serge -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210913/031c986c/attachment.html>
Aaron Ballman via llvm-dev
2021-Sep-13 17:08 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
Sorry for fat-fingering my previous attempt at a response. If it would be helpful, I am happy to put people in touch with the WG14 C Floating Point study group. Then these questions can be asked of a wider audience of compiler vendors to see if there's some common thoughts on the subject, even if WG14 won't have an "official" stance because the behavior is wholly a matter of QoI. I'd request that we nominate one person from the LLVM community to hold that discussion and report back so we don't throw the study group into the deep end of our pool (and given my lack of domain knowledge, I'd appreciate it if that someone was not me). ~Aaron On Mon, Sep 13, 2021 at 12:46 PM Chris Tetreault via cfe-dev <cfe-dev at lists.llvm.org> wrote:> > Honestly, we can do this until the end of time. I think we both agree, that for either scheme, there exists workarounds. The question is which workarounds are more palatable, which is a matter of opinion. I think we’ve come to an impasse, so let me just state that my opinion on the question “Should isnan be optimized out in fast-math mode?” is “Yes”, which is what you asked to get in your original message. I think that the implementation of fast-math will be cleaner if we don’t special case a bunch of random constructs in order to do what the user meant instead of what they said. I think fast-math is a notorious footgun, and any attempts to mitigate this will only reduce the effectiveness of the tool, while not really improving the user experience. > > > > As a user, if I read that: > > > > ``` > > if (isnan(x)) { > > ``` > > > > … is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when: > > > > ``` > > if (isnan(x + 0)) { > > ``` > > > > … does not also work. I’m going to open a bug and complain, and the slide down the slippery slope will continue. You and I understand the difference, and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` isn’t, but Joe Coder just trying to figure out why he’s got NaN in his matrices despite his careful NaN handling code. Joe is not a compiler expert, and on the face of it, it seems like a silly limitation. This will never end until fast-math is gutted. > > > > Thanks, > > Chris Tetreault > > > > From: Serge Pavlov <sepavloff at gmail.com> > Sent: Friday, September 10, 2021 9:21 PM > To: Chris Tetreault <ctetreau at quicinc.com> > Cc: Richard Smith <richard at metafoo.co.uk>; llvm-dev at lists.llvm.org; cfe-dev at lists.llvm.org > Subject: Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode? > > > > WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > The problem is that math code is often templated, so `template <typename T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a header. > > > > No problem, the user can write: > > ``` > > #ifdef __FAST_MATH__ > > #undef isnan > #define isnan(x) false > > #endif > > ``` > and put it somewhere in the headers. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > Regardless, my position isn’t “there is no NaN”. My position is “you cannot count on operations on NaN working”. > > > > Exactly. Attempts to express the condition of -ffast-math as restrictions on types are not fruitful. I think it is the reason why GCC documentation does not use simple and clear "there is no NaN" but prefers more complicated wording about arithmetic. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> wrote: > > I think working around these sorts of issues is something that C and C++ developers are used to. These sorts of “inconsistent” between compilers behaviors is something we accept because we know it comes with improved performance. In this case, the fix is easy, so I don’t think this corner case is worth supporting. Especially when the fix is also just one line: > ``` > #define myIsNan(x) (reinterpret_cast<uint32_t>(x) == THE_BIT_PATTERN_OF_MY_SENTINEL_NAN) > ``` > > > > It won't work in this way. If `x == 5.0`, then `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. Standard C does not have such. To emulate it a reinterpret_cast of memory can be used: `*reinterpret_cast<int *>(&x)`. Another way is to use a union. Both these solutions require operations with memory, which is not good for performance, especially on GPU and ML cores. Of course, a smart compiler can eliminate memory operation, but it does not have to do it always, as it is only optimization. Moving a value between float and integer pipelines also may incur a performance penalty. At the same time this check often may be done with a single instruction. > > > > Thanks, > --Serge > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Serge Pavlov via llvm-dev
2021-Sep-13 17:50 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
What I'd like to emphasize is that this option was introduced not for logical consistency, but for practical needs. It allows users to get faster code and this is why it is an important option. We are discussing two ways, which are not equivalent. If `isnan` is unconditionally optimized out, users that need it have to use workarounds, which leads to loss of portability and performance. If `isnan` is preserved, no workarounds are required, simple redefinition results in the "old" behavior. It seems to me that implementation of this option should pursue practical needs and should enable most use cases. The current implementation does not fit user needs, as it follows from the complaints in gcc bug tracker and forums. We could make clang more user-friendly if this option would be implemented slightly differently than now. On Mon, Sep 13, 2021 at 11:46 PM Chris Tetreault <ctetreau at quicinc.com> wrote:> … is guaranteed to work, and I read that fast-math enables the compiler to > reason about constructs like `x + 0` being equal to `x`, then I’m going to > be very confused when: >You are right, this was a bad idea. Compiler may optimize out `isnan` but only when it deduces that the value cannot be NaN, but not due to the user's promise. It is especially important for `isinf`. Addition of two finite values may produce infinity and there is no universal way to predict it. It is probably not an issue for types like float or double, but ML cores use halfs or even minifloats, where overflow is much more probable. If in the code: ``` float r = a + b; if (isinf(r)) {... ``` `isinf` were optimized out just because -ffinite-math-only is in effect, the user cannot check if overflow did not occur. This contrasts with the definition of `ninf` in LLVM IR: "No Infs - Allow optimizations to assume the arguments and result are not +/-Inf." It is possible to ensure that arguments are not Infs but for the result it is much more difficult to guarantee. Thanks, --Serge On Mon, Sep 13, 2021 at 11:46 PM Chris Tetreault <ctetreau at quicinc.com> wrote:> Honestly, we can do this until the end of time. I think we both agree, > that for either scheme, there exists workarounds. The question is which > workarounds are more palatable, which is a matter of opinion. I think we’ve > come to an impasse, so let me just state that my opinion on the question > “Should isnan be optimized out in fast-math mode?” is “Yes”, which is what > you asked to get in your original message. I think that the implementation > of fast-math will be cleaner if we don’t special case a bunch of random > constructs in order to do what the user meant instead of what they said. I > think fast-math is a notorious footgun, and any attempts to mitigate this > will only reduce the effectiveness of the tool, while not really improving > the user experience. > > > > As a user, if I read that: > > > > ``` > > if (isnan(x)) { > > ``` > > > > … is guaranteed to work, and I read that fast-math enables the compiler to > reason about constructs like `x + 0` being equal to `x`, then I’m going to > be very confused when: > > > > ``` > > if (isnan(x + 0)) { > > ``` > > > > … does not also work. I’m going to open a bug and complain, and the slide > down the slippery slope will continue. You and I understand the difference, > and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` > isn’t, but Joe Coder just trying to figure out why he’s got NaN in his > matrices despite his careful NaN handling code. Joe is not a compiler > expert, and on the face of it, it seems like a silly limitation. This will > never end until fast-math is gutted. > > > > Thanks, > > Chris Tetreault > > > > *From:* Serge Pavlov <sepavloff at gmail.com> > *Sent:* Friday, September 10, 2021 9:21 PM > *To:* Chris Tetreault <ctetreau at quicinc.com> > *Cc:* Richard Smith <richard at metafoo.co.uk>; llvm-dev at lists.llvm.org; > cfe-dev at lists.llvm.org > *Subject:* Re: [llvm-dev] [cfe-dev] Should isnan be optimized out in > fast-math mode? > > > > *WARNING:* This email originated from outside of Qualcomm. Please be wary > of any links or attachments, and do not enable macros. > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> > wrote: > > The problem is that math code is often templated, so `template <typename > T> MyMatrixT<T> safeMul(const MyMatrixT<T> & lhs …` is going to be in a > header. > > > > No problem, the user can write: > > ``` > > #ifdef __FAST_MATH__ > > #undef isnan > #define isnan(x) false > > #endif > > ``` > and put it somewhere in the headers. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> > wrote: > > Regardless, my position isn’t “there is no NaN”. My position is “you > cannot count on operations on NaN working”. > > > > Exactly. Attempts to express the condition of -ffast-math as restrictions > on types are not fruitful. I think it is the reason why GCC documentation > does not use simple and clear "there is no NaN" but prefers more > complicated wording about arithmetic. > > > > On Sat, Sep 11, 2021 at 2:39 AM Chris Tetreault <ctetreau at quicinc.com> > wrote: > > I think working around these sorts of issues is something that C and C++ > developers are used to. These sorts of “inconsistent” between compilers > behaviors is something we accept because we know it comes with improved > performance. In this case, the fix is easy, so I don’t think this corner > case is worth supporting. Especially when the fix is also just one line: > ``` > #define myIsNan(x) (reinterpret_cast<uint32_t>(x) => THE_BIT_PATTERN_OF_MY_SENTINEL_NAN) > ``` > > > > It won't work in this way. If `x == 5.0`, then > `reinterpret_cast<uint32_t>(x) == 5`. What you need there is a bitcast. > Standard C does not have such. To emulate it a reinterpret_cast of memory > can be used: `*reinterpret_cast<int *>(&x)`. Another way is to use a > union. Both these solutions require operations with memory, which is not > good for performance, especially on GPU and ML cores. Of course, a smart > compiler can eliminate memory operation, but it does not have to do it > always, as it is only optimization. Moving a value between float and > integer pipelines also may incur a performance penalty. At the same time > this check often may be done with a single instruction. > > > > Thanks, > --Serge >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210914/19048407/attachment.html>
Michael Kruse via llvm-dev
2021-Sep-16 19:28 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
Am Mo., 13. Sept. 2021 um 11:46 Uhr schrieb Chris Tetreault via cfe-dev <cfe-dev at lists.llvm.org>:> As a user, if I read that: > > > > ``` > > if (isnan(x)) { > > ``` > > > > … is guaranteed to work, and I read that fast-math enables the compiler to reason about constructs like `x + 0` being equal to `x`, then I’m going to be very confused when: > > > > ``` > > if (isnan(x + 0)) { > > ``` > > > > … does not also work. I’m going to open a bug and complain, and the slide down the slippery slope will continue. You and I understand the difference, and the technical reason why `isnan(x)` is supported but `isnan(x + 0)` isn’t, but Joe Coder just trying to figure out why he’s got NaN in his matrices despite his careful NaN handling code. Joe is not a compiler expert, and on the face of it, it seems like a silly limitation. This will never end until fast-math is gutted.C/C++ already has cases like this. Pointer arithmetic on null pointers is undefined behaviour, even if adding[1,2]/subtracting[3] zero. I don't think it is too far fetched to expect from users to know that an operation is undefined behaviour even if one of the operands is zero. Michael [1] https://github.com/llvm/llvm-project/blob/main/clang/test/Sema/pointer-addition.c [2] https://github.com/llvm/llvm-project/blob/main/compiler-rt/test/ubsan/TestCases/Pointer/nullptr-and-nonzero-offset-constants.cpp [3] https://github.com/llvm/llvm-project/blob/main/clang/test/Sema/pointer-subtraction.c Michael