https://bugs.llvm.org/show_bug.cgi?id=38274
Bug ID: 38274
Summary: Issues with ABI and compatibility
Product: libraries
Version: 6.0
Hardware: Other
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Core LLVM classes
Assignee: unassignedb...@nondot.org
Reporter: ken...@adacore.com
CC: llvm-bugs@lists.llvm.org
I want to reopen the (very old) discussion that occurred in bug 1521 because I
think we have a situation where there's a high burden for front-ends. I'm
working with x86-64. It's not clear what the best "Component" is here.
It looks like the root cause of this issue is that GCC didn't completely follow
the 64-bit ABI for struct parameter types (it's unclear how this happened
because GCC folks were involved with AMD in the creation of that ABI, but it
did) thus causing LLVM to have to choose whether to be compatible with GCC or
the ABI. Unfortunately, the choice seems to be "half and half".
Let's consider a function that's being passed a struct with two i32 components.
The straightforward translation into IR is:
%r = type { i32, i32 }
define void @tworec() {
entry:
call void @p(%r { i32 1, i32 2 })
For x86-64, this obeys the ABI and does:
movl $1, %edi
movl $2, %esi
callq p
This is, however, not what GCC generates, which is complex code that packs both
integers into %edi.
clang does the same, so it's compatible with GCC, but it does it with a messy
IR:
%1 = bitcast %struct.R* %x to i64*
%2 = load i64, i64* %1, align 4
call void @p(i64 %2)
which is even messier for the case of the callee.
The "bug", which is really a question, is how is a front-end supposed to know
to do the above mangling rather than simply generating the straightforward IR?
Note that for large structs, what's done is neither of these, but passing by
"pointer" and using byval. I put "pointer" in quotes because, as far as I can
tell, nothing actually passes a pointer, but just puts the value on the stack.
But this makes things worse because it means that a non-C front end that wants
to pass in a way compatible with C, when it wants to pass by value has to
choose one of *three* possibilities:
(1) Using the straightforward IR representation
(2) Packing data into integers (which means it has to know how wide an integer
to use)
(3) Using byval
How does the front-end determine this in a target-independent way?
If the idea is to use a calling sequence compatible with GCC even if it doesn't
agree with the API, why not use have such a calling sequence explicitly and use
it everywhere? If not, what *is* a front end supposed to do?
--
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs