[LLVMdev] Pass a struct on windows
Duncan Sands
baldrick at free.fr
Thu Aug 11 07:22:39 PDT 2011
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
>
>
More information about the llvm-dev
mailing list