@@ -95,6 +95,9 @@ if (MSVC)
9595 # and https://devblogs.microsoft.com/cppblog/the-fpcontract-flag-and-changes-to-fp-modes-in-vs2022/
9696 # By default, MSVC doesn't enable the /fp:fast option.
9797 set_cxx_flag ("/fp:fast" )
98+ else ()
99+ # Precise model (/fp:precise) should do safe contractions, but we should not trust that (see below).
100+ set_cxx_flag ("/fp:strict" )
98101 endif ()
99102
100103 if (USE_LTO)
@@ -118,14 +121,34 @@ else()
118121 set_cxx_flag ("-O3" RELWITHDEBINFO )
119122 endif ()
120123
124+ try_cxx_flag (FNO_MATH_ERRNO "-fno-math-errno" )
125+
121126 if (USE_FAST_MATH)
122- # By default, GCC uses -ffp-contract=fast with -std=gnu* and uses -ffp-contract=off with -std=c*.
123- # See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
124- # By default, GCC doesn't enable the -ffast-math option.
125- set_cxx_flag ("-ffast-math -fno-math-errno -ffp-contract=fast" )
127+ try_cxx_flag (FFAST_MATH "-ffast-math" )
128+
129+ # GCC.
130+ try_cxx_flag (FFP_CONTRACT_FAST "-ffp-contract=fast" )
131+ # Clang.
132+ try_cxx_flag (FFP_MODEL_FAST "-ffp-model=agressive" )
133+ # ICC.
134+ try_cxx_flag (FP_MODEL_FAST_2 "-fp-model=fast=2" )
135+ try_cxx_flag (QSIMD_HONOR_FP_MODEL "-qsimd-honor-fp-model" )
126136 else ()
137+ try_cxx_flag (FNO_FAST_MATH "-fno-fast-math" )
138+
139+ # By default, GCC uses -ffp-contract=fast with -std=gnu* and uses -ffp-contract=off with -std=c*.
127140 # By default, GCC uses -std=gnu* and then enables -ffp-contract=fast even if -ffast-math is not enabled.
128- set_cxx_flag ("-ffp-contract=off" )
141+ # See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
142+ # GCC fast contractions (-ffp-contract=fast) should be safe, but aren't on arm64 with GCC 12.
143+ # Clang precise contractions (-ffp-contract=precise) should be safe, but aren't on arm64 with Clang 14.
144+
145+ # GCC.
146+ try_cxx_flag (FFP_CONTRACT_OFF "-ffp-contract=off" )
147+ # Clang
148+ try_cxx_flag (FFP_MODEL_STRICT "-ffp-model=strict" )
149+ # ICC.
150+ try_cxx_flag (FP_MODEL_STRICT "-fp-model=strict" )
151+ try_cxx_flag (QSIMD_HONOR_FP_MODEL "-qsimd-honor-fp-model" )
129152 endif ()
130153
131154 # It should be done at the very end because it copies all compiler flags
0 commit comments