Thanks for reply! This is indeed annoying. I suspect that passing an pointer to the struct <div>and using GEP instructions to access and modify the struct would work on all platforms.</div><div>Is this true? </div><div><div>
<br></div><div>Thanks,</div><div><br></div><div>Wei</div><div><br><div class="gmail_quote">On Thu, Aug 11, 2011 at 7:55 AM, Duncan Sands <span dir="ltr"><<a href="mailto:baldrick@free.fr">baldrick@free.fr</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Hi Wei, this is a FAQ.  The LLVM code generators do *not* try to produce ABI<br>
conformant code.  Instead, your front-end must produce LLVM IR which is already<br>
ABI conformant.  For example, on a platform where a function returning a struct<br>
should return it via a hidden pointer, the IR function should be declared with<br>
an explicit pointer argument for returning it; while on platforms for which it<br>
should be returned in registers, the IR function should be declared to return<br>
a struct.  Yes, this is very annoying.<br>
<br>
Ciao, Duncan.<br>
<div><div></div><div class="h5"><br>
> I made a simple test about aggregates in llvm IR.  My simple LLVM code<br>
> is running as expected under linux 32/64, but not under windows 32.<br>
> After searched on the web on multiple return values, I'm still not sure if<br>
> this test case can be flagged as the ABI issue. Or this would be a llvm<br>
> code generator bug on window 32. The complete IR is attached as a text file<br>
> and I checked the test with lli.<br>
><br>
> (1) Pass a struct of type {void*, uint64_t} by pointer (in fact this is<br>
> generated from Clang 3.0).<br>
> The returned value of @call_by_pointer is 4 as expected, on both windows XP ia32<br>
> and linux ubuntu x64 I tested.<br>
><br>
> %0 = type { i8*, i64 }<br>
><br>
> define void @foo_by_pointer(%0* %agg_addr, i8*, i64) nounwind {<br>
> entry:<br>
>    %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32 0<br>
>    store i8* %0, i8** %agg_addr.0, align 8<br>
>    %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>
>    store i64 %1, i64* %agg_addr.1, align 8<br>
>    ret void<br>
> }<br>
><br>
> define i64 @call_by_pointer() {<br>
>    %a_ptr = alloca float, align 4<br>
>    %a_opq = bitcast float* %a_ptr to i8*<br>
>    %agg_addr = alloca %0, align 8<br>
>    call void @foo_by_pointer(%0* %agg_addr, i8* %a_opq, i64 4)<br>
>    %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>
>    %result.1 = load i64* %agg_addr.1, align 8<br>
>    ret i64 %result.1<br>
> }<br>
><br>
> (2) Pass the struct by value (minor modifications on above code).<br>
> The only difference is that we build the structure inside callee @foo_by_value<br>
> and pass it by value to the caller @call_by_value. The returned value of<br>
> @call_by_value is a random number on windows XP ia32. But on linux<br>
> ubuntu x64 it is correct, 4.<br>
><br>
> define %0 @foo_by_value(i8*, i64) nounwind {<br>
> entry:<br>
>    %agg_addr = alloca %0, align 8<br>
>    %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32 0<br>
>    store i8* %0, i8** %agg_addr.0, align 8<br>
>    %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>
>    store i64 %1, i64* %agg_addr.1, align 8<br>
>    %result = load %0* %agg_addr, align 8<br>
>    ret %0 %result<br>
> }<br>
><br>
> define i64 @call_by_value() {<br>
>    %a_ptr = alloca float, align 4<br>
>    %a_opq = bitcast float* %a_ptr to i8*<br>
>    %result = call %0 @foo_by_value(i8* %a_opq, i64 4)<br>
>    %agg_addr = alloca %0, align 8<br>
>    store %0 %result, %0* %agg_addr, align 8<br>
>    %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>
>    %result.1 = load i64* %agg_addr.1, align 8<br>
>    ret i64 %result.1<br>
> }<br>
><br>
> Is this a LLVM bug? Or call_by_value with foo_by_valye is invalid LLVM code?<br>
><br>
> Thanks,<br>
><br>
> Wei<br>
><br>
><br>
><br>
</div></div>> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br></div></div>