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