Force isnan and isinf functions to always work
This is to ensure that PetscIsInfReal
and PetscIsNanReal
always check if a number if Inf
or NaN
. For certain compiler flags (e.g. -Ofast
, -ffast-math
, -ffinite-math-only
, etc.), the compiler will completely ignore calls to isnan
or isinf
(shoutout to this article for bring this to my attention). This can be avoided by having a function marked to not be optimized.
Example
Example:#include <math.h>
#include <stdio.h>
int __attribute__((optimize ("no-finite-math-only"))) isnan_correct(float x) {
return isnan(x);
}
int __attribute__((optimize ("no-finite-math-only"))) isinf_correct(float x) {
return isinf(x);
}
int main() {
float f = NAN;
float g = INFINITY;
if (isnan(f)) printf("it's a NaN!\n");
else printf("it's (probably) not a NaN\n");
if (isinf(g)) printf("it's a Inf!\n");
else printf("it's (probably) not a Inf\n");
printf("corrected version...\n");
if (isnan_correct(f)) printf("it's a NaN!\n");
else printf("it's (probably) not a NaN\n");
if (isinf_correct(g)) printf("it's a Inf!\n");
else printf("it's (probably) not a Inf\n");
return 0;
}
returns:
$ gcc -Ofast main.c && ./a.out
it's (probably) not a NaN
it's (probably) not a Inf
corrected version...
it's a NaN!
it's a Inf!
Todo:
-
Detect if attributes are valid in configure -
Determine appropriate attributes for compilers -
GCC -
Clang -
Intel -
Others?
-
Note that I can't seem to reproduce the isnan
or isinf
bug on clang 17.0.6 on my machine. It's possible they've (rightfully imo) kept the functionality of those functions in, regardless of the compiler settings.