[LLVMdev] Wrong calling convention?
Duncan Sands
baldrick at free.fr
Wed Mar 26 08:30:03 PDT 2008
Hi Óscar,
> >> define internal i1 @Addr_045442A0() {
> >> alloca [8 x i8], align 4 ; <[8 x i8]*>:1 [#uses=2]
> >> alloca i1, align 4 ; <i1*>:2 [#uses=2]
> >> tail call void @F95478DA5_FFI_FN( [8 x i8]* %1 sret )
> >
> > this call uses the "struct-return" convention (due to the sret attribute).
> > On x86 this means that the caller is responsible for adjusting the stack
> > pointer after the call for the sret parameter. If the callee is not following
> > the sret convention then the stack pointer will be adjusted wrongly and your
> > program will die horribly.
> >
> >> 0x0e8d937b: call 0x5053b0 <_ZN3lp04OpF0IN5IncDB9TDateTimeEXadL_ZNS2_3NowEvEEE1wEv>
> >> 0x0e8d9380: sub $0x4,%esp
> >
> > Here you see the sret stack adjustment.
>
> This looks like the opposite: it is making room for passing a parameter
> to the next call (the stack grows downwards).
yes I said it the wrong way round: with sret the callee pops the sret parameter,
so the caller needs to correct for that. I'm pretty sure that's exactly what this
sub is doing.
> But you put me on the right track. The problem is that the class is
> returned on the stack.
>
> This is the class:
>
> class Foo {
> public:
> Foo() : data(113.5) {}
> static Foo GetFoo() { return Foo(); }
> private:
> double data;
> };
>
> This is the assembler code for Foo::GetFoo:
>
> Dump of assembler code for function _ZN3Foo6GetFooEv:
> 0x6e08b5a4 <_ZN3Foo6GetFooEv+0>: push %ebp
> 0x6e08b5a5 <_ZN3Foo6GetFooEv+1>: mov %esp,%ebp
> 0x6e08b5a7 <_ZN3Foo6GetFooEv+3>: sub $0x14,%esp
> 0x6e08b5aa <_ZN3Foo6GetFooEv+6>: lea -0x8(%ebp),%eax
> 0x6e08b5ad <_ZN3Foo6GetFooEv+9>: mov %eax,(%esp)
> 0x6e08b5b0 <_ZN3Foo6GetFooEv+12>: call 0x6e08b5bc <Foo>
> 0x6e08b5b5 <_ZN3Foo6GetFooEv+17>: fldl -0x8(%ebp)
> 0x6e08b5b8 <_ZN3Foo6GetFooEv+20>: leave
> 0x6e08b5b9 <_ZN3Foo6GetFooEv+21>: ret
> End of assembler dump.
>
> I guess that g++ exploits its knowledge of Foo's internals for deciding
> how to return the class.
How Foo is returned is specified by the platform ABI. It is not really a
feature of g++.
> But my compiler knows nothing about Foo, so I
> must disable this "feature" of g++. Suggestions welcome.
It is not possible to correctly codegen parameter passing/result returning
without knowing the type (though not all details of the type are relevant).
Your compiler needs to know something about Foo.
Ciao,
Duncan.
More information about the llvm-dev
mailing list