@@ -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)
@@ -122,14 +125,34 @@ else()
122125 set_cxx_flag("-O3" RELWITHDEBINFO)
123126 endif ()
124127
128+ try_cxx_flag(FNO_MATH_ERRNO "-fno-math-errno" )
129+
125130 if (USE_FAST_MATH)
126- # By default, GCC uses -ffp-contract=fast with -std=gnu* and uses -ffp-contract=off with -std=c*.
127- # See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
128- # By default, GCC doesn't enable the -ffast-math option.
129- set_cxx_flag("-ffast-math -fno-math-errno -ffp-contract=fast" )
131+ try_cxx_flag(FFAST_MATH "-ffast-math" )
132+
133+ # GCC.
134+ try_cxx_flag(FFP_CONTRACT_FAST "-ffp-contract=fast" )
135+ # Clang.
136+ try_cxx_flag(FFP_MODEL_FAST "-ffp-model=agressive" )
137+ # ICC.
138+ try_cxx_flag(FP_MODEL_FAST_2 "-fp-model=fast=2" )
139+ try_cxx_flag(QSIMD_HONOR_FP_MODEL "-qsimd-honor-fp-model" )
130140 else ()
141+ try_cxx_flag(FNO_FAST_MATH "-fno-fast-math" )
142+
143+ # By default, GCC uses -ffp-contract=fast with -std=gnu* and uses -ffp-contract=off with -std=c*.
131144 # By default, GCC uses -std=gnu* and then enables -ffp-contract=fast even if -ffast-math is not enabled.
132- set_cxx_flag("-ffp-contract=off" )
145+ # See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
146+ # GCC fast contractions (-ffp-contract=fast) should be safe, but aren't on arm64 with GCC 12.
147+ # Clang precise contractions (-ffp-contract=precise) should be safe, but aren't on arm64 with Clang 14.
148+
149+ # GCC.
150+ try_cxx_flag(FFP_CONTRACT_OFF "-ffp-contract=off" )
151+ # Clang
152+ try_cxx_flag(FFP_MODEL_STRICT "-ffp-model=strict" )
153+ # ICC.
154+ try_cxx_flag(FP_MODEL_STRICT "-fp-model=strict" )
155+ try_cxx_flag(QSIMD_HONOR_FP_MODEL "-qsimd-honor-fp-model" )
133156 endif ()
134157
135158 # It should be done at the very end because it copies all compiler flags
0 commit comments