There are 2 parts to getting the -fassociative-math command-line flag translated to LLVM FMF:
- In the driver/frontend, we accept the flag and its 'no' inverse and deal with the interactions with other flags like -ffast-math. This was mostly already done - we just needed to pass the flag on as a codegen option. The test file is complicated because there are many potential combinations of flags here.
- In codegen, we map the option to FMF in the IR builder. This is simple code and corresponding test.
For the motivating example from PR27372:
float foo(float a, float x) { return ((a + x) - x); } $ ./clang -O2 27372.c -S -o - -ffast-math -fno-associative-math -emit-llvm | egrep 'fadd|fsub' %add = fadd nnan ninf nsz arcp contract float %0, %1 %sub = fsub nnan ninf nsz arcp contract float %add, %2
So 'reassoc' is off as expected (and so is the new 'afn' but that's a different patch). This case now works as expected end-to-end although the underlying logic is still wrong:
$ ./clang -O2 27372.c -S -o - -ffast-math -fno-associative-math | grep xmm addss %xmm1, %xmm0 subss %xmm1, %xmm0
We're not done because the case where 'reassoc' is set is ignored by optimizer passes. Example:
$ ./clang -O2 27372.c -S -o - -fassociative-math -emit-llvm | grep fadd %add = fadd reassoc float %0, %1 $ ./clang -O2 27372.c -S -o - -fassociative-math | grep xmm addss %xmm1, %xmm0 subss %xmm1, %xmm0