This was asked and answered a few days ago (Re: [LLVMdev] Pass a struct on
windows):
==Hi Wei,
> Thanks for reply! This is indeed annoying. I suspect that passing an
pointer to
> the struct
> and using GEP instructions to access and modify the struct would work on
all
> platforms.
> Is this true?
yes, I think that would work fine.
Ciao, Duncan.
>
> Thanks,
>
> Wei
>
> On Thu, Aug 11, 2011 at 7:55 AM, Duncan Sands <baldrick at free.fr
> <mailto:baldrick at free.fr>> wrote:
>
> Hi Wei, this is a FAQ. The LLVM code generators do *not* try to
produce ABI
> conformant code. Instead, your front-end must produce LLVM IR which is
already
> ABI conformant. For example, on a platform where a function returning
a struct
> should return it via a hidden pointer, the IR function should be
declared with
> an explicit pointer argument for returning it; while on platforms for
which it
> should be returned in registers, the IR function should be declared to
return
> a struct. Yes, this is very annoying.
>
> Ciao, Duncan.
>
> > I made a simple test about aggregates in llvm IR. My simple LLVM
code
> > is running as expected under linux 32/64, but not under windows
32.
> > After searched on the web on multiple return values, I'm
still not sure if
> > this test case can be flagged as the ABI issue. Or this would be
a llvm
> > code generator bug on window 32. The complete IR is attached as a
text file
> > and I checked the test with lli.
> >
> > (1) Pass a struct of type {void*, uint64_t} by pointer (in fact
this is
> > generated from Clang 3.0).
> > The returned value of @call_by_pointer is 4 as expected, on both
windows
> XP ia32
> > and linux ubuntu x64 I tested.
> >
> > %0 = type { i8*, i64 }
> >
> > define void @foo_by_pointer(%0* %agg_addr, i8*, i64) nounwind {
> > entry:
> > %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32
0
> > store i8* %0, i8** %agg_addr.0, align 8
> > %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32
1
> > store i64 %1, i64* %agg_addr.1, align 8
> > ret void
> > }
> >
> > define i64 @call_by_pointer() {
> > %a_ptr = alloca float, align 4
> > %a_opq = bitcast float* %a_ptr to i8*
> > %agg_addr = alloca %0, align 8
> > call void @foo_by_pointer(%0* %agg_addr, i8* %a_opq, i64 4)
> > %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32
1
> > %result.1 = load i64* %agg_addr.1, align 8
> > ret i64 %result.1
> > }
> >
> > (2) Pass the struct by value (minor modifications on above code).
> > The only difference is that we build the structure inside callee
> @foo_by_value
> > and pass it by value to the caller @call_by_value. The returned
value of
> > @call_by_value is a random number on windows XP ia32. But on
linux
> > ubuntu x64 it is correct, 4.
> >
> > define %0 @foo_by_value(i8*, i64) nounwind {
> > entry:
> > %agg_addr = alloca %0, align 8
> > %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32
0
> > store i8* %0, i8** %agg_addr.0, align 8
> > %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32
1
> > store i64 %1, i64* %agg_addr.1, align 8
> > %result = load %0* %agg_addr, align 8
> > ret %0 %result
> > }
> >
> > define i64 @call_by_value() {
> > %a_ptr = alloca float, align 4
> > %a_opq = bitcast float* %a_ptr to i8*
> > %result = call %0 @foo_by_value(i8* %a_opq, i64 4)
> > %agg_addr = alloca %0, align 8
> > store %0 %result, %0* %agg_addr, align 8
> > %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32
1
> > %result.1 = load i64* %agg_addr.1, align 8
> > ret i64 %result.1
> > }
> >
> > Is this a LLVM bug? Or call_by_value with foo_by_valye is invalid
LLVM code?
> >
> > Thanks,
> >
> > Wei
> >
> >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
http://llvm.cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
==
--
Stefanus Du Toit stefanus.du.toit at intel.com
Intel Array Building Blocks - http://intel.com/go/arbb
Intel Embedded Computing, Debuggers & Libraries
Intel Waterloo
phone: +1 519 772 2576 -- fax: +1 519 772 2586
> -----Original Message-----
> From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at
cs.uiuc.edu] On
> Behalf Of Nicolas Ojeda Bar
> Sent: Monday, August 15, 2011 12:02 PM
> To: llvmdev at cs.uiuc.edu
> Subject: [LLVMdev] structured types as function arguments
>
> Hi,
>
> When calling a function, does the llvm code generator support passing
> structured types (arrays, structs, etc.) by _value_? I wrote some small
examples,
> and it seemed
> to work, but I was wondering if anything can go wrong if the structured
types
> are very large...
>
> Thanks,
> N
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev