@@ -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:exact" )
98101 endif ()
99102
100103 if (USE_LTO)
@@ -118,14 +121,31 @@ 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+ # GCC.
128+ try_cxx_flag(FFAST_MATH "-ffast-math" )
129+ try_cxx_flag(FFP_CONTRACT_FAST "-ffp-contract=fast" )
130+ # Clang.
131+ try_cxx_flag(FFP_MODEL_FAST "-ffp-model=agressive" )
132+ # ICC.
133+ try_cxx_flag(FP_MODEL_FAST_2 "-fp-model=fast=2" )
126134 else ()
135+ # By default, GCC uses -ffp-contract=fast with -std=gnu* and uses -ffp-contract=off with -std=c*.
127136 # 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" )
137+ # See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
138+ # GCC fast contractions (-ffp-contract=fast) should be safe, but aren't on arm64 with GCC 12.
139+ # Clang precise contractions (-ffp-contract=precise) should be safe, but aren't on arm64 with Clang 14.
140+
141+ # GCC.
142+ try_cxx_flag(FNO_FAST_MATH "-fno-fast-math" )
143+ try_cxx_flag(FFP_CONTRACT_FAST "-ffp-contract=off" )
144+ # Clang
145+ try_cxx_flag(FFP_MODEL_PRECISE "-ffp-model=exact" )
146+ # ICC. Precise model should do safe contractions.
147+ try_cxx_flag(FP_MODEL_PRECISE "-fp-model=exact" )
148+ try_cxx_flag(QSMID_HONOR_FP_MODEL "-qsimd-honor-fp-model" )
129149 endif ()
130150
131151 # It should be done at the very end because it copies all compiler flags
0 commit comments