AdaCore / gnat-llvm

LLVM based GNAT compiler
179 stars 18 forks source link

ABI issue passing float records by copy to C code #42

Open deniska opened 4 months ago

deniska commented 4 months ago

Minimal example I could come up with:

hello.c:

struct two_floats { float a; float b; };

float hello(struct two_floats x) {
    return x.a + x.b;
}

mini.ada:

with Ada.Text_IO; use Ada.Text_IO;

function Mini return Integer is
    type Two_Floats is record
        a: aliased float;
        b: aliased float;
    end record
        with Convention => C_Pass_By_Copy;

    function hello(a: two_floats) return float
        with
            Import => True,
            Convention => C,
            External_Name => "hello";

    x: Two_Floats;
    y: float;
begin
    x := (3.0, 4.0);
    y := hello(x);
    Put_Line(y'Image);
    return 0;
end;

gnat-llvm gives incorrect results, while gcc gives the correct one:

$ ~/sdk/llvm-16.0.6/bin/clang -c hello.c && ar rc hello.a hello.o
$ ~/src/gnat-llvm/llvm-interface/bin/llvm-gnatmake -ggdb -f mini.adb -largs hello.a && ./mini
llvm-gcc -c -ggdb mini.adb
llvm-gnatbind -x mini.ali
llvm-gnatlink mini.ali -ggdb hello.a
 3.00000E+00
$ ~/sdk/gcc-13.2.0/bin/gnatmake -ggdb -f mini.adb -largs hello.a && ./mini
gcc -c -ggdb mini.adb
gnatbind -x mini.ali
gnatlink mini.ali -ggdb hello.a
 7.00000E+00

Looking at disassembly output I'm seeing that the version built with gnat-llvm passes the struct via RDI register while version built with gcc passes the struct via XMM0 (like the convention used on x86_64 linux assumes):

$ objdump -d ./mini_from_llvm
...
mov    0x40(%rsp),%rdi
callq  4de0 <hello>
movss  %xmm0,0x3c(%rsp)
...
$ objdump -d ./mini_from_gcc
mov    -0x48(%rbp),%rax
movq   %rax,%xmm0
callq  404680 <hello>
movd   %xmm0,%eax
mov    %eax,-0x34(%rbp)

So I'm wondering whether the issue is reproducible for anyone else, or if it's something wrong with my gnat-llvm setup.

ArnaudCharlet commented 1 month ago

Issue closed by accident (conflict between AdaCore GitLab issues and GitHub issues)