コンパイラの最適化を妨げている IEEE 浮動小数点規則に問題がありますが、これは明らかなようです。例えば、
char foo(float x) {
if (x == x)
return 1;
else
return 0;
}
NaN == NaN が false であるため、1 を返すように最適化することはできません。わかりました、大丈夫だと思います。
ただし、オプティマイザが実際に修正できるように記述したいと思います。すべてのフロートに当てはまる数学的同一性はありますか? たとえば、!(x - x) が常に保持されているとコンパイラが想定できるのであれば、喜んで !(x - x) を記述します (ただし、そうではありません)。
このような ID については、たとえばここなどで Web 上にいくつかの参照がありますが、IEEE 754 標準の軽いスキャンを含め、整理された情報は見つかりませんでした。
オプティマイザに isnormal(x) を想定させることができれば、(gcc または clang で) 追加のコードを生成する必要はありません。
明らかに、ソース コードに (x == x) を実際に記述するつもりはありませんが、インライン化用に設計された関数があります。関数は foo(float x, float y) として宣言できますが、多くの場合、x は 0、y は 0、または x と y は両方とも z などです。float は画面上の幾何学的座標を表します。これらはすべて、関数を使用せずに手動でコーディングした場合、0 と (x - x) を決して区別せず、ばかげたものを手動で最適化するだけです。そのため、関数をインライン展開した後にコンパイラが行う IEEE 規則についてはまったく気にしません。基本的に画面上で描画を行っているため、丸めの違いもそれほど重要ではありません。
関数がヘッダー ファイルに表示され、関数を使用する .c ファイルが -ffast-math でコンパイルされるのは適切ではないため、-ffast-math はオプションではないと思います。