Skip to content

FTZ/DAZ handling with -ffast-math targets is inconsistent for x86-64 #81204

Open
@andykaylor

Description

@andykaylor

The behavior of intializing the FTZ/DAZ state when using -ffast-math with x86-64 is inconsistent. It depends on the options used on the link command (assuming we're using clang for linking) rather than the options used during compilation.

This can be demonstrated by comparing the results of compiling and linking in one step versus compiling to an object file and linking separately.

$ cat ftz.c

#include <float.h>
#include <stdio.h>

float foo(float);

int main(int argc, char **argv) {
  float two = argc + argc;
  printf("x = %e\n", FLT_MIN / two);
  return 0;
}

$ ../build/bin/clang -O2 -ffast-math -o ftz.exe ftz.c
$ ./ftz.exe

x = 0.000000e+00

$ ../build/bin/clang -c -O2 -ffast-math -o ftz.o ftz.c
$ ../build/bin/clang -o ftz.exe ftz.o
$ ./ftz.exe

x = 5.877472e-39

This is happening because we are setting the FTZ/DAZ state of the MXCSR by linking with crtfastmath.o, as described here: https://clang.llvm.org/docs/UsersManual.html#a-note-about-crtfastmath-o

However, if the -ffast-math option isn't specified on the command-line used to link the executable, we will not link with crtfastmath.o. This is problematic because not only do we not get this advertised benefit of -ffast-math, but we are, nevertheless, setting the "dernomal-fp-math"="preserve-sign,preserve-sign" attribute for all compiled function, indicating that the compiler can assume that denormals will be flushed to zero. As far as I can tell, the primary effect of this for x86-64 targets is that we flush denormals to zero when constant folding.

It may be worth noting that this behavior is consistent with gcc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:driver'clang' and 'clang++' user-facing binaries. Not 'clang-cl'floating-pointFloating-point math

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions