[LLVMdev] Broke my tail (call)

Jon Harrop jon at ffconsultancy.com
Sun Feb 22 15:20:22 PST 2009


On Sunday 22 February 2009 20:36:52 Duncan Sands wrote:
> Hi Jon,
>
> > I have written a variety tests of tail calls for my HLVM and all passed
> > with flying colors until I wrote this test (which is actually for
> > algebraic datatypes) and discovered that it segfaults after ~100k
> > iterations through what I think should be a tail call. Here's the IR:
>
> is this really a tail call?

>From what I have understood of the LLVM docs about when tail calls get 
eliminated on x86 and x64 it should be a tail call, yes.

  http://llvm.org/docs/CodeGenerator.html#tailcallopt

. Caller and callee have the calling convention fastcc.
. The call is a tail call - in tail position (ret immediately follows call and 
ret uses value of call or is void).
. Option -tailcallopt is enabled.
. No variable argument lists are used.
. On x86-64 when generating GOT/PIC code only module-local calls (visibility = 
hidden or protected) are supported.

Those are all satisfied.

> I didn't look closely but at a glance it seems to be passing a local stack
> variable as a call parameter. 

In this case, the arguments are a { { i8*, i8* }*, i8* } and a i32. As I 
understand it, first-class structs are simply unpacked for argument passing 
so that is equivalent to passing { i8*, i8* }* and i8* and i32. In this case, 
the first is a pointer to a global variable and the second is a pointer to a 
malloc'd block. So I don't see why any of the arguments should be inhibiting 
tail call elimination.

I just tested my theory that returning a first-class struct from a function 
inhibits tail call elimination and it seems that I was correct: altering this 
function to pass its return struct by pointer in the first argument fixes the 
stack overflow.

Is this a bug in LLVM?

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e




More information about the llvm-dev mailing list