1; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s 2 3declare token @llvm.call.preallocated.setup(i32) 4declare ptr @llvm.call.preallocated.arg(token, i32) 5 6%Foo = type { i32, i32 } 7 8declare void @init(ptr) 9 10 11 12declare void @foo_p(ptr preallocated(%Foo)) 13 14define void @one_preallocated() { 15; CHECK-LABEL: _one_preallocated: 16 %t = call token @llvm.call.preallocated.setup(i32 1) 17 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 18; CHECK: subl $8, %esp 19; CHECK: calll _foo_p 20 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 21 ret void 22} 23 24define void @one_preallocated_two_blocks() { 25; CHECK-LABEL: _one_preallocated_two_blocks: 26 %t = call token @llvm.call.preallocated.setup(i32 1) 27 br label %second 28second: 29 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 30; CHECK: subl $8, %esp 31; CHECK: calll _foo_p 32 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 33 ret void 34} 35 36define void @preallocated_with_store() { 37; CHECK-LABEL: _preallocated_with_store: 38; CHECK: subl $8, %esp 39 %t = call token @llvm.call.preallocated.setup(i32 1) 40; CHECK: leal (%esp), [[REGISTER:%[a-z]+]] 41 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 42 %p1 = getelementptr %Foo, ptr %a, i32 0, i32 1 43 store i32 13, ptr %a 44 store i32 42, ptr %p1 45; CHECK-DAG: movl $13, ([[REGISTER]]) 46; CHECK-DAG: movl $42, 4([[REGISTER]]) 47; CHECK-NOT: subl {{\$[0-9]+}}, %esp 48; CHECK-NOT: pushl 49; CHECK: calll _foo_p 50 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 51 ret void 52} 53 54define void @preallocated_with_init() { 55; CHECK-LABEL: _preallocated_with_init: 56; CHECK: subl $8, %esp 57 %t = call token @llvm.call.preallocated.setup(i32 1) 58; CHECK: leal (%esp), [[REGISTER:%[a-z]+]] 59 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 60; CHECK: pushl [[REGISTER]] 61; CHECK: calll _init 62 call void @init(ptr %a) 63; CHECK-NOT: subl {{\$[0-9]+}}, %esp 64; CHECK-NOT: pushl 65; CHECK: calll _foo_p 66 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 67 ret void 68} 69 70declare void @foo_p_p(ptr preallocated(%Foo), ptr preallocated(%Foo)) 71 72define void @two_preallocated() { 73; CHECK-LABEL: _two_preallocated: 74 %t = call token @llvm.call.preallocated.setup(i32 2) 75 %a1 = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 76 %a2 = call ptr @llvm.call.preallocated.arg(token %t, i32 1) preallocated(%Foo) 77; CHECK: subl $16, %esp 78; CHECK: calll _foo_p_p 79 call void @foo_p_p(ptr preallocated(%Foo) %a1, ptr preallocated(%Foo) %a2) ["preallocated"(token %t)] 80 ret void 81} 82 83declare void @foo_p_int(ptr preallocated(%Foo), i32) 84 85define void @one_preallocated_one_normal() { 86; CHECK-LABEL: _one_preallocated_one_normal: 87; CHECK: subl $12, %esp 88 %t = call token @llvm.call.preallocated.setup(i32 1) 89; CHECK: leal (%esp), [[REGISTER:%[a-z]+]] 90 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 91; CHECK: pushl [[REGISTER]] 92; CHECK: calll _init 93 call void @init(ptr %a) 94; CHECK-NOT: subl {{\$[0-9]+}}, %esp 95; CHECK-NOT: pushl 96; CHECK: movl $2, 8(%esp) 97; CHECK: calll _foo_p_int 98 call void @foo_p_int(ptr preallocated(%Foo) %a, i32 2) ["preallocated"(token %t)] 99 ret void 100} 101 102declare void @foo_ret_p(ptr sret(%Foo), ptr preallocated(%Foo)) 103 104define void @nested_with_init() { 105; CHECK-LABEL: _nested_with_init: 106 %tmp = alloca %Foo 107 108 %t1 = call token @llvm.call.preallocated.setup(i32 1) 109; CHECK: subl $12, %esp 110 %a1 = call ptr @llvm.call.preallocated.arg(token %t1, i32 0) preallocated(%Foo) 111; CHECK: leal 4(%esp), [[REGISTER1:%[a-z]+]] 112 113 %t2 = call token @llvm.call.preallocated.setup(i32 1) 114; CHECK: subl $12, %esp 115 %a2 = call ptr @llvm.call.preallocated.arg(token %t2, i32 0) preallocated(%Foo) 116; CHECK: leal 4(%esp), [[REGISTER2:%[a-z]+]] 117 118 call void @init(ptr %a2) 119; CHECK: pushl [[REGISTER2]] 120; CHECK: calll _init 121 122 call void @foo_ret_p(ptr sret(%Foo) %a1, ptr preallocated(%Foo) %a2) ["preallocated"(token %t2)] 123; CHECK-NOT: subl {{\$[0-9]+}}, %esp 124; CHECK-NOT: pushl 125; CHECK: calll _foo_ret_p 126 call void @foo_ret_p(ptr sret(%Foo) %tmp, ptr preallocated(%Foo) %a1) ["preallocated"(token %t1)] 127; CHECK-NOT: subl {{\$[0-9]+}}, %esp 128; CHECK-NOT: pushl 129; CHECK: calll _foo_ret_p 130 ret void 131} 132 133declare void @foo_inreg_p(i32 inreg, ptr preallocated(%Foo)) 134 135define void @inreg() { 136; CHECK-LABEL: _inreg: 137 %t = call token @llvm.call.preallocated.setup(i32 1) 138 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 139; CHECK: subl $8, %esp 140; CHECK: movl $9, %eax 141; CHECK: calll _foo_inreg_p 142 call void @foo_inreg_p(i32 inreg 9, ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 143 ret void 144} 145 146declare x86_thiscallcc void @foo_thiscall_p(ptr, ptr preallocated(%Foo)) 147 148define void @thiscall() { 149; CHECK-LABEL: _thiscall: 150 %t = call token @llvm.call.preallocated.setup(i32 1) 151 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 152; CHECK: subl $8, %esp 153; CHECK: xorl %ecx, %ecx 154; CHECK: calll _foo_thiscall_p 155 call x86_thiscallcc void @foo_thiscall_p(ptr null, ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 156 ret void 157} 158 159declare x86_stdcallcc void @foo_stdcall_p(ptr preallocated(%Foo)) 160declare x86_stdcallcc void @i(i32) 161 162define void @stdcall() { 163; CHECK-LABEL: _stdcall: 164 %t = call token @llvm.call.preallocated.setup(i32 1) 165 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo) 166; CHECK: subl $8, %esp 167; CHECK: calll _foo_stdcall_p@8 168 call x86_stdcallcc void @foo_stdcall_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)] 169; CHECK-NOT: %esp 170; CHECK: pushl 171; CHECK: calll _i@4 172 call x86_stdcallcc void @i(i32 0) 173 ret void 174} 175