[llvm-dev] clang 4.0.0: Invalid code for builtin floating point function with -mfloat-abi=hard -ffast-math (ARM)

Peter Jakubek via llvm-dev llvm-dev at lists.llvm.org
Wed Mar 22 13:42:59 PDT 2017


Am 22.03.2017 um 02:38 schrieb Friedman, Eli:
>
> That is probably unintentional.  Granted, using -mfloat-abi like this is
> kind of weird, but I think clang's behavior is supposed to be
> gcc-compatible.  See https://reviews.llvm.org/rL291909 and
> https://bugs.llvm.org/show_bug.cgi?id=30543 for the most recent work in
> this area.

why is using -mfloat-abi weird?

And I do not agree that whether functions are treated as builtin should 
depend on -ffast-math.
(it does not with gcc)

Obviously rL291909 is related. It explicitly states -mfloat-abi should 
be ignored for builtins.
(It does not actually ignore -mfloat-abi unless -ffast-math is specified)

I do not think this is how gcc actually behaves.
Gcc does not ignore -mfloat-abi. This really changes the calling 
conventions for builtin functions to VFP.

And with gcc -ffast-math does *not* change CC. I tested this with the 
latest binary I could find (gcc version 6.3.1 20170215):

https://developer.arm.com/-/media/Files/downloads/gnu-rm/6_1-2017q1/gcc-arm-none-eabi-6-2017-q1-update-win32.exe?product=GNU%20ARM%20Embedded%20Toolchain,32-
bit,,Windows,6-2017-q1-update

Here is a more elaborate example of the problem:

fail.c:

   extern float sinf (float x);
   float sin1 (float x) {return (sinf (x) + 1.0);}

arm-none-eabi-gcc.exe -O2 -mfloat-abi=hard -ffast-math -S fail.c -o -

   sin1:
     push    {r4, lr}
     bl      sinf
     vldr.32 s15, .L3
     pop     {r4, lr}
     vadd.f32        s0, s0, s15
     bx      lr

VFP CC (and optimal code).

Compiled with clang/llvm 4.0.0:
clang.exe -target armv7a-none-none-eabi -O2 -mfloat-abi=hard -ffast-math 
-S fail.c -o -

   sin1:
     push    {r11, lr}
     mov     r11, sp
     vmov    r0, s0
     bl      sinf
     vmov.f32        d16, #1.000000e+00
     vmov    d17, r0, r0
     vadd.f32        d0, d17, d16
     pop     {r11, pc}

Using non-VFP CC - incompatible with the gcc code.

Finally, using eabihf or -fno-fast-math corrects the problem:

clang.exe -target armv7a-none-none-eabihf -O2 -mfloat-abi=hard 
-ffast-math -S fail.c -o -

   sin1:
     push    {r11, lr}
     mov     r11, sp
     vpush   {d8}
     vmov.f32        d8, #1.000000e+00
     bl      sinf
     vadd.f32        d0, d0, d8
     vpop    {d8}
     pop     {r11, pc}

This is using VFP calling conventions as expected.

(I don't like llvm's handling of r11 and d8, though - the optimizer 
needs to be optimized...:-)

IMHO the current handling is incompatible with gcc. (and with previous 
releases of clang)

Cheers,

Peter


More information about the llvm-dev mailing list