[LLVMdev] Question about fastcc assumptions and seemingly superfluous %esp updates
Eli Bendersky
eliben at google.com
Thu Feb 14 14:45:55 PST 2013
Hello,
While investigating one of the existing tests
(test/CodeGen/X86/tailcallpic2.ll), I ran into IR that produces some
interesting code. The IR is very straightforward:
define protected fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) {
entry:
ret i32 %a3
}
define fastcc i32 @tailcaller(i32 %in1, i32 %in2) {
entry:
%tmp11 = tail call fastcc i32 @tailcallee( i32 %in1, i32 %in2, i32
%in1, i32 %in2)
ret i32 %tmp11
}
define i32 @foo(i32 %in1, i32 %in2) {
entry:
%q = call fastcc i32 @tailcaller(i32 %in2, i32 %in1)
%ww = sub i32 %q, 6
ret i32 %ww
}
Built with (ToT LLVM):
llc < ~/temp/z.ll -march=x86 -tailcallopt -O3
The produced code is (cleaned up a bit)
tailcallee: # @tailcallee
movl 4(%esp), %eax
ret $12
tailcaller: # @tailcaller
subl $12, %esp
movl %edx, 20(%esp)
movl %ecx, 16(%esp)
addl $12, %esp
jmp tailcallee # TAILCALL
foo: # @foo
subl $12, %esp
movl 20(%esp), %ecx
movl 16(%esp), %edx
calll tailcaller
subl $12, %esp
addl $-6, %eax
addl $12, %esp
ret
A number of questions arise here:
1) Notice that 'tailcaller' goes beyond its own stack frame when
arranging arguments for 'tailcallee'. It subs 12 from %esp, but then
writes to 20(%esp). Clearly, something in the fastcc convention allows
it to assume that stack space will be available there? What is it?
2) Note the %esp dance 'tailcaller' is doing - completely useless sub
followed by add. Does this have an inherent goal or can it be
eliminated?
3) The %esp dance of 'foo' is even stranger:
subl $12, %esp
addl $-6, %eax
addl $12, %esp
The subl and addl to %esp cancel out, and with an unrelated operation
in between. Why are they needed?
I'll be very grateful if someone could shed some light on this.
Eli
More information about the llvm-dev
mailing list