Returning structs on Linux x86

Hello all,

I've run into a problem with returning a struct on Linux x86.

Consider the following two pieces of code:

    # cat a.ll
    declare { i32, i32 } @foo(i32, i32, i32)
    define void @do_foo() {
        call { i32, i32 } @foo(i32 1, i32 2, i32 3)
        ret void
    # cat b.c
    #include <stdio.h>
    #include <stdint.h>
    extern void do_foo();
    int main()
        return 0;
    struct A {
        int32_t a;
        int32_t b;
    struct A foo(int32_t a, int32_t b, int32_t c)
        const struct A x = { 1, 2 };
        fprintf(stderr, "%d %d %d\n", a, b, c);
        return x;

    # llvm-as <a.ll | llc >a.S && gcc b.c a.S
    # ./a.out
    2 3 134513658
    Segmentation fault

I see this with both LLVM 2.4 and 2.5. On Darwin x86, however, I get
the expected "1 2 3" (only tried with 2.4 there) and on Linux x86_64
it works fine as well (with 2.5).

Is this a known limitation of the x86 backend?



If you want ABI compatibility with C code, you have to implement some
knowledge of the ABI rules, which are different between Darwin and
Linux. Try comparing the output of "clang-cc -emit-llvm -triple
i686-pc-linux-gnu -O2" and "clang-cc -emit-llvm -triple
i386-apple-darwin10 -O2".