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()
    {
        do_foo();
        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?

Thanks,

Robin

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".

-Eli