diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-01-31 23:50:57 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-01-31 23:50:57 +0000 |
commit | 8a24e835504105efdf6d882053d5da7b0e1dccd3 (patch) | |
tree | 51aae09038f8ef7f890074e673143426c48763e8 /test | |
parent | cb6684b63b3c4c5a90e194c5719bc82690180f30 (diff) | |
download | llvm-8a24e835504105efdf6d882053d5da7b0e1dccd3.tar.gz llvm-8a24e835504105efdf6d882053d5da7b0e1dccd3.tar.bz2 llvm-8a24e835504105efdf6d882053d5da7b0e1dccd3.tar.xz |
Implement inalloca codegen for x86 with the new inalloca design
Calls with inalloca are lowered by skipping all stores for arguments
passed in memory and the initial stack adjustment to allocate argument
memory.
Now the frontend is responsible for the memory layout, and the backend
doesn't have to do any work. As a result these changes are pretty
minimal.
Reviewers: echristo
Differential Revision: http://llvm-reviews.chandlerc.com/D2637
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200596 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGen/X86/inalloca-ctor.ll | 34 | ||||
-rw-r--r-- | test/CodeGen/X86/inalloca-invoke.ll | 54 | ||||
-rw-r--r-- | test/CodeGen/X86/inalloca-stdcall.ll | 26 | ||||
-rw-r--r-- | test/CodeGen/X86/inalloca.ll | 65 |
4 files changed, 179 insertions, 0 deletions
diff --git a/test/CodeGen/X86/inalloca-ctor.ll b/test/CodeGen/X86/inalloca-ctor.ll new file mode 100644 index 0000000000..f81e9675b7 --- /dev/null +++ b/test/CodeGen/X86/inalloca-ctor.ll @@ -0,0 +1,34 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s + +%Foo = type { i32, i32 } + +%frame = type { %Foo, i32, %Foo } + +declare void @f(%frame* inalloca %a) + +declare void @Foo_ctor(%Foo* %this) + +define void @g() { +entry: + %args = alloca %frame, inalloca + %c = getelementptr %frame* %args, i32 0, i32 2 +; CHECK: movl $20, %eax +; CHECK: calll __chkstk +; CHECK: movl %esp, + call void @Foo_ctor(%Foo* %c) +; CHECK: leal 12(%{{.*}}), +; CHECK: subl $4, %esp +; CHECK: calll _Foo_ctor +; CHECK: addl $4, %esp + %b = getelementptr %frame* %args, i32 0, i32 1 + store i32 42, i32* %b +; CHECK: movl $42, + %a = getelementptr %frame* %args, i32 0, i32 0 + call void @Foo_ctor(%Foo* %a) +; CHECK: subl $4, %esp +; CHECK: calll _Foo_ctor +; CHECK: addl $4, %esp + call void @f(%frame* inalloca %args) +; CHECK: calll _f + ret void +} diff --git a/test/CodeGen/X86/inalloca-invoke.ll b/test/CodeGen/X86/inalloca-invoke.ll new file mode 100644 index 0000000000..ac530ca525 --- /dev/null +++ b/test/CodeGen/X86/inalloca-invoke.ll @@ -0,0 +1,54 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s + +%Iter = type { i32, i32, i32 } + +%frame.reverse = type { %Iter, %Iter } + +declare void @llvm.stackrestore(i8*) +declare i8* @llvm.stacksave() +declare void @begin(%Iter* sret) +declare void @plus(%Iter* sret, %Iter*, i32) +declare void @reverse(%frame.reverse* inalloca align 4) + +define i32 @main() { + %temp.lvalue = alloca %Iter + br label %blah + +blah: + %inalloca.save = call i8* @llvm.stacksave() + %rev_args = alloca %frame.reverse, inalloca, align 4 + %beg = getelementptr %frame.reverse* %rev_args, i32 0, i32 0 + %end = getelementptr %frame.reverse* %rev_args, i32 0, i32 1 + +; CHECK: calll __chkstk +; CHECK: movl %[[beg:[^,]*]], %esp +; CHECK: leal 12(%[[beg]]), %[[end:[^ ]*]] + + call void @begin(%Iter* sret %temp.lvalue) +; CHECK: calll _begin + + invoke void @plus(%Iter* sret %end, %Iter* %temp.lvalue, i32 4) + to label %invoke.cont unwind label %lpad + +; Uses end as sret param. +; CHECK: movl %[[end]], (%esp) +; CHECK: calll _plus + +invoke.cont: + call void @begin(%Iter* sret %beg) + +; CHECK: movl %[[beg]], +; CHECK: calll _begin + + invoke void @reverse(%frame.reverse* inalloca align 4 %rev_args) + to label %invoke.cont5 unwind label %lpad + +invoke.cont5: ; preds = %invoke.cont + call void @llvm.stackrestore(i8* %inalloca.save) + ret i32 0 + +lpad: ; preds = %invoke.cont, %entry + %lp = landingpad { i8*, i32 } personality i8* null + cleanup + unreachable +} diff --git a/test/CodeGen/X86/inalloca-stdcall.ll b/test/CodeGen/X86/inalloca-stdcall.ll new file mode 100644 index 0000000000..93ac451a50 --- /dev/null +++ b/test/CodeGen/X86/inalloca-stdcall.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s + +%Foo = type { i32, i32 } + +declare x86_stdcallcc void @f(%Foo* inalloca %a) +declare x86_stdcallcc void @i(i32 %a) + +define void @g() { + %b = alloca %Foo, inalloca +; CHECK: movl $8, %eax +; CHECK: calll __chkstk +; CHECK: movl %[[REG:[^,]*]], %esp + %f1 = getelementptr %Foo* %b, i32 0, i32 0 + %f2 = getelementptr %Foo* %b, i32 0, i32 1 + store i32 13, i32* %f1 + store i32 42, i32* %f2 +; CHECK: movl $13, (%[[REG]]) +; CHECK: movl $42, 4(%[[REG]]) + call x86_stdcallcc void @f(%Foo* inalloca %b) +; CHECK: calll _f@8 +; CHECK-NOT: %esp +; CHECK: subl $4, %esp +; CHECK: calll _i@4 + call x86_stdcallcc void @i(i32 0) + ret void +} diff --git a/test/CodeGen/X86/inalloca.ll b/test/CodeGen/X86/inalloca.ll new file mode 100644 index 0000000000..84d694a1fb --- /dev/null +++ b/test/CodeGen/X86/inalloca.ll @@ -0,0 +1,65 @@ +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s + +%Foo = type { i32, i32 } + +declare void @f(%Foo* inalloca %b) + +define void @a() { +; CHECK-LABEL: _a: +entry: + %b = alloca %Foo, inalloca +; CHECK: movl $8, %eax +; CHECK: calll __chkstk +; CHECK: movl %[[REG:[^,]*]], %esp + %f1 = getelementptr %Foo* %b, i32 0, i32 0 + %f2 = getelementptr %Foo* %b, i32 0, i32 1 + store i32 13, i32* %f1 + store i32 42, i32* %f2 +; CHECK: movl $13, (%[[REG]]) +; CHECK: movl $42, 4(%[[REG]]) + call void @f(%Foo* inalloca %b) +; CHECK: calll _f + ret void +} + +declare void @inreg_with_inalloca(i32 inreg %a, %Foo* inalloca %b) + +define void @b() { +; CHECK-LABEL: _b: +entry: + %b = alloca %Foo, inalloca +; CHECK: movl $8, %eax +; CHECK: calll __chkstk +; CHECK: movl %[[REG:[^,]*]], %esp + %f1 = getelementptr %Foo* %b, i32 0, i32 0 + %f2 = getelementptr %Foo* %b, i32 0, i32 1 + store i32 13, i32* %f1 + store i32 42, i32* %f2 +; CHECK: movl $13, (%[[REG]]) +; CHECK: movl $42, 4(%[[REG]]) + call void @inreg_with_inalloca(i32 inreg 1, %Foo* inalloca %b) +; CHECK: movl $1, %eax +; CHECK: calll _inreg_with_inalloca + ret void +} + +declare x86_thiscallcc void @thiscall_with_inalloca(i8* %a, %Foo* inalloca %b) + +define void @c() { +; CHECK-LABEL: _c: +entry: + %b = alloca %Foo, inalloca +; CHECK: movl $8, %eax +; CHECK: calll __chkstk +; CHECK: movl %[[REG:[^,]*]], %esp + %f1 = getelementptr %Foo* %b, i32 0, i32 0 + %f2 = getelementptr %Foo* %b, i32 0, i32 1 + store i32 13, i32* %f1 + store i32 42, i32* %f2 +; CHECK: movl $13, (%[[REG]]) +; CHECK: movl $42, 4(%[[REG]]) + call x86_thiscallcc void @thiscall_with_inalloca(i8* null, %Foo* inalloca %b) +; CHECK: xorl %ecx, %ecx +; CHECK: calll _thiscall_with_inalloca + ret void +} |