[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