[LLVMdev] Pass a struct on windows

Wei Pan wei.pan9 at gmail.com
Thu Aug 11 07:17:05 PDT 2011


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?

Thanks,

Wei

On Thu, Aug 11, 2011 at 7:55 AM, Duncan Sands <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         http://llvm.cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110811/5b0bf2aa/attachment.html>


More information about the llvm-dev mailing list