[LLVMdev] Broke my tail (call)

Jon Harrop jon at ffconsultancy.com
Sun Feb 22 06:17:34 PST 2009


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:

define fastcc { { i8*, i8* }*, i8* } @init({ { i8*, i8* }*, i8* }, i32) {
entry:
        %2 = alloca { i32, { { i8*, i8* }*, i8* } }             ; <{ i32, { { 
i8
*, i8* }*, i8* } }*> [#uses=3]
        %3 = alloca { { i8*, i8* }*, i8* }              ; <{ { i8*, i8* }*, 
i8*
}*> [#uses=3]
        br label %start

start:          ; preds = %entry
        %4 = getelementptr { i32, { { i8*, i8* }*, i8* } }* %2, i32 0, i32 0
        ; <i32*> [#uses=1]
        store i32 %1, i32* %4
        %5 = getelementptr { i32, { { i8*, i8* }*, i8* } }* %2, i32 0, i32 1
        ; <{ { i8*, i8* }*, i8* }*> [#uses=1]
        store { { i8*, i8* }*, i8* } %0, { { i8*, i8* }*, i8* }* %5
        %6 = getelementptr { i32, { { i8*, i8* }*, i8* } }* %2, i32 0
; <{ i32, { { i8*, i8* }*, i8* } }*> [#uses=1]
        %7 = load { i32, { { i8*, i8* }*, i8* } }* %6           ; <{ i32, { { 
i8
*, i8* }*, i8* } }> [#uses=1]
        %8 = malloc { i32, { { i8*, i8* }*, i8* } }             ; <{ i32, { { 
i8
*, i8* }*, i8* } }*> [#uses=2]
        %9 = getelementptr { i32, { { i8*, i8* }*, i8* } }* %8, i32 0
; <{ i32, { { i8*, i8* }*, i8* } }*> [#uses=1]
        store { i32, { { i8*, i8* }*, i8* } } %7, { i32, { { i8*, i8* }*, 
i8* }
}* %9
        %10 = getelementptr { { i8*, i8* }*, i8* }* %3, i32 0, i32 0
; <{ i8*, i8* }**> [#uses=1]
        store { i8*, i8* }* @Cons, { i8*, i8* }** %10
        %11 = bitcast { i32, { { i8*, i8* }*, i8* } }* %8 to i8*
; <i8*> [#uses=1]
        %12 = getelementptr { { i8*, i8* }*, i8* }* %3, i32 0, i32 1
; <i8**> [#uses=1]
        store i8* %11, i8** %12
        %13 = getelementptr { { i8*, i8* }*, i8* }* %3, i32 0           ; <{ { 
i
8*, i8* }*, i8* }*> [#uses=1]
        %14 = load { { i8*, i8* }*, i8* }* %13          ; <{ { i8*, i8* }*, 
i8*
}> [#uses=2]
        %15 = icmp eq i32 %1, 0         ; <i1> [#uses=1]
        br i1 %15, label %pass, label %fail

fail:           ; preds = %start
        %16 = sub i32 %1, 1             ; <i32> [#uses=1]
        %17 = tail call fastcc { { i8*, i8* }*, i8* } @init({ { i8*, i8* }*, 
i8*
 } %14, i32 %16)                ; <{ { i8*, i8* }*, i8* }> [#uses=1]
        ret { { i8*, i8* }*, i8* } %17

pass:           ; preds = %start
        ret { { i8*, i8* }*, i8* } %14
}

Am I going mad or should that tail call three lines up not be leaking stack 
space?

The only possible explanation I can think of is that LLVM believes it cannot 
make this a tail call because it thinks it is passing a pointer to a struct 
that is local to the caller. Is that correct and, if so, how can i work 
around it?

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



More information about the llvm-dev mailing list