175 lines · plain
1; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s2 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, %esp19; CHECK: calll _foo_p20 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)]21 ret void22}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 %second28second:29 %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%Foo)30; CHECK: subl $8, %esp31; CHECK: calll _foo_p32 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)]33 ret void34}35 36define void @preallocated_with_store() {37; CHECK-LABEL: _preallocated_with_store:38; CHECK: subl $8, %esp39 %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 143 store i32 13, ptr %a44 store i32 42, ptr %p145; CHECK-DAG: movl $13, ([[REGISTER]])46; CHECK-DAG: movl $42, 4([[REGISTER]])47; CHECK-NOT: subl {{\$[0-9]+}}, %esp48; CHECK-NOT: pushl49; CHECK: calll _foo_p50 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)]51 ret void52}53 54define void @preallocated_with_init() {55; CHECK-LABEL: _preallocated_with_init:56; CHECK: subl $8, %esp57 %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 _init62 call void @init(ptr %a)63; CHECK-NOT: subl {{\$[0-9]+}}, %esp64; CHECK-NOT: pushl65; CHECK: calll _foo_p66 call void @foo_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)]67 ret void68}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, %esp78; CHECK: calll _foo_p_p79 call void @foo_p_p(ptr preallocated(%Foo) %a1, ptr preallocated(%Foo) %a2) ["preallocated"(token %t)]80 ret void81}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, %esp88 %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 _init93 call void @init(ptr %a)94; CHECK-NOT: subl {{\$[0-9]+}}, %esp95; CHECK-NOT: pushl96; CHECK: movl $2, 8(%esp)97; CHECK: calll _foo_p_int98 call void @foo_p_int(ptr preallocated(%Foo) %a, i32 2) ["preallocated"(token %t)]99 ret void100}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 %Foo107 108 %t1 = call token @llvm.call.preallocated.setup(i32 1)109; CHECK: subl $12, %esp110 %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, %esp115 %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 _init121 122 call void @foo_ret_p(ptr sret(%Foo) %a1, ptr preallocated(%Foo) %a2) ["preallocated"(token %t2)]123; CHECK-NOT: subl {{\$[0-9]+}}, %esp124; CHECK-NOT: pushl125; CHECK: calll _foo_ret_p126 call void @foo_ret_p(ptr sret(%Foo) %tmp, ptr preallocated(%Foo) %a1) ["preallocated"(token %t1)]127; CHECK-NOT: subl {{\$[0-9]+}}, %esp128; CHECK-NOT: pushl129; CHECK: calll _foo_ret_p130 ret void131}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, %esp140; CHECK: movl $9, %eax141; CHECK: calll _foo_inreg_p142 call void @foo_inreg_p(i32 inreg 9, ptr preallocated(%Foo) %a) ["preallocated"(token %t)]143 ret void144}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, %esp153; CHECK: xorl %ecx, %ecx154; CHECK: calll _foo_thiscall_p155 call x86_thiscallcc void @foo_thiscall_p(ptr null, ptr preallocated(%Foo) %a) ["preallocated"(token %t)]156 ret void157}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, %esp167; CHECK: calll _foo_stdcall_p@8168 call x86_stdcallcc void @foo_stdcall_p(ptr preallocated(%Foo) %a) ["preallocated"(token %t)]169; CHECK-NOT: %esp170; CHECK: pushl171; CHECK: calll _i@4172 call x86_stdcallcc void @i(i32 0)173 ret void174}175