Replies: 2 comments 1 reply
-
There are a ton of these problems. There are ABI requirements and the whole Clang/LLVM pipeline implements different aspects of it in different spots in the pipeline. The |
Beta Was this translation helpful? Give feedback.
0 replies
-
So maybe to try to solve this issue at least, we can either:
I personally think we should go for option 2. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
So over the winter break I started this small chess program in Artic as some kind of fun thing/language demo/benchmark, and encountered two kinds of C ABI troubles:
The first, which we touched on lightly with @leissa on today's call has to do with the poor mapping between C and Artic types when it comes to empty datatypes: These simply do not exist in (standard) C, or are defined has having a size of one in C++, causing alignment issues:
http://161.97.116.199:10240/z/hYYMTn Working around this is simple: just avoid zero-sized data types (we could ban them from being present in exported functions, just like we ban exporting higher order ones)
The other, more problematic one in my opinion, has to do with what Arsène was talking about with LLVM being a "leaky" IR. Despite what the LLVM documentation claims, the C calling rules are (partially) implemented in Clang, and not available to other front-ends as a library. (See https://lists.llvm.org/pipermail/llvm-dev/2020-June/142055.html) In particular, the code for mangling functions with "large" parameters, for an example please see how a function passing a structure
S
is done in Clang versus ThorinWe see the C code putting the whole S struct on the stack, and the Thorin code exploding S and passing its contents in 6 registers + the last one on the stack. The LLVM IR is also different:
Thorin:
Clang:
The real difference here is that Clang uses this
byval
pointer attribute, while Thorin "naively" just passes S by value. Of course once the actual x86_64 code is emitted, stuff that does not fit into physical registers obviously is made to fit by exploding structs and/or allocating them on the stack, but the fact that the LLVM IR signatures did not match makes it so this "second" round of C ABI conversion can and does produce different results and effectively breaks the ability to link Thorin and C code properly when passing large-ish structs.Beta Was this translation helpful? Give feedback.
All reactions