[LLVMdev] bug of tail call optimization on x86 target
Katsuhiro Ueno
katsu at riec.tohoku.ac.jp
Fri Aug 2 11:26:04 PDT 2013
Dear LLVM developers,
I am a developer of SML#, an ML-style functional programming language
developed at Tohoku University. Currently we are intending to use
LLVM as the backend of our SML# compiler in our upcoming release, and
have rewritten our frontend and runtime so that they can cooperate
with LLVM. LLVM works extremely fine with our SML# compiler. We are
grateful to LLVM community for providing such an excellent software.
However, when generating x86 code with enabling tail call optimization,
unfortunately I found a bug that destroys callee-save registers.
The following is the bug I found and the attached file is the fix of
this bug.
The following is the LLVM IR code that causes the bug:
; bug.ll
target triple = "i686-apple-darwin12.4.0"
declare fastcc void @foo(i32, i32, i32, i32, i32, i32)
declare i32* @bar(i32*)
define fastcc void @hoge(i32 %b) nounwind {
%a = alloca i32
store i32 0, i32* %a
%d = tail call i32* @bar(i32* %a) nounwind
store i32 %b, i32* %d
tail call fastcc void @foo(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6) nounwind
ret void
}
LLVM produces the following x86 code against the above source:
% llc -tailcallopt -filetype=asm -disable-cfi -o - bug.ll
...
_hoge: ## @hoge
## BB#0:
subl $16, %esp
pushl %esi ;;;; this preserves %esi, but
subl $40, %esp
movl %ecx, %esi
movl $0, 40(%esp) ;;;; this overwrites preserved %esi
leal 40(%esp), %eax
movl %eax, (%esp)
calll _bar
movl %esi, (%eax)
movl 60(%esp), %eax
movl $6, 60(%esp)
movl $5, 56(%esp)
movl $4, 52(%esp)
movl $3, 48(%esp)
movl %eax, 44(%esp)
movl $1, %ecx
movl $2, %edx
addl $40, %esp
popl %esi ;;;; this always fails to restore %esi
jmp _foo ## TAILCALL
In the above code, 2nd instruction "pushl %esi" saves a callee-save
register %esi to the stack, but 5th instruction "movl $0, 40(%esp)"
overwrites the saved %esi. Eventually at the epilogue "popl %esi"
fails to restore the previous %esi.
This bug is due to wrong computation of stack object indices by the
x86 backend. The attached patch indicates the wrong points. Due to
integral promotion, explicit conversion to signed integer is needed
at those points.
Eliminating tail calls (with arbitrary number of arguments) is mandatory
for practical functional languages. I would appreciate it if this bug
would be fixed in the next release.
Best regards,
Katsuhiro Ueno
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x86-tailcallopt-fix.diff
Type: application/octet-stream
Size: 1790 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130803/b8ef92ae/attachment.obj>
More information about the llvm-dev
mailing list