Hi All,
Using option ffp-model=fast and #pragma STDC FP_CONTRACT OFF doesn’t have the expected clang’s behavior of pragmas.
See for example https://godbolt.org/z/PYYd5zd4Pthis The pragma is honored; FMA instructions are generated following the option and are suppressed as directed by the pragma at codegen.
In contrast, https://godbolt.org/z/WvvaKrv1b shows that the option -ffp-model=fast is honored in the FE, but the pragma is ignored. The LLVM IR generated is correct, but codegen doesn’t honor the pragma as expected. Although this seems to be “historically” (codegen didn’t used to get fast-math flags so a global option was used; now codegen sees these flags) the pragma should be honored. This should be filed as a bug.
Thoughts?
Thanks.

A bug has been filed about this: https://bugs.llvm.org/show_bug.cgi?id=39679
On the other hand, a change was made to add a new setting, fast-honor-pragmas, to the -ffp-contract option (though it doesn’t seem to work from the command line) and document the current behavior: https://reviews.llvm.org/D90174
I’ve brought this up before and I feel very strongly that the pragma should be honored even when fp-contract=fast is used on the command line. The current behavior depends on a communication channel outside the IR, which is bad. The argument has been made in the past that ignoring the pragma is consistent with gcc behavior, but gcc doesn’t support the pragma at all, so I don’t think that’s a very strong argument.
There are tests in llvm-test-suite, which fail when FMA is performed, and without the pragma being respected, the only practical way to force the tests to pass with fast-math enabled is to override the option and set fp-contract=off for these tests. If the pragma were respected, we’d be able to have these tests use two kernels – one with FMA enabled for performance measurements, and one with FMA disabled to provide a baseline for results verification. Here’s an example of such a test: https://github.com/llvm/llvm-test-suite/tree/main/SingleSource/Benchmarks/Polybench/linear-algebra/kernels/3mm The CMakeLists.txt and Makefile for this test have been modified to force fp-contract=off, but there is code in the test that would perform a relative error comparison if the pragma could be relied upon.
I would like to build a consensus, for or against, changing the current behavior. If you care about this either way, please respond.
Thanks,
Andy

In an ideal world, the pragma should be either honored or result in an
explicit compile-time error if it can't be honored. E.g. if the
implementation requires the pragma to be specified outside a function,
it would be reasonable to error if it should change the state when used
inside a function.
Joerg
I'm not aware of any cases where it isn't possible to honor the pragma. There was a time when the backend didn't have fast-math flags during instruction selection, and so it relied on TargetOptions::FPOpFusion. However, the fast-math flags have been available for several years now. The clang front end generates the correct representation with respect to the pragma (that is, it omits the 'contract' fast-math flag when the pragma turns fp-contract off), but the backend is still looking at the TargetOption::FPOpFusion setting and ignoring the absence of the contract flag. I think this is obviously wrong.
For what it's worth, here is the patch where the DAGCombiner was taught to check the 'contract' fast-math flag: ⚙ D31169 [DAGCombiner] Initial support for the fast-math flag contract
Note that in this patch, the old check for TargetOptions::FPOpFusion==FPOpFusion::Fast was left (along with TargetOptions::UnsafeFPMath) and used to set a flag, AllowFusionGlobally. I would regard that as a mistake.
-Andy