-
Notifications
You must be signed in to change notification settings - Fork 23
Open
Description
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.
Metadata
Metadata
Assignees
Labels
No labels