[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