Skip to content

Force isnan and isinf functions to always work

James Wright requested to merge jrwrigh/force_isnan into main

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.

Edited by James Wright

Merge request reports