diff options
| author | Reid Kleckner <reid@kleckner.net> | 2014-04-29 23:55:41 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2014-04-29 23:55:41 +0000 |
| commit | fb693085683836d52d7edec3de7a13dd77926ea7 (patch) | |
| tree | 66b8890310487e7763fbe95d5bb1def8e75eccd2 /llvm/test/CodeGen/X86/musttail.ll | |
| parent | 7aeb9051740bef76ee3a2deb86e8444d694e935a (diff) | |
| download | bcm5719-llvm-fb693085683836d52d7edec3de7a13dd77926ea7.tar.gz bcm5719-llvm-fb693085683836d52d7edec3de7a13dd77926ea7.zip | |
Implement X86 code generation for musttail
Currently, musttail codegen is relying on sibcall optimization, and
reporting a fatal error if fails. Sibcall optimization fails when stack
arguments need to be modified, which is insufficient for musttail.
The logic for moving arguments in memory safely is already implemented
for GuaranteedTailCallOpt. This change merely arranges for musttail
calls to use it.
No functional change for GuaranteedTailCallOpt.
Reviewers: espindola
Differential Revision: http://reviews.llvm.org/D3493
llvm-svn: 207598
Diffstat (limited to 'llvm/test/CodeGen/X86/musttail.ll')
| -rw-r--r-- | llvm/test/CodeGen/X86/musttail.ll | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/llvm/test/CodeGen/X86/musttail.ll b/llvm/test/CodeGen/X86/musttail.ll index 75b217f9947..ca5d3119cf1 100644 --- a/llvm/test/CodeGen/X86/musttail.ll +++ b/llvm/test/CodeGen/X86/musttail.ll @@ -1,8 +1,6 @@ ; RUN: llc -march=x86 < %s | FileCheck %s - -; FIXME: Eliminate this tail call at -O0, since musttail is a correctness -; requirement. -; RUN: not llc -march=x86 -O0 < %s +; RUN: llc -march=x86 -O0 < %s | FileCheck %s +; RUN: llc -march=x86 -disable-tail-calls < %s | FileCheck %s declare void @t1_callee(i8*) define void @t1(i32* %a) { @@ -21,3 +19,72 @@ define i32* @t2() { %w = bitcast i8* %v to i32* ret i32* %w } + +; Complex frame layout: stack realignment with dynamic alloca. +define void @t3(i32 %n) alignstack(32) nounwind { +entry: +; CHECK: t3: +; CHECK: pushl %ebp +; CHECK: pushl %esi +; CHECK: andl $-32, %esp +; CHECK: movl %esp, %esi +; CHECK: popl %esi +; CHECK: popl %ebp +; CHECK-NEXT: jmp {{_?}}t3_callee + %a = alloca i8, i32 %n + call void @capture(i8* %a) + musttail call void @t3_callee(i32 %n) nounwind + ret void +} + +declare void @capture(i8*) +declare void @t3_callee(i32) + +; Test that we actually copy in and out stack arguments that aren't forwarded +; without modification. +define i32 @t4({}* %fn, i32 %n, i32 %r) { +; CHECK-LABEL: t4: +; CHECK: incl %[[r:.*]] +; CHECK: decl %[[n:.*]] +; CHECK: movl %[[r]], {{[0-9]+}}(%esp) +; CHECK: movl %[[n]], {{[0-9]+}}(%esp) +; CHECK: jmpl *%{{.*}} + +entry: + %r1 = add i32 %r, 1 + %n1 = sub i32 %n, 1 + %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)* + %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1) + ret i32 %r2 +} + +; Combine the complex stack frame with the parameter modification. +define i32 @t5({}* %fn, i32 %n, i32 %r) alignstack(32) { +; CHECK-LABEL: t5: +; CHECK: pushl %ebp +; CHECK: movl %esp, %ebp +; CHECK: pushl %esi +; Align the stack. +; CHECK: andl $-32, %esp +; CHECK: movl %esp, %esi +; Modify the args. +; CHECK: incl %[[r:.*]] +; CHECK: decl %[[n:.*]] +; Store them through ebp, since that's the only stable arg pointer. +; CHECK: movl %[[r]], {{[0-9]+}}(%ebp) +; CHECK: movl %[[n]], {{[0-9]+}}(%ebp) +; Epilogue. +; CHECK: leal {{[-0-9]+}}(%ebp), %esp +; CHECK: popl %esi +; CHECK: popl %ebp +; CHECK: jmpl *%{{.*}} + +entry: + %a = alloca i8, i32 %n + call void @capture(i8* %a) + %r1 = add i32 %r, 1 + %n1 = sub i32 %n, 1 + %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)* + %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1) + ret i32 %r2 +} |

