Documentation on -ffp-contract=fast vs pragma contract(off)

Hi,

The documentation of the #pragma clang fp contract appears to
misrepresent the interaction of -ffp-contract=fast with the #pragma
clang fp contract(off). The documentation states:

The pragma can also be used with off which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise enabled for the translation unit with the -ffp-contract=fast flag.

(https://clang.llvm.org/docs/LanguageExtensions.html#extensions-to-specify-floating-point-flags)

However, a minimal example contradicts that:

float abc_pragma_off(float a, float b, float c) {
#pragma clang fp contract(off)
  return a * b + c;
}

... is compiled to a fused multiply-add:
$ clang -o - -S -march=haswell -O3 -ffp-contract=fast min.c

abc_pragma_off:
  vfmadd213ss %xmm2, %xmm1, %xmm0 # xmm0 = (xmm1 * xmm0) + xmm2
  retq

In my understanding, setting -ffp-contract=fast allows the backend to
always contract FP operations. Since setting the pragma to off only
controls clang's frontend and the pragma is not expressed in the IR, it
cannot override the backend's behavior.

If clang behaves as designed in that case, I think we should fix the
documentation, along the lines of

"The pragma can also be used with off which turns FP contraction off for
a section of the code. Note that if fast contraction is enabled for a
translation unit with the flag -ffp-contract=fast then using the pragma
with off will have not effect".

Marius

Hi,

The documentation of the #pragma clang fp contract appears to
misrepresent the interaction of -ffp-contract=fast with the #pragma
clang fp contract(off). The documentation states:

The pragma can also be used with off which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise enabled for the translation unit with the -ffp-contract=fast flag.

(https://clang.llvm.org/docs/LanguageExtensions.html#extensions-to-specify-floating-point-flags)

However, a minimal example contradicts that:

float abc_pragma_off(float a, float b, float c) {
#pragma clang fp contract(off)
  return a * b + c;
}

... is compiled to a fused multiply-add:
$ clang -o - -S -march=haswell -O3 -ffp-contract=fast min.c

abc_pragma_off:
   vfmadd213ss %xmm2, %xmm1, %xmm0 # xmm0 = (xmm1 * xmm0) + xmm2
   retq

Hi,

This looks very similar to what I had just found in <http://lists.llvm.org/pipermail/cfe-dev/2020-September/066870.html> for #pragma float_control. There are probably more #pragmas with the same problem.

In my understanding, setting -ffp-contract=fast allows the backend to
always contract FP operations. Since setting the pragma to off only
controls clang's frontend and the pragma is not expressed in the IR, it
cannot override the backend's behavior.

For anything that starts with #pragma clang, that could be reasonable, but I had thought this to be a backend bug because it affects pragmas that are not specific to clang, where it would seem very strange to me to adjust the documentation to match the implementation.

Cheers,
Harald van Dijk