diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index dc73e3260891c2..1d71148d67e67f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2290,7 +2290,7 @@ void CodeGenModule::ConstructAttributeList( // Attach attributes to inalloca argument. if (IRFunctionArgs.hasInallocaArg()) { llvm::AttrBuilder Attrs; - Attrs.addAttribute(llvm::Attribute::InAlloca); + Attrs.addInAllocaAttr(FI.getArgStruct()); ArgAttrs[IRFunctionArgs.getInallocaArgNo()] = llvm::AttributeSet::get(getLLVMContext(), Attrs); } diff --git a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp index a611587b56f727..be9fc941c4809e 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp @@ -16,20 +16,20 @@ void usage() { bar(f); } -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] // WINDOWS: ret i32 %[[LOAD]] -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.sse4.2"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] // WINDOWS: %[[ADD:[0-9a-zA-Z]+]] = add nsw i32 %[[LOAD]], 1 // WINDOWS: ret i32 %[[ADD]] -// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca %0) +// WINDOWS: define dso_local i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %0) // WINDOWS: %[[O:[0-9a-zA-Z]+]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 // WINDOWS: %[[X:[0-9a-zA-Z]+]] = getelementptr inbounds %struct.Foo, %struct.Foo* %[[O]], i32 0, i32 0 // WINDOWS: %[[LOAD:[0-9a-zA-Z]+]] = load i32, i32* %[[X]] @@ -39,7 +39,7 @@ void usage() { // WINDOWS: define dso_local void @"?usage@@YAXXZ"() // WINDOWS: %[[F:[0-9a-zA-Z]+]] = alloca %struct.Foo // WINDOWS: %[[ARGMEM:[0-9a-zA-Z]+]] = alloca inalloca <{ %struct.Foo }> -// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca %[[ARGMEM]]) +// WINDOWS: %[[CALL:[0-9a-zA-Z]+]] = call i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %[[ARGMEM]]) // WINDOWS: define weak_odr dso_local i32 @"?bar@@YAHUFoo@@@Z.resolver"(<{ %struct.Foo }>* %0) // WINDOWS: %[[RET:[0-9a-zA-Z]+]] = musttail call i32 @"?bar@@YAHUFoo@@@Z.arch_ivybridge"(<{ %struct.Foo }>* %0) diff --git a/clang/test/CodeGenCXX/inalloca-overaligned.cpp b/clang/test/CodeGenCXX/inalloca-overaligned.cpp index 48a6183db8eb05..0a51875bb59223 100644 --- a/clang/test/CodeGenCXX/inalloca-overaligned.cpp +++ b/clang/test/CodeGenCXX/inalloca-overaligned.cpp @@ -28,7 +28,7 @@ int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) { } // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_overaligned@@Y{{.*}}" -// CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %0) +// CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca(<{ %struct.NonTrivial, %struct.OverAligned* }>) %0) int pass_inalloca_overaligned() { gvi32 = receive_inalloca_overaligned(NonTrivial(), OverAligned()); @@ -50,7 +50,7 @@ int pass_inalloca_overaligned() { // Store the address of an OverAligned temporary into the struct. // CHECK: getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 1 // CHECK: store %struct.OverAligned* [[TMP]], %struct.OverAligned** %{{.*}}, align 4 -// CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %argmem) +// CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca(<{ %struct.NonTrivial, %struct.OverAligned* }>) %argmem) int receive_both(Both o) { return o.x + o.y; @@ -74,7 +74,7 @@ int receive_inalloca_both(NonTrivial nt, Both o) { } // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_both@@Y{{.*}}" -// CHECK-SAME: (<{ %struct.NonTrivial, %struct.Both* }>* inalloca %0) +// CHECK-SAME: (<{ %struct.NonTrivial, %struct.Both* }>* inalloca(<{ %struct.NonTrivial, %struct.Both* }>) %0) int pass_inalloca_both() { gvi32 = receive_inalloca_both(NonTrivial(), Both()); @@ -84,7 +84,7 @@ int pass_inalloca_both() { // CHECK-LABEL: define dso_local i32 @"?pass_inalloca_both@@Y{{.*}}" // CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 8 // CHECK: call x86_thiscallcc %struct.Both* @"??0Both@@QAE@XZ"(%struct.Both* {{[^,]*}} [[TMP]]) -// CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca %argmem) +// CHECK: call i32 @"?receive_inalloca_both@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.Both* }>* inalloca(<{ %struct.NonTrivial, %struct.Both* }>) %argmem) // Here we have a type that is: // - overaligned diff --git a/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp b/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp index e7ae2cb4e70306..090953ae3b1d96 100644 --- a/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp +++ b/clang/test/CodeGenCXX/inalloca-stmtexpr.cpp @@ -46,6 +46,6 @@ out:; // CHECK: call zeroext i1 @"?cond@@YA_NXZ"() // CHECK: br i1 // CHECK: br label %out -// CHECK: call void @"?inalloca@@YAXUFoo@@0@Z"(<{ %struct.Foo, %struct.Foo }>* inalloca %{{.*}}) +// CHECK: call void @"?inalloca@@YAXUFoo@@0@Z"(<{ %struct.Foo, %struct.Foo }>* inalloca(<{ %struct.Foo, %struct.Foo }>) %{{.*}}) // CHECK: call void @llvm.stackrestore(i8* %inalloca.save) // CHECK: out: diff --git a/clang/test/CodeGenCXX/inalloca-vector.cpp b/clang/test/CodeGenCXX/inalloca-vector.cpp index bf71fac37b6a83..e052d2e6728d67 100644 --- a/clang/test/CodeGenCXX/inalloca-vector.cpp +++ b/clang/test/CodeGenCXX/inalloca-vector.cpp @@ -21,7 +21,7 @@ void receive_vec_128(NonTrivial nt, __m128 x, __m128 y, __m128 z, __m128 w, __m1 // CHECK-SAME: (<4 x float> inreg %x, // CHECK-SAME: <4 x float> inreg %y, // CHECK-SAME: <4 x float> inreg %z, -// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca %0) +// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca(<{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>) %0) void pass_vec_128() { __m128 z = {0}; @@ -45,7 +45,7 @@ void pass_vec_128() { // CHECK-SAME: (<4 x float> inreg %{{[^,]*}}, // CHECK-SAME: <4 x float> inreg %{{[^,]*}}, // CHECK-SAME: <4 x float> inreg %{{[^,]*}}, -// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca %{{[^,]*}}) +// CHECK-SAME: <{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>* inalloca(<{ %struct.NonTrivial, <4 x float>*, <4 x float>* }>) %{{[^,]*}}) // w will be passed indirectly by register, and q will be passed indirectly, but // the pointer will be in memory. @@ -58,7 +58,7 @@ void __fastcall fastcall_receive_vec(__m128 x, __m128 y, __m128 z, __m128 w, int // CHECK-SAME: <4 x float> inreg %z, // CHECK-SAME: <4 x float>* inreg %0, // CHECK-SAME: i32 inreg %edx, -// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca %1) +// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca(<{ <4 x float>*, %struct.NonTrivial }>) %1) void __vectorcall vectorcall_receive_vec(double xmm0, double xmm1, double xmm2, @@ -75,4 +75,4 @@ void __vectorcall vectorcall_receive_vec(double xmm0, double xmm1, double xmm2, // CHECK-SAME: <4 x float> inreg %z, // CHECK-SAME: <4 x float>* inreg %0, // CHECK-SAME: i32 inreg %edx, -// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca %1) +// CHECK-SAME: <{ <4 x float>*, %struct.NonTrivial }>* inalloca(<{ <4 x float>*, %struct.NonTrivial }>) %1) diff --git a/clang/test/CodeGenCXX/inheriting-constructor.cpp b/clang/test/CodeGenCXX/inheriting-constructor.cpp index 6de8e92186dd76..c338edcc76ae43 100644 --- a/clang/test/CodeGenCXX/inheriting-constructor.cpp +++ b/clang/test/CodeGenCXX/inheriting-constructor.cpp @@ -134,7 +134,7 @@ namespace inalloca_nonvirt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( @@ -170,7 +170,7 @@ namespace inalloca_nonvirt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_nonvirt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: call {{.*}} @"??0Z@@QAE@XZ"( // WIN32: call {{.*}} @"??1Q@@QAE@XZ"( @@ -216,7 +216,7 @@ namespace inalloca_virt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: br // @@ -266,7 +266,7 @@ namespace inalloca_virt { // WIN32: store i32 2, i32* %[[ARG2]] // WIN32: %[[ARG4:.*]] = getelementptr {{.*}} %[[ARGMEM]] // WIN32: store {{.*}}* %[[TMP]], {{.*}}** %[[ARG4]] - // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca %[[ARGMEM]]) + // WIN32: call {{.*}} @"??0A@inalloca_virt@@QAE@UQ@@H0$$QAU2@@Z"(%{{[^,]*}}, <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]]) // WIN32: call void @llvm.stackrestore( // WIN32: br // diff --git a/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp index 4da04a43ff6103..215a39ec7d489c 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp @@ -14,7 +14,7 @@ void foo(A a, A b, A c) { // Order of destruction should be left to right. // // X86-LABEL: define dso_local void @"?foo@@YAXUA@@00@Z" -// X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca %0) +// X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca([[argmem_ty]]) %0) // X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 0 // X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 1 // X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 2 @@ -47,7 +47,7 @@ void call_foo() { // X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* {{[^,]*}} %[[arg2]], i32 2) // X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // X86: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@H@Z"(%struct.A* {{[^,]*}} %[[arg1]], i32 1) -// X86: call void @"?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// X86: call void @"?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) // X86: call void @llvm.stackrestore // X86: ret void // diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp index 7f8730080a0990..adf3921f711569 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp @@ -19,7 +19,7 @@ A B::foo(A x) { } // CHECK-LABEL: define dso_local x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z" -// CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca(<{ %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.A*, %struct.A }>, <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -29,7 +29,7 @@ A B::bar(A x) { } // CHECK-LABEL: define dso_local %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -39,7 +39,7 @@ A B::baz(A x) { } // CHECK-LABEL: define dso_local x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %0) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %0) // CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 // CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* @@ -49,7 +49,7 @@ A B::qux(A x) { } // CHECK-LABEL: define dso_local x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (%struct.B* inreg %this, %struct.A* inreg noalias sret(%struct.A) align 4 %agg.result, <{ %struct.A }>* inalloca %0) +// CHECK: (%struct.B* inreg %this, %struct.A* inreg noalias sret(%struct.A) align 4 %agg.result, <{ %struct.A }>* inalloca(<{ %struct.A }>) %0) // CHECK: ret void int main() { @@ -61,10 +61,10 @@ int main() { } // CHECK: call x86_thiscallcc %struct.A* @"?foo@B@@QAE?AUA@@U2@@Z" -// CHECK: (%struct.B* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (%struct.B* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca(<{ %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call %struct.A* @"?bar@B@@QAA?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call x86_stdcallcc %struct.A* @"?baz@B@@QAG?AUA@@U2@@Z" -// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A*, %struct.A }>) %{{[^,]*}}) // CHECK: call x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (%struct.B* inreg %{{[^,]*}}, %struct.A* inreg sret(%struct.A) align 4 %{{.*}}, <{ %struct.A }>* inalloca %{{[^,]*}}) +// CHECK: (%struct.B* inreg %{{[^,]*}}, %struct.A* inreg sret(%struct.A) align 4 %{{.*}}, <{ %struct.A }>* inalloca(<{ %struct.A }>) %{{[^,]*}}) diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp index 917a7677c41e45..65e789ce5c637d 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp @@ -15,10 +15,10 @@ struct C : A, B { C(); virtual void foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?foo@C@byval_thunk@@W3AEXUAgg@2@@Z" -// CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca %0) +// CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca(<{ %"struct.byval_thunk::Agg" }>) %0) // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: musttail call x86_thiscallcc void @"?foo@C@byval_thunk@@UAEXUAgg@2@@Z" -// CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca %0) +// CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca(<{ %"struct.byval_thunk::Agg" }>) %0) // CHECK32-NEXT: ret void // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z" @@ -44,13 +44,13 @@ struct C : A, B { C(); virtual void __stdcall foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local x86_stdcallcc void @"?foo@C@stdcall_thunk@@W3AGXUAgg@2@@Z" -// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca(<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>) %0) // CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>, <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* %0, i32 0, i32 0 // CHECK32: load %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::C"** %[[this_slot]] // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::C"** %[[this_slot]] // CHECK32: musttail call x86_stdcallcc void @"?foo@C@stdcall_thunk@@UAGXUAgg@2@@Z" -// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca(<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>) %0) // CHECK32-NEXT: ret void // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z" @@ -76,13 +76,13 @@ struct C : A, B { C(); virtual Agg __cdecl foo(Agg x); }; C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr dso_local %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@W3AA?AUAgg@2@U32@@Z" -// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca(<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>) %0) // CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>, <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* %0, i32 0, i32 0 // CHECK32: load %"struct.sret_thunk::C"*, %"struct.sret_thunk::C"** %[[this_slot]] // CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::C"** %[[this_slot]] // CHECK32: %[[rv:[^ ]*]] = musttail call %"struct.sret_thunk::Agg"* @"?foo@C@sret_thunk@@UAA?AUAgg@2@U32@@Z" -// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0) +// CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca(<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>) %0) // CHECK32-NEXT: ret %"struct.sret_thunk::Agg"* %[[rv]] // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z" diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp index 26f6814cc1d4d9..18333f36c239d4 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp @@ -19,14 +19,14 @@ int foo(A a, ...) { return sum; } -// CHECK-LABEL: define dso_local i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca %0, ...) +// CHECK-LABEL: define dso_local i32 @"?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca(<{ %struct.A }>) %0, ...) int main() { return foo(A(3), 1, 2, 3); } // CHECK-LABEL: define dso_local i32 @main() // CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }> -// CHECK: call i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca %[[argmem]]) +// CHECK: call i32 {{.*bitcast.*}}@"?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca(<{ %struct.A, i32, i32, i32 }>) %[[argmem]]) void varargs_zero(...); void varargs_one(int, ...); @@ -41,10 +41,10 @@ void call_var_args() { } // CHECK-LABEL: define dso_local void @"?call_var_args@@YAXXZ"() -// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca %{{.*}}) -// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca(<{ %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca(<{ i32, %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca(<{ i32, i32, %struct.A }>) %{{.*}}) +// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca(<{ i32, i32, i32, %struct.A }>) %{{.*}}) // CHECK-LABEL: declare dso_local void @"?varargs_zero@@YAXZZ"(...) // CHECK-LABEL: declare dso_local void @"?varargs_one@@YAXHZZ"(i32, ...) diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp index 7e173668f26ff3..0b6b4385a35217 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -54,7 +54,7 @@ int HasDeactivatedCleanups() { // WIN32: invoke x86_thiscallcc %struct.A* @"??0A@@QAE@XZ" // WIN32: store i1 false, i1* %[[isactive]] // -// WIN32: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// WIN32: invoke i32 @"?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) // Destroy the two const ref temporaries. // WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) // WIN32: call x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) diff --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp index e0e4ba9e41b5f4..b36ea9ccd9f015 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -76,7 +76,7 @@ struct SmallWithPrivate { // WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}" // WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, -// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca) +// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca(<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor, i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>) void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g); void call_bools_and_chars() { take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false); @@ -176,7 +176,7 @@ void packed_arg(Packed s) {} // Test that dtors are invoked in the callee. void small_arg_with_dtor(SmallWithDtor s) {} -// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca %0) {{.*}} { +// WIN32: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca(<{ %struct.SmallWithDtor }>) %0) {{.*}} { // WIN32: call x86_thiscallcc void @"??1SmallWithDtor@@QAE@XZ" // WIN32: } // WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} { @@ -253,13 +253,13 @@ void eh_cleanup_arg_with_dtor() { void small_arg_with_vftable(SmallWithVftable s) {} // LINUX-LABEL: define{{.*}} void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s) -// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca %0) +// WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca(<{ %struct.SmallWithVftable }>) %0) // WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s) // WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s) void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {} // LINUX-LABEL: define{{.*}} void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s) -// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca %0) +// WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca(<{ %struct.MediumWithCopyCtor }>) %0) // WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) // WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) // WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s) @@ -363,7 +363,7 @@ struct X { }; void g(X) { } -// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca %0) {{.*}} { +// WIN32: define dso_local void @"?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca(<{ %struct.X, [3 x i8] }>) %0) {{.*}} { // WIN32: call x86_thiscallcc void @"??1X@@QAE@XZ"(%struct.X* {{.*}}) // WIN32: } void f() { @@ -398,7 +398,7 @@ void bar() { // WIN32: call void @llvm.memcpy // WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: call x86_thiscallcc %"struct.test2::NonTrivial"* @"??0NonTrivial@test2@@QAE@XZ" -// WIN32: call i32 @"?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca %argmem) +// WIN32: call i32 @"?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %argmem) // WIN32: ret void // WIN32: } @@ -414,7 +414,7 @@ struct NonTrivial { int a; }; void foo(NonTrivial a, bool b) { } -// WIN32-LABEL: define dso_local void @"?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca %0) +// WIN32-LABEL: define dso_local void @"?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>) %0) } @@ -440,7 +440,7 @@ void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); }; // WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]* // WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4 -// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// WIN32: call void @"?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca([[argmem_ty]]) %[[argmem]]) namespace pr30293 { // Virtual methods living in a secondary vtable take i8* as their 'this' @@ -462,8 +462,8 @@ void C::g() { return h(SmallWithDtor()); } // WIN32-LABEL: define dso_local x86_thiscallcc void @"?g@C@pr30293@@QAEXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this) // WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@@QAE@XZ" -// WIN32: call void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca %{{[^,)]*}}) -// WIN32: declare dso_local void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca) +// WIN32: call void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>) %{{[^,)]*}}) +// WIN32: declare dso_local void @"?h@C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>)) // WIN64-LABEL: define dso_local void @"?g@C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"* {{[^,]*}} %this) // WIN64: declare dso_local void @"?h@C@pr30293@@UEAAXUSmallWithDtor@@@Z"(i8*, i32) diff --git a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp index 6082228d36b6e9..e71d6238c53add 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp @@ -94,7 +94,7 @@ void f(C *c) { // CHECK-LABEL: define dso_local void @"?f@cdecl_inalloca@@YAXPAUC@1@@Z"(%"struct.cdecl_inalloca::C"* %c) // CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* {{[^,]*}} %{{.*}}) -// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}}) +// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>) %{{.*}}) // CHECK-LABEL: define linkonce_odr void @"??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat // CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...) %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp index 93a7d4602223d8..5cced42834e1b1 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp @@ -189,7 +189,7 @@ void C::g(NonTrivial o) { whatsthis = this; } -// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca %0) +// BITCODE-LABEL: define dso_local void @"?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca(<{ i8*, %"struct.pr30293::NonTrivial" }>) %0) // BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0 // BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"** // BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4 diff --git a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp index 256f7123ee517d..b8ebe2dd9f3999 100644 --- a/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp +++ b/clang/test/CodeGenCXX/ms-thunks-ehspec.cpp @@ -20,8 +20,8 @@ class C : A, B { }; C c; -// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f@C@@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>* inalloca(<{ %struct.NonTrivial }>) %0) // CHECK-NOT: invoke -// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0) +// CHECK: musttail call x86_thiscallcc void @"?f@C@@EAEXUNonTrivial@@@Z"(%class.C* %{{.*}}, <{ %struct.NonTrivial }>* inalloca(<{ %struct.NonTrivial }>) %0) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp b/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp index 8f413021b3d0ca..dd1c88a653343d 100644 --- a/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp +++ b/clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp @@ -13,7 +13,7 @@ void test(X x) { // CHECK-LABEL: define dso_local void @"?test@@YAXUX@@@Z" // X86: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.X }> - // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) + // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca(<{ %struct.X }>) %[[argmem]]) // X64: alloca %struct.X diff --git a/clang/test/CodeGenObjCXX/arc-indirect.mm b/clang/test/CodeGenObjCXX/arc-indirect.mm index de7566fcf987e5..40543c054ea555 100644 --- a/clang/test/CodeGenObjCXX/arc-indirect.mm +++ b/clang/test/CodeGenObjCXX/arc-indirect.mm @@ -15,8 +15,8 @@ - (void)object:(id)obj struct:(S)s { } @end -// CHECK-GNUSTEP: define internal void @_i_C__object_struct_(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca %0) -// CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca %0) +// CHECK-GNUSTEP: define internal void @_i_C__object_struct_(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>) %0) +// CHECK-DARWIN: define internal void @"\01-[C object:struct:]"(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* inalloca(<{ %0*, i8*, i8*, %struct.S, [3 x i8] }>) %0) // CHECK: %obj = getelementptr inbounds <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>, <{ %0*, i8*, i8*, %struct.S, [3 x i8] }>* %0, i32 0, i32 2 // CHECK: %[[INSTANCE:[0-9]+]] = load i8*, i8** %obj, align 4 // CHECK: call void @llvm.objc.storeStrong(i8** %obj, i8* %[[INSTANCE]]) diff --git a/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm index 6be7995f5f0190..26c13acf8959ad 100644 --- a/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm +++ b/clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm @@ -10,7 +10,7 @@ // Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d. // // CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAUobjc_object@@01@Z" -// CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca %0) +// CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca(<{ %struct.A, i8*, %struct.A, i8* }>) %0) void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) { // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* {{[^,]*}} %{{.*}}) // CHECK: call void @llvm.objc.storeStrong(i8** %{{.*}}, i8* null) diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 09a8933c110a2a..794ca1092eafa3 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1119,7 +1119,7 @@ Currently, only the following parameter attributes are defined: .. _attr_inalloca: -``inalloca`` +``inalloca()`` The ``inalloca`` argument attribute allows the caller to take the address of outgoing stack arguments. An ``inalloca`` argument must @@ -1143,6 +1143,9 @@ Currently, only the following parameter attributes are defined: must be cleared off with :ref:`llvm.stackrestore `. + The inalloca attribute requires a type argument, which must be the + same as the pointee type of the argument. + See :doc:`InAlloca` for more information on how to use this attribute. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index e35dfddbe0439a..e751ed90db2a48 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -58,7 +58,8 @@ Non-comprehensive list of changes in this release Changes to the LLVM IR ---------------------- -* ... +* The ``inalloca`` attribute now has a mandatory type field, similar + to ``byval`` and ``sret``. Changes to building LLVM diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h index e8ca8a6e81b92d..4b13e2d2a9e820 100644 --- a/llvm/include/llvm/IR/Argument.h +++ b/llvm/include/llvm/IR/Argument.h @@ -111,6 +111,9 @@ class Argument final : public Value { /// If this is a byref argument, return its type. Type *getParamByRefType() const; + /// If this is an inalloca argument, return its type. + Type *getParamInAllocaType() const; + /// Return true if this argument has the nest attribute. bool hasNestAttr() const; diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index d21d65bc4e798c..a8c4017118580c 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -114,6 +114,7 @@ class Attribute { static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty); static Attribute getWithByRefType(LLVMContext &Context, Type *Ty); static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty); + static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty); /// For a typed attribute, return the equivalent attribute with the type /// changed to \p ReplacementTy. @@ -160,7 +161,7 @@ class Attribute { bool hasAttribute(StringRef Val) const; /// Return the attribute's kind as an enum (Attribute::AttrKind). This - /// requires the attribute to be an enum or integer attribute. + /// requires the attribute to be an enum, integer, or type attribute. Attribute::AttrKind getKindAsEnum() const; /// Return the attribute's value as an integer. This requires that the @@ -325,6 +326,7 @@ class AttributeSet { Type *getStructRetType() const; Type *getByRefType() const; Type *getPreallocatedType() const; + Type *getInAllocaType() const; std::pair> getAllocSizeArgs() const; std::pair getVScaleRangeArgs() const; std::string getAsString(bool InAttrGrp = false) const; @@ -684,6 +686,9 @@ class AttributeList { /// Return the preallocated type for the specified function parameter. Type *getParamPreallocatedType(unsigned ArgNo) const; + /// Return the inalloca type for the specified function parameter. + Type *getParamInAllocaType(unsigned ArgNo) const; + /// Get the stack alignment. MaybeAlign getStackAlignment(unsigned Index) const; @@ -791,6 +796,7 @@ class AttrBuilder { Type *StructRetType = nullptr; Type *ByRefType = nullptr; Type *PreallocatedType = nullptr; + Type *InAllocaType = nullptr; public: AttrBuilder() = default; @@ -885,6 +891,9 @@ class AttrBuilder { /// Retrieve the preallocated type. Type *getPreallocatedType() const { return PreallocatedType; } + /// Retrieve the inalloca type. + Type *getInAllocaType() const { return InAllocaType; } + /// Retrieve the allocsize args, if the allocsize attribute exists. If it /// doesn't exist, pair(0, 0) is returned. std::pair> getAllocSizeArgs() const; @@ -944,6 +953,9 @@ class AttrBuilder { /// This turns a preallocated type into the form used internally in Attribute. AttrBuilder &addPreallocatedAttr(Type *Ty); + /// This turns an inalloca type into the form used internally in Attribute. + AttrBuilder &addInAllocaAttr(Type *Ty); + /// Add an allocsize attribute, using the representation returned by /// Attribute.getIntValue(). AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr); diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index 9f62723646e5bd..9684ffa0009b1e 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -80,7 +80,7 @@ def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">; def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">; /// Pass structure in an alloca. -def InAlloca : EnumAttr<"inalloca">; +def InAlloca : TypeAttr<"inalloca">; /// Source said inlining was desirable. def InlineHint : EnumAttr<"inlinehint">; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index ab20cc4b68c838..a24b12c1a470a2 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -493,6 +493,11 @@ class Function : public GlobalObject, public ilist_node { return AttributeSets.getParamStructRetType(ArgNo); } + /// Extract the inalloca type for a parameter. + Type *getParamInAllocaType(unsigned ArgNo) const { + return AttributeSets.getParamInAllocaType(ArgNo); + } + /// Extract the byref type for a parameter. Type *getParamByRefType(unsigned ArgNo) const { return AttributeSets.getParamByRefType(ArgNo); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 0372da19df55a7..ee84424b31f63b 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1736,6 +1736,13 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) { B.addPreallocatedAttr(Ty); continue; } + case lltok::kw_inalloca: { + Type *Ty; + if (parseInalloca(Ty)) + return true; + B.addInAllocaAttr(Ty); + continue; + } case lltok::kw_dereferenceable: { uint64_t Bytes; if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes)) @@ -1757,7 +1764,6 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) { B.addByRefAttr(Ty); continue; } - case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; case lltok::kw_noundef: @@ -2694,6 +2700,12 @@ bool LLParser::parsePreallocated(Type *&Result) { return parseRequiredTypeAttr(Result, lltok::kw_preallocated); } +/// parseInalloca +/// ::= inalloca() +bool LLParser::parseInalloca(Type *&Result) { + return parseRequiredTypeAttr(Result, lltok::kw_inalloca); +} + /// parseByRef /// ::= byref() bool LLParser::parseByRef(Type *&Result) { diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 1205394ff67fc3..3d9ffe6e90da93 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -331,6 +331,7 @@ namespace llvm { bool inAttrGrp, LocTy &BuiltinLoc); bool parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName); bool parsePreallocated(Type *&Result); + bool parseInalloca(Type *&Result); bool parseByRef(Type *&Result); // Module Summary Index Parsing. diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 951e32e36dd659..46db3edcc3427c 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1624,6 +1624,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addByValAttr(nullptr); else if (Kind == Attribute::StructRet) B.addStructRetAttr(nullptr); + else if (Kind == Attribute::InAlloca) + B.addInAllocaAttr(nullptr); B.addAttribute(Kind); } else if (Record[i] == 1) { // Integer attribute @@ -1675,6 +1677,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addByRefAttr(getTypeByID(Record[++i])); } else if (Kind == Attribute::Preallocated) { B.addPreallocatedAttr(getTypeByID(Record[++i])); + } else if (Kind == Attribute::InAlloca) { + B.addInAllocaAttr(HasType ? getTypeByID(Record[++i]) : nullptr); } } } @@ -3328,7 +3332,8 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef Record) { // argument's pointee type. There should be no opaque pointers where the byval // type is implicit. for (unsigned i = 0; i != Func->arg_size(); ++i) { - for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, + Attribute::InAlloca}) { if (!Func->hasParamAttribute(i, Kind)) continue; @@ -3336,10 +3341,21 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef Record) { Type *PTy = cast(FullFTy)->getParamType(i); Type *PtrEltTy = getPointerElementFlatType(PTy); - Attribute NewAttr = - Kind == Attribute::ByVal - ? Attribute::getWithByValType(Context, PtrEltTy) - : Attribute::getWithStructRetType(Context, PtrEltTy); + Attribute NewAttr; + switch (Kind) { + case Attribute::ByVal: + NewAttr = Attribute::getWithByValType(Context, PtrEltTy); + break; + case Attribute::StructRet: + NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy); + break; + case Attribute::InAlloca: + NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy); + break; + default: + llvm_unreachable("not an upgraded type attribute"); + } + Func->addParamAttr(i, NewAttr); } } @@ -3805,17 +3821,29 @@ Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) { void BitcodeReader::propagateByValSRetTypes(CallBase *CB, ArrayRef ArgsFullTys) { for (unsigned i = 0; i != CB->arg_size(); ++i) { - for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet}) { + for (Attribute::AttrKind Kind : {Attribute::ByVal, Attribute::StructRet, + Attribute::InAlloca}) { if (!CB->paramHasAttr(i, Kind)) continue; CB->removeParamAttr(i, Kind); Type *PtrEltTy = getPointerElementFlatType(ArgsFullTys[i]); - Attribute NewAttr = - Kind == Attribute::ByVal - ? Attribute::getWithByValType(Context, PtrEltTy) - : Attribute::getWithStructRetType(Context, PtrEltTy); + Attribute NewAttr; + switch (Kind) { + case Attribute::ByVal: + NewAttr = Attribute::getWithByValType(Context, PtrEltTy); + break; + case Attribute::StructRet: + NewAttr = Attribute::getWithStructRetType(Context, PtrEltTy); + break; + case Attribute::InAlloca: + NewAttr = Attribute::getWithInAllocaType(Context, PtrEltTy); + break; + default: + llvm_unreachable("not an upgraded type attribute"); + } + CB->addParamAttr(i, NewAttr); } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 09f21d26971d44..91f8939a8ffa0d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -4413,20 +4413,18 @@ void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) { return; } - assert((Attr.hasAttribute(Attribute::ByVal) || - Attr.hasAttribute(Attribute::StructRet) || - Attr.hasAttribute(Attribute::ByRef) || - Attr.hasAttribute(Attribute::Preallocated)) && - "unexpected type attr"); - if (Attr.hasAttribute(Attribute::ByVal)) { Out << "byval"; } else if (Attr.hasAttribute(Attribute::StructRet)) { Out << "sret"; } else if (Attr.hasAttribute(Attribute::ByRef)) { Out << "byref"; - } else { + } else if (Attr.hasAttribute(Attribute::Preallocated)) { Out << "preallocated"; + } else if (Attr.hasAttribute(Attribute::InAlloca)) { + Out << "inalloca"; + } else { + llvm_unreachable("unexpected type attr"); } if (Type *Ty = Attr.getValueAsType()) { diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index 53c2228658b54f..60e2ec2c21be39 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -258,6 +258,7 @@ class AttributeSetNode final Type *getStructRetType() const; Type *getByRefType() const; Type *getPreallocatedType() const; + Type *getInAllocaType() const; using iterator = const Attribute *; diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 831186a49fca75..c174e4f9319692 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -195,6 +195,10 @@ Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) { return get(Context, Preallocated, Ty); } +Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) { + return get(Context, InAlloca, Ty); +} + Attribute Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional &NumElemsArg) { @@ -377,8 +381,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "inaccessiblememonly"; if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly)) return "inaccessiblemem_or_argmemonly"; - if (hasAttribute(Attribute::InAlloca)) - return "inalloca"; if (hasAttribute(Attribute::InlineHint)) return "inlinehint"; if (hasAttribute(Attribute::InReg)) @@ -484,24 +486,30 @@ std::string Attribute::getAsString(bool InAttrGrp) const { if (hasAttribute(Attribute::MustProgress)) return "mustprogress"; - const bool IsByVal = hasAttribute(Attribute::ByVal); - if (IsByVal || hasAttribute(Attribute::StructRet)) { + if (isTypeAttribute()) { std::string Result; - Result += IsByVal ? "byval" : "sret"; - if (Type *Ty = getValueAsType()) { - raw_string_ostream OS(Result); - Result += '('; - Ty->print(OS, false, true); - OS.flush(); - Result += ')'; + raw_string_ostream OS(Result); + + switch (getKindAsEnum()) { + case Attribute::ByVal: + Result += "byval"; + break; + case Attribute::StructRet: + Result += "sret"; + break; + case Attribute::ByRef: + Result += "byref"; + break; + case Attribute::Preallocated: + Result += "preallocated"; + break; + case Attribute::InAlloca: + Result += "inalloca"; + break; + default: + llvm_unreachable("unhandled type attribute"); } - return Result; - } - const bool IsByRef = hasAttribute(Attribute::ByRef); - if (IsByRef || hasAttribute(Attribute::Preallocated)) { - std::string Result = IsByRef ? "byref" : "preallocated"; - raw_string_ostream OS(Result); Result += '('; getValueAsType()->print(OS, false, true); OS.flush(); @@ -809,6 +817,10 @@ Type *AttributeSet::getPreallocatedType() const { return SetNode ? SetNode->getPreallocatedType() : nullptr; } +Type *AttributeSet::getInAllocaType() const { + return SetNode ? SetNode->getInAllocaType() : nullptr; +} + std::pair> AttributeSet::getAllocSizeArgs() const { return SetNode ? SetNode->getAllocSizeArgs() : std::pair>(0, 0); @@ -915,6 +927,9 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { case Attribute::Preallocated: Attr = Attribute::getWithPreallocatedType(C, B.getPreallocatedType()); break; + case Attribute::InAlloca: + Attr = Attribute::getWithInAllocaType(C, B.getInAllocaType()); + break; case Attribute::Alignment: assert(B.getAlignment() && "Alignment must be set"); Attr = Attribute::getWithAlignment(C, *B.getAlignment()); @@ -1021,6 +1036,12 @@ Type *AttributeSetNode::getPreallocatedType() const { return nullptr; } +Type *AttributeSetNode::getInAllocaType() const { + if (auto A = findEnumAttribute(Attribute::InAlloca)) + return A->getValueAsType(); + return nullptr; +} + uint64_t AttributeSetNode::getDereferenceableBytes() const { if (auto A = findEnumAttribute(Attribute::Dereferenceable)) return A->getDereferenceableBytes(); @@ -1578,6 +1599,10 @@ Type *AttributeList::getParamPreallocatedType(unsigned Index) const { return getAttributes(Index + FirstArgIndex).getPreallocatedType(); } +Type *AttributeList::getParamInAllocaType(unsigned Index) const { + return getAttributes(Index + FirstArgIndex).getInAllocaType(); +} + MaybeAlign AttributeList::getStackAlignment(unsigned Index) const { return getAttributes(Index).getStackAlignment(); } @@ -1699,6 +1724,9 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { AllocSizeArgs = Attr.getValueAsInt(); else if (Kind == Attribute::VScaleRange) VScaleRangeArgs = Attr.getValueAsInt(); + else if (Kind == Attribute::InAlloca) + InAllocaType = Attr.getValueAsType(); + return *this; } @@ -1723,6 +1751,8 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { ByRefType = nullptr; else if (Val == Attribute::Preallocated) PreallocatedType = nullptr; + else if (Val == Attribute::InAlloca) + InAllocaType = nullptr; else if (Val == Attribute::Dereferenceable) DerefBytes = 0; else if (Val == Attribute::DereferenceableOrNull) @@ -1852,6 +1882,12 @@ AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) { return *this; } +AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) { + Attrs[Attribute::InAlloca] = true; + InAllocaType = Ty; + return *this; +} + AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { // FIXME: What if both have alignments, but they don't match?! if (!Alignment) @@ -1881,6 +1917,9 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { if (!PreallocatedType) PreallocatedType = B.PreallocatedType; + if (!InAllocaType) + InAllocaType = B.InAllocaType; + if (!VScaleRangeArgs) VScaleRangeArgs = B.VScaleRangeArgs; @@ -1921,6 +1960,9 @@ AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { if (B.PreallocatedType) PreallocatedType = nullptr; + if (B.InAllocaType) + InAllocaType = nullptr; + if (B.VScaleRangeArgs) VScaleRangeArgs = 0; @@ -1985,6 +2027,7 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const { DerefBytes == B.DerefBytes && ByValType == B.ByValType && StructRetType == B.StructRetType && ByRefType == B.ByRefType && PreallocatedType == B.PreallocatedType && + InAllocaType == B.InAllocaType && VScaleRangeArgs == B.VScaleRangeArgs; } @@ -2014,6 +2057,7 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) { .addAttribute(Attribute::ReadOnly) .addAttribute(Attribute::InAlloca) .addPreallocatedAttr(Ty) + .addInAllocaAttr(Ty) .addByValAttr(Ty) .addStructRetAttr(Ty) .addByRefAttr(Ty); diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 7389ec6858ed50..1001607403d2ef 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -162,6 +162,8 @@ static Type *getMemoryParamAllocType(AttributeSet ParamAttrs, Type *ArgTy) { return ByRefTy; if (Type *PreAllocTy = ParamAttrs.getPreallocatedType()) return PreAllocTy; + if (Type *InAllocaTy = ParamAttrs.getInAllocaType()) + return InAllocaTy; // FIXME: sret and inalloca always depends on pointee element type. It's also // possible for byval to miss it. @@ -213,6 +215,11 @@ Type *Argument::getParamByRefType() const { return getParent()->getParamByRefType(getArgNo()); } +Type *Argument::getParamInAllocaType() const { + assert(getType()->isPointerTy() && "Only pointers have inalloca types"); + return getParent()->getParamInAllocaType(getArgNo()); +} + uint64_t Argument::getDereferenceableBytes() const { assert(getType()->isPointerTy() && "Only pointers have dereferenceable bytes"); diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 0a96b29407bb55..b6952f70304162 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1813,6 +1813,11 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty, Assert(Attrs.getPreallocatedType() == PTy->getElementType(), "Attribute 'preallocated' type does not match parameter!", V); } + + if (Attrs.hasAttribute(Attribute::InAlloca)) { + Assert(Attrs.getInAllocaType() == PTy->getElementType(), + "Attribute 'inalloca' type does not match parameter!", V); + } } else { Assert(!Attrs.hasAttribute(Attribute::ByVal), "Attribute 'byval' only applies to parameters with pointer type!", diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index f9b9b94911a717..1433d074595bac 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -647,7 +647,8 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { AttributeList IRLinker::mapAttributeTypes(LLVMContext &C, AttributeList Attrs) { for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) { for (Attribute::AttrKind TypedAttr : - {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) { + {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef, + Attribute::InAlloca}) { if (Attrs.hasAttribute(i, TypedAttr)) { if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) { Attrs = Attrs.replaceAttributeType(C, i, TypedAttr, TypeMap.get(Ty)); diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index ae839bd3a3d365..d8751888ad21eb 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -945,7 +945,8 @@ void Mapper::remapInstruction(Instruction *I) { AttributeList Attrs = CB->getAttributes(); for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) { for (Attribute::AttrKind TypedAttr : - {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) { + {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef, + Attribute::InAlloca}) { if (Type *Ty = Attrs.getAttribute(i, TypedAttr).getValueAsType()) { Attrs = Attrs.replaceAttributeType(C, i, TypedAttr, TypeMapper->remapType(Ty)); diff --git a/llvm/test/Assembler/inalloca-parse-error0.ll b/llvm/test/Assembler/inalloca-parse-error0.ll new file mode 100644 index 00000000000000..24fe82baaeff2c --- /dev/null +++ b/llvm/test/Assembler/inalloca-parse-error0.ll @@ -0,0 +1,6 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +; CHECK: :[[@LINE+1]]:40: error: expected '('{{$}} +define void @test_inalloca(i8* inalloca) { + ret void +} diff --git a/llvm/test/Assembler/invalid-immarg.ll b/llvm/test/Assembler/invalid-immarg.ll index f2203d2609fd3f..023a528ea7bb07 100644 --- a/llvm/test/Assembler/invalid-immarg.ll +++ b/llvm/test/Assembler/invalid-immarg.ll @@ -4,7 +4,7 @@ declare void @llvm.immarg.byval(i32* byval(i32) immarg) ; CHECK: Attribute 'immarg' is incompatible with other attributes -declare void @llvm.immarg.inalloca(i32* inalloca immarg) +declare void @llvm.immarg.inalloca(i32* inalloca(i32) immarg) ; CHECK: Attribute 'immarg' is incompatible with other attributes declare void @llvm.immarg.inreg(i32 inreg immarg) diff --git a/llvm/test/Bitcode/Inputs/inalloca-upgrade.bc b/llvm/test/Bitcode/Inputs/inalloca-upgrade.bc new file mode 100644 index 00000000000000..51012caacddcea Binary files /dev/null and b/llvm/test/Bitcode/Inputs/inalloca-upgrade.bc differ diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index b8b41e5c4e5c68..936a2953901a98 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -214,8 +214,8 @@ define void @f35() optnone noinline ret void; } -define void @f36(i8* inalloca %0) { -; CHECK: define void @f36(i8* inalloca %0) { +define void @f36(i8* inalloca(i8) %0) { +; CHECK: define void @f36(i8* inalloca(i8) %0) { ret void } diff --git a/llvm/test/Bitcode/compatibility-3.6.ll b/llvm/test/Bitcode/compatibility-3.6.ll index 05e6b71f147786..882f0416e89369 100644 --- a/llvm/test/Bitcode/compatibility-3.6.ll +++ b/llvm/test/Bitcode/compatibility-3.6.ll @@ -406,7 +406,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -993,7 +993,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-3.7.ll b/llvm/test/Bitcode/compatibility-3.7.ll index b31509ec0a8673..65dae1b6a75536 100644 --- a/llvm/test/Bitcode/compatibility-3.7.ll +++ b/llvm/test/Bitcode/compatibility-3.7.ll @@ -412,7 +412,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1034,7 +1034,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-3.8.ll b/llvm/test/Bitcode/compatibility-3.8.ll index 72b01f6a1d98b3..51b4740ea42e3c 100644 --- a/llvm/test/Bitcode/compatibility-3.8.ll +++ b/llvm/test/Bitcode/compatibility-3.8.ll @@ -437,7 +437,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1182,7 +1182,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-3.9.ll b/llvm/test/Bitcode/compatibility-3.9.ll index f5b409ab257890..e203e5144c28ce 100644 --- a/llvm/test/Bitcode/compatibility-3.9.ll +++ b/llvm/test/Bitcode/compatibility-3.9.ll @@ -506,7 +506,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1253,7 +1253,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-4.0.ll b/llvm/test/Bitcode/compatibility-4.0.ll index c7874106d2b991..b0b65fe75da81d 100644 --- a/llvm/test/Bitcode/compatibility-4.0.ll +++ b/llvm/test/Bitcode/compatibility-4.0.ll @@ -506,7 +506,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1253,7 +1253,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-5.0.ll b/llvm/test/Bitcode/compatibility-5.0.ll index e63ff3a7cc066c..93916d9ff89023 100644 --- a/llvm/test/Bitcode/compatibility-5.0.ll +++ b/llvm/test/Bitcode/compatibility-5.0.ll @@ -510,7 +510,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1265,7 +1265,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility-6.0.ll b/llvm/test/Bitcode/compatibility-6.0.ll index 980dd92563c7ed..bd5dfd3457928f 100644 --- a/llvm/test/Bitcode/compatibility-6.0.ll +++ b/llvm/test/Bitcode/compatibility-6.0.ll @@ -517,7 +517,7 @@ declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1276,7 +1276,7 @@ exit: define void @instructions.call_musttail(i8* inalloca %val) { musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll index 34c5cfd4120461..95bb2639e09bcd 100644 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -532,8 +532,8 @@ declare void @f.param.inreg(i8 inreg) ; CHECK: declare void @f.param.inreg(i8 inreg) declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) ; CHECK: declare void @f.param.byval({ i8, i8 }* byval({ i8, i8 })) -declare void @f.param.inalloca(i8* inalloca) -; CHECK: declare void @f.param.inalloca(i8* inalloca) +declare void @f.param.inalloca(i8* inalloca(i8)) +; CHECK: declare void @f.param.inalloca(i8* inalloca(i8)) declare void @f.param.sret(i8* sret(i8)) ; CHECK: declare void @f.param.sret(i8* sret(i8)) declare void @f.param.noalias(i8* noalias) @@ -1520,9 +1520,9 @@ exit: ret void } -define void @instructions.call_musttail(i8* inalloca %val) { - musttail call void @f.param.inalloca(i8* inalloca %val) - ; CHECK: musttail call void @f.param.inalloca(i8* inalloca %val) +define void @instructions.call_musttail(i8* inalloca(i8) %val) { + musttail call void @f.param.inalloca(i8* inalloca(i8) %val) + ; CHECK: musttail call void @f.param.inalloca(i8* inalloca(i8) %val) ret void } diff --git a/llvm/test/Bitcode/inalloca-upgrade.test b/llvm/test/Bitcode/inalloca-upgrade.test new file mode 100644 index 00000000000000..20d41365b3601c --- /dev/null +++ b/llvm/test/Bitcode/inalloca-upgrade.test @@ -0,0 +1,7 @@ +RUN: llvm-dis %p/Inputs/inalloca-upgrade.bc -o - | FileCheck %s + +Make sure we upgrade old-style IntAttribute inalloca records to a +fully typed version correctly. + +CHECK: call void @bar({ i32*, i8 }* inalloca({ i32*, i8 }) %ptr) +CHECK: invoke void @bar({ i32*, i8 }* inalloca({ i32*, i8 }) %ptr) diff --git a/llvm/test/Bitcode/inalloca.ll b/llvm/test/Bitcode/inalloca.ll index 84abe176d65e99..3b56f571b15b25 100644 --- a/llvm/test/Bitcode/inalloca.ll +++ b/llvm/test/Bitcode/inalloca.ll @@ -3,17 +3,17 @@ ; inalloca should roundtrip. -define void @foo(i32* inalloca %args) { +define void @foo(i32* inalloca(i32) %args) { ret void } -; CHECK-LABEL: define void @foo(i32* inalloca %args) +; CHECK-LABEL: define void @foo(i32* inalloca(i32) %args) define void @bar() { ; Use the maximum alignment, since we stuff our bit with alignment. %args = alloca inalloca i32, align 536870912 - call void @foo(i32* inalloca %args) + call void @foo(i32* inalloca(i32) %args) ret void } ; CHECK-LABEL: define void @bar() { ; CHECK: %args = alloca inalloca i32, align 536870912 -; CHECK: call void @foo(i32* inalloca %args) +; CHECK: call void @foo(i32* inalloca(i32) %args) diff --git a/llvm/test/CodeGen/X86/arg-copy-elide.ll b/llvm/test/CodeGen/X86/arg-copy-elide.ll index f8761bd0ac9b45..36510e09beba29 100644 --- a/llvm/test/CodeGen/X86/arg-copy-elide.ll +++ b/llvm/test/CodeGen/X86/arg-copy-elide.ll @@ -232,7 +232,7 @@ entry: ; CHECK: retl -define void @avoid_inalloca(i32* inalloca %x) { +define void @avoid_inalloca(i32* inalloca(i32) %x) { entry: %x.p.p = alloca i32* store i32* %x, i32** %x.p.p diff --git a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll index 4e28b5f1a3e928..927956d4412957 100644 --- a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll +++ b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll @@ -25,7 +25,7 @@ entry: to label %invoke.cont unwind label %ehcleanup invoke.cont: ; preds = %entry - call void @takes_two(<{ %struct.A, %struct.A }>* inalloca nonnull %argmem) + call void @takes_two(<{ %struct.A, %struct.A }>* inalloca(<{ %struct.A, %struct.A }>) nonnull %argmem) ret void ehcleanup: ; preds = %entry @@ -57,7 +57,7 @@ ehcleanup: ; preds = %entry ; CHECK: addl $8, %esp ; CHECK: retl -declare void @takes_two(<{ %struct.A, %struct.A }>* inalloca) #0 +declare void @takes_two(<{ %struct.A, %struct.A }>* inalloca(<{ %struct.A, %struct.A }>)) #0 declare x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* returned) #0 diff --git a/llvm/test/CodeGen/X86/inalloca-ctor.ll b/llvm/test/CodeGen/X86/inalloca-ctor.ll index f13d537d90b8f1..740c61a3e7d3ae 100644 --- a/llvm/test/CodeGen/X86/inalloca-ctor.ll +++ b/llvm/test/CodeGen/X86/inalloca-ctor.ll @@ -4,7 +4,7 @@ %frame = type { %Foo, i32, %Foo } -declare void @f(%frame* inalloca %a) +declare void @f(%frame* inalloca(%frame) %a) declare void @Foo_ctor(%Foo* %this) @@ -28,7 +28,7 @@ entry: ; CHECK-NEXT: pushl ; CHECK-NEXT: calll _Foo_ctor ; CHECK: addl $4, %esp - call void @f(%frame* inalloca %args) + call void @f(%frame* inalloca(%frame) %args) ; CHECK: calll _f ret void } diff --git a/llvm/test/CodeGen/X86/inalloca-invoke.ll b/llvm/test/CodeGen/X86/inalloca-invoke.ll index 4623c58210a3e3..39a9ac5751f299 100644 --- a/llvm/test/CodeGen/X86/inalloca-invoke.ll +++ b/llvm/test/CodeGen/X86/inalloca-invoke.ll @@ -9,7 +9,7 @@ declare void @llvm.stackrestore(i8*) declare i8* @llvm.stacksave() declare void @begin(%Iter* sret(%Iter)) declare void @plus(%Iter* sret(%Iter), %Iter*, i32) -declare void @reverse(%frame.reverse* inalloca align 4) +declare void @reverse(%frame.reverse* inalloca(%frame.reverse) align 4) define i32 @main() personality i32 (...)* @pers { %temp.lvalue = alloca %Iter @@ -42,7 +42,7 @@ invoke.cont: ; CHECK: pushl %[[beg]] ; CHECK: calll _begin - invoke void @reverse(%frame.reverse* inalloca align 4 %rev_args) + invoke void @reverse(%frame.reverse* inalloca(%frame.reverse) align 4 %rev_args) to label %invoke.cont5 unwind label %lpad invoke.cont5: ; preds = %invoke.cont diff --git a/llvm/test/CodeGen/X86/inalloca-regparm.ll b/llvm/test/CodeGen/X86/inalloca-regparm.ll index d379333a962f60..24a7d17d4b4aae 100644 --- a/llvm/test/CodeGen/X86/inalloca-regparm.ll +++ b/llvm/test/CodeGen/X86/inalloca-regparm.ll @@ -4,11 +4,11 @@ ; This will compile successfully on x86 but not x86_64, because %b will become a ; register parameter. -declare x86_thiscallcc i32 @f(i32 %a, i32* inalloca %b) +declare x86_thiscallcc i32 @f(i32 %a, i32* inalloca(i32) %b) define void @g() { %b = alloca inalloca i32 store i32 2, i32* %b - call x86_thiscallcc i32 @f(i32 0, i32* inalloca %b) + call x86_thiscallcc i32 @f(i32 0, i32* inalloca(i32) %b) ret void } diff --git a/llvm/test/CodeGen/X86/inalloca-stdcall.ll b/llvm/test/CodeGen/X86/inalloca-stdcall.ll index 69d94d8bfa7448..e0a292b866f2cd 100644 --- a/llvm/test/CodeGen/X86/inalloca-stdcall.ll +++ b/llvm/test/CodeGen/X86/inalloca-stdcall.ll @@ -2,7 +2,7 @@ %Foo = type { i32, i32 } -declare x86_stdcallcc void @f(%Foo* inalloca %a) +declare x86_stdcallcc void @f(%Foo* inalloca(%Foo) %a) declare x86_stdcallcc void @i(i32 %a) define void @g() { @@ -17,7 +17,7 @@ define void @g() { ; CHECK: movl %esp, %eax ; CHECK: movl $13, (%eax) ; CHECK: movl $42, 4(%eax) - call x86_stdcallcc void @f(%Foo* inalloca %b) + call x86_stdcallcc void @f(%Foo* inalloca(%Foo) %b) ; CHECK: calll _f@8 ; CHECK-NOT: %esp ; CHECK: pushl diff --git a/llvm/test/CodeGen/X86/inalloca.ll b/llvm/test/CodeGen/X86/inalloca.ll index 134de2f58ddad8..ed85c79f6d44cd 100644 --- a/llvm/test/CodeGen/X86/inalloca.ll +++ b/llvm/test/CodeGen/X86/inalloca.ll @@ -2,7 +2,7 @@ %Foo = type { i32, i32 } -declare void @f(%Foo* inalloca %b) +declare void @f(%Foo* inalloca(%Foo) %b) define void @a() { ; CHECK-LABEL: _a: @@ -17,12 +17,12 @@ entry: ; CHECK: movl %esp, %eax ; CHECK: movl $13, (%eax) ; CHECK: movl $42, 4(%eax) - call void @f(%Foo* inalloca %b) + call void @f(%Foo* inalloca(%Foo) %b) ; CHECK: calll _f ret void } -declare void @inreg_with_inalloca(i32 inreg %a, %Foo* inalloca %b) +declare void @inreg_with_inalloca(i32 inreg %a, %Foo* inalloca(%Foo) %b) define void @b() { ; CHECK-LABEL: _b: @@ -37,13 +37,13 @@ entry: ; CHECK: movl %esp, %eax ; CHECK: movl $13, (%eax) ; CHECK: movl $42, 4(%eax) - call void @inreg_with_inalloca(i32 inreg 1, %Foo* inalloca %b) + call void @inreg_with_inalloca(i32 inreg 1, %Foo* inalloca(%Foo) %b) ; CHECK: movl $1, %eax ; CHECK: calll _inreg_with_inalloca ret void } -declare x86_thiscallcc void @thiscall_with_inalloca(i8* %a, %Foo* inalloca %b) +declare x86_thiscallcc void @thiscall_with_inalloca(i8* %a, %Foo* inalloca(%Foo) %b) define void @c() { ; CHECK-LABEL: _c: @@ -58,7 +58,7 @@ entry: ; CHECK: movl %esp, %eax ; CHECK-DAG: movl $13, (%eax) ; CHECK-DAG: movl $42, 4(%eax) - call x86_thiscallcc void @thiscall_with_inalloca(i8* null, %Foo* inalloca %b) + call x86_thiscallcc void @thiscall_with_inalloca(i8* null, %Foo* inalloca(%Foo) %b) ; CHECK-DAG: xorl %ecx, %ecx ; CHECK: calll _thiscall_with_inalloca ret void diff --git a/llvm/test/CodeGen/X86/movtopush.ll b/llvm/test/CodeGen/X86/movtopush.ll index fa200c2253b94d..33e11235fe83b8 100644 --- a/llvm/test/CodeGen/X86/movtopush.ll +++ b/llvm/test/CodeGen/X86/movtopush.ll @@ -15,7 +15,7 @@ declare void @eightparams(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g declare void @eightparams16(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f, i16 %g, i16 %h) declare void @eightparams64(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h) declare void @struct(%struct.s* byval(%struct.s) %a, i32 %b, i32 %c, i32 %d) -declare void @inalloca(<{ %struct.s }>* inalloca) +declare void @inalloca(<{ %struct.s }>* inalloca(<{ %struct.s }>)) declare i8* @llvm.stacksave() declare void @llvm.stackrestore(i8*) diff --git a/llvm/test/CodeGen/X86/musttail-inalloca.ll b/llvm/test/CodeGen/X86/musttail-inalloca.ll index c0e571a7213b4e..f3e27fac3a9d82 100644 --- a/llvm/test/CodeGen/X86/musttail-inalloca.ll +++ b/llvm/test/CodeGen/X86/musttail-inalloca.ll @@ -11,10 +11,10 @@ target triple = "i386-pc-windows-msvc19.16.0" ; 20 bytes of memory. %struct.Args = type { i32, i32, i32, i32, i32 } -declare dso_local x86_thiscallcc void @methodWithVtorDisp(i8* nocapture readonly, <{ %struct.Args }>* inalloca) +declare dso_local x86_thiscallcc void @methodWithVtorDisp(i8* nocapture readonly, <{ %struct.Args }>* inalloca(<{ %struct.Args }>)) ; Function Attrs: nounwind optsize -define dso_local x86_thiscallcc void @methodWithVtorDisp_thunk(i8* %0, <{ %struct.Args }>* inalloca %1) #0 { +define dso_local x86_thiscallcc void @methodWithVtorDisp_thunk(i8* %0, <{ %struct.Args }>* inalloca(<{ %struct.Args }>) %1) #0 { ; CHECK-LABEL: methodWithVtorDisp_thunk: ; CHECK: # %bb.0: ; CHECK-NEXT: pushl %esi @@ -34,7 +34,7 @@ define dso_local x86_thiscallcc void @methodWithVtorDisp_thunk(i8* %0, <{ %struc %7 = getelementptr i8, i8* %0, i32 %6 %8 = call i8* @llvm.returnaddress(i32 0) call void @__cyg_profile_func_exit(i8* bitcast (void (i8*, <{ %struct.Args }>*)* @methodWithVtorDisp_thunk to i8*), i8* %8) - musttail call x86_thiscallcc void @methodWithVtorDisp(i8* %7, <{ %struct.Args }>* inalloca nonnull %1) + musttail call x86_thiscallcc void @methodWithVtorDisp(i8* %7, <{ %struct.Args }>* inalloca(<{ %struct.Args }>) nonnull %1) ret void } diff --git a/llvm/test/CodeGen/X86/musttail-indirect.ll b/llvm/test/CodeGen/X86/musttail-indirect.ll index f30d775a343b38..cb7a31433e2758 100644 --- a/llvm/test/CodeGen/X86/musttail-indirect.ll +++ b/llvm/test/CodeGen/X86/musttail-indirect.ll @@ -42,13 +42,13 @@ entry: ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}} ; CHECK: jmpl ; CHECK-NOT: ret -define x86_thiscallcc i32 @g_thunk(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca) { +define x86_thiscallcc i32 @g_thunk(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A, i32, %struct.A }>)) { entry: %1 = bitcast %struct.B* %this to i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*** %vtable = load i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)**, i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*** %1 %vfn = getelementptr inbounds i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*, i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)** %vtable, i32 1 %2 = load i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*, i32 (%struct.B*, <{ %struct.A, i32, %struct.A }>*)** %vfn - %3 = musttail call x86_thiscallcc i32 %2(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca %0) + %3 = musttail call x86_thiscallcc i32 %2(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A, i32, %struct.A }>) %0) ret i32 %3 } @@ -71,13 +71,13 @@ entry: ; CHECK: jmpl ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}} ; CHECK-NOT: ret -define x86_thiscallcc void @h_thunk(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca) { +define x86_thiscallcc void @h_thunk(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A, i32, %struct.A }>)) { entry: %1 = bitcast %struct.B* %this to void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*** %vtable = load void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)**, void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*** %1 %vfn = getelementptr inbounds void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*, void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)** %vtable, i32 2 %2 = load void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)*, void (%struct.B*, <{ %struct.A, i32, %struct.A }>*)** %vfn - musttail call x86_thiscallcc void %2(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca %0) + musttail call x86_thiscallcc void %2(%struct.B* %this, <{ %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A, i32, %struct.A }>) %0) ret void } @@ -99,13 +99,13 @@ entry: ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}} ; CHECK: jmpl ; CHECK-NOT: ret -define x86_thiscallcc %struct.A* @i_thunk(%struct.B* %this, <{ %struct.A*, %struct.A, i32, %struct.A }>* inalloca) { +define x86_thiscallcc %struct.A* @i_thunk(%struct.B* %this, <{ %struct.A*, %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A*, %struct.A, i32, %struct.A }>)) { entry: %1 = bitcast %struct.B* %this to %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)*** %vtable = load %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)**, %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)*** %1 %vfn = getelementptr inbounds %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)*, %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)** %vtable, i32 3 %2 = load %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)*, %struct.A* (%struct.B*, <{ %struct.A*, %struct.A, i32, %struct.A }>*)** %vfn - %3 = musttail call x86_thiscallcc %struct.A* %2(%struct.B* %this, <{ %struct.A*, %struct.A, i32, %struct.A }>* inalloca %0) + %3 = musttail call x86_thiscallcc %struct.A* %2(%struct.B* %this, <{ %struct.A*, %struct.A, i32, %struct.A }>* inalloca(<{ %struct.A*, %struct.A, i32, %struct.A }>) %0) ret %struct.A* %3 } @@ -140,7 +140,7 @@ entry: ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}} ; CHECK: jmpl ; CHECK-NOT: ret -define x86_stdcallcc i32 @stdcall_thunk(<{ %struct.B*, %struct.A }>* inalloca) { +define x86_stdcallcc i32 @stdcall_thunk(<{ %struct.B*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A }>)) { entry: %this_ptr = getelementptr inbounds <{ %struct.B*, %struct.A }>, <{ %struct.B*, %struct.A }>* %0, i32 0, i32 0 %this = load %struct.B*, %struct.B** %this_ptr @@ -148,7 +148,7 @@ entry: %vtable = load i32 (<{ %struct.B*, %struct.A }>*)**, i32 (<{ %struct.B*, %struct.A }>*)*** %1 %vfn = getelementptr inbounds i32 (<{ %struct.B*, %struct.A }>*)*, i32 (<{ %struct.B*, %struct.A }>*)** %vtable, i32 1 %2 = load i32 (<{ %struct.B*, %struct.A }>*)*, i32 (<{ %struct.B*, %struct.A }>*)** %vfn - %3 = musttail call x86_stdcallcc i32 %2(<{ %struct.B*, %struct.A }>* inalloca %0) + %3 = musttail call x86_stdcallcc i32 %2(<{ %struct.B*, %struct.A }>* inalloca(<{ %struct.B*, %struct.A }>) %0) ret i32 %3 } @@ -172,13 +172,13 @@ entry: ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}} ; CHECK: jmpl ; CHECK-NOT: ret -define x86_fastcallcc i32 @fastcall_thunk(%struct.B* inreg %this, <{ %struct.A }>* inalloca) { +define x86_fastcallcc i32 @fastcall_thunk(%struct.B* inreg %this, <{ %struct.A }>* inalloca(<{ %struct.A }>)) { entry: %1 = bitcast %struct.B* %this to i32 (%struct.B*, <{ %struct.A }>*)*** %vtable = load i32 (%struct.B*, <{ %struct.A }>*)**, i32 (%struct.B*, <{ %struct.A }>*)*** %1 %vfn = getelementptr inbounds i32 (%struct.B*, <{ %struct.A }>*)*, i32 (%struct.B*, <{ %struct.A }>*)** %vtable, i32 1 %2 = load i32 (%struct.B*, <{ %struct.A }>*)*, i32 (%struct.B*, <{ %struct.A }>*)** %vfn - %3 = musttail call x86_fastcallcc i32 %2(%struct.B* inreg %this, <{ %struct.A }>* inalloca %0) + %3 = musttail call x86_fastcallcc i32 %2(%struct.B* inreg %this, <{ %struct.A }>* inalloca(<{ %struct.A }>) %0) ret i32 %3 } diff --git a/llvm/test/CodeGen/X86/musttail-thiscall.ll b/llvm/test/CodeGen/X86/musttail-thiscall.ll index 682f85e1eb8522..b9994963132c78 100644 --- a/llvm/test/CodeGen/X86/musttail-thiscall.ll +++ b/llvm/test/CodeGen/X86/musttail-thiscall.ll @@ -21,14 +21,14 @@ declare x86_thiscallcc i32 @t2_callee(i8* %this, i32 %a) ; CHECK-LABEL: t3: ; CHECK: jmp {{_?}}t3_callee -define x86_thiscallcc i8* @t3(i8* %this, <{ i8*, i32 }>* inalloca %args) { +define x86_thiscallcc i8* @t3(i8* %this, <{ i8*, i32 }>* inalloca(<{ i8*, i32 }>) %args) { %adj = getelementptr i8, i8* %this, i32 4 %a_ptr = getelementptr <{ i8*, i32 }>, <{ i8*, i32 }>* %args, i32 0, i32 1 store i32 0, i32* %a_ptr - %rv = musttail call x86_thiscallcc i8* @t3_callee(i8* %adj, <{ i8*, i32 }>* inalloca %args) + %rv = musttail call x86_thiscallcc i8* @t3_callee(i8* %adj, <{ i8*, i32 }>* inalloca(<{ i8*, i32 }>) %args) ret i8* %rv } -declare x86_thiscallcc i8* @t3_callee(i8* %this, <{ i8*, i32 }>* inalloca %args); +declare x86_thiscallcc i8* @t3_callee(i8* %this, <{ i8*, i32 }>* inalloca(<{ i8*, i32 }>) %args); ; CHECK-LABEL: t4: ; CHECK: jmp {{_?}}t4_callee diff --git a/llvm/test/CodeGen/X86/shrink-wrap-chkstk.ll b/llvm/test/CodeGen/X86/shrink-wrap-chkstk.ll index 32e046df6bb055..241d42c3227b24 100644 --- a/llvm/test/CodeGen/X86/shrink-wrap-chkstk.ll +++ b/llvm/test/CodeGen/X86/shrink-wrap-chkstk.ll @@ -25,7 +25,7 @@ bb1: br label %bb2 bb2: - call void @inalloca_params(<{ %struct.S }>* inalloca nonnull %argmem) + call void @inalloca_params(<{ %struct.S }>* inalloca(<{ %struct.S }>) nonnull %argmem) ret void } @@ -39,7 +39,7 @@ bb2: ; CHECK: popl %ebp ; CHECK: retl -declare void @inalloca_params(<{ %struct.S }>* inalloca) +declare void @inalloca_params(<{ %struct.S }>* inalloca(<{ %struct.S }>)) declare i32 @doSomething(i32, i32*) diff --git a/llvm/test/CodeGen/X86/tail-call-mutable-memarg.ll b/llvm/test/CodeGen/X86/tail-call-mutable-memarg.ll index 34db632ec2050c..e4b9dada399d7d 100644 --- a/llvm/test/CodeGen/X86/tail-call-mutable-memarg.ll +++ b/llvm/test/CodeGen/X86/tail-call-mutable-memarg.ll @@ -24,7 +24,7 @@ entry: ; CHECK: calll _tail_std@4 ; CHECK: retl $4 -define x86_thiscallcc void @inalloca(i32* %this, i32* inalloca %args) { +define x86_thiscallcc void @inalloca(i32* %this, i32* inalloca(i32) %args) { entry: %val = load i32, i32* %args store i32 0, i32* %args diff --git a/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll b/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll index 91bce1610c8b81..110691504655b4 100644 --- a/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll +++ b/llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll @@ -5,7 +5,7 @@ target triple = "i686-pc-windows-msvc18.0.0" %struct.T = type { i64, [3 x i32] } ; Function Attrs: nounwind optsize -define void @f(i8* %p, i8* %q, i32* inalloca nocapture %unused) #0 { +define void @f(i8* %p, i8* %q, i32* inalloca(i32) nocapture %unused) #0 { entry: %g = alloca %struct.T, align 8 %r = alloca i32, align 8 @@ -25,7 +25,7 @@ while.end: ; preds = %while.body ret void } -define void @f_pgso(i8* %p, i8* %q, i32* inalloca nocapture %unused) !prof !14 { +define void @f_pgso(i8* %p, i8* %q, i32* inalloca(i32) nocapture %unused) !prof !14 { entry: %g = alloca %struct.T, align 8 %r = alloca i32, align 8 diff --git a/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll b/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll index ce5e583f911543..d6920a7f9a59f6 100644 --- a/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll +++ b/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll @@ -109,7 +109,7 @@ target triple = "i386-pc-windows-msvc19.10.24728" %struct.NonTrivial = type { i32 } ; Function Attrs: nounwind -define void @f(<{ %struct.NonTrivial, i32, i32, i32 }>* inalloca) local_unnamed_addr #0 !dbg !7 { +define void @f(<{ %struct.NonTrivial, i32, i32, i32 }>* inalloca(<{ %struct.NonTrivial, i32, i32, i32 }>)) local_unnamed_addr #0 !dbg !7 { entry: %a = getelementptr inbounds <{ %struct.NonTrivial, i32, i32, i32 }>, <{ %struct.NonTrivial, i32, i32, i32 }>* %0, i32 0, i32 0 %b = getelementptr inbounds <{ %struct.NonTrivial, i32, i32, i32 }>, <{ %struct.NonTrivial, i32, i32, i32 }>* %0, i32 0, i32 1 diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument-dynamic-allocas.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument-dynamic-allocas.ll index 434e4be4e8e6d4..257c0cbf0c7e94 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/instrument-dynamic-allocas.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/instrument-dynamic-allocas.ll @@ -31,8 +31,8 @@ define void @has_inalloca() uwtable sanitize_address { entry: %t = alloca inalloca i32 store i32 42, i32* %t - call void @pass_inalloca(i32* inalloca %t) + call void @pass_inalloca(i32* inalloca(i32) %t) ret void } -declare void @pass_inalloca(i32* inalloca) +declare void @pass_inalloca(i32* inalloca(i32)) diff --git a/llvm/test/Linker/Inputs/inalloca-type-input.ll b/llvm/test/Linker/Inputs/inalloca-type-input.ll new file mode 100644 index 00000000000000..7fa2d8fdb3f3db --- /dev/null +++ b/llvm/test/Linker/Inputs/inalloca-type-input.ll @@ -0,0 +1,13 @@ +%a = type { i64 } +%struct = type { i32, i8 } + +define void @g(%a* inalloca(%a)) { + ret void +} + +declare void @baz(%struct* inalloca(%struct)) + +define void @foo(%struct* inalloca(%struct) %a) { + call void @baz(%struct* inalloca(%struct) %a) + ret void +} diff --git a/llvm/test/Linker/inalloca-types.ll b/llvm/test/Linker/inalloca-types.ll new file mode 100644 index 00000000000000..36cc9c3f7ef4a2 --- /dev/null +++ b/llvm/test/Linker/inalloca-types.ll @@ -0,0 +1,25 @@ +; RUN: llvm-link %s %p/Inputs/inalloca-type-input.ll -S | FileCheck %s + +%a = type { i64 } +%struct = type { i32, i8 } + +; CHECK-LABEL: define void @f(%a* inalloca(%a) %0) +define void @f(%a* inalloca(%a)) { + ret void +} + +; CHECK-LABEL: define void @bar( +; CHECK: call void @foo(%struct* inalloca(%struct) %ptr) +define void @bar() { + %ptr = alloca inalloca %struct + call void @foo(%struct* inalloca(%struct) %ptr) + ret void +} + +; CHECK-LABEL: define void @g(%a* inalloca(%a) %0) + +; CHECK-LABEL: define void @foo(%struct* inalloca(%struct) %a) +; CHECK-NEXT: call void @baz(%struct* inalloca(%struct) %a) +declare void @foo(%struct* inalloca(%struct) %a) + +; CHECK: declare void @baz(%struct* inalloca(%struct)) diff --git a/llvm/test/Transforms/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/ArgumentPromotion/X86/thiscall.ll index d9f3681ba4ab22..0643397be09929 100644 --- a/llvm/test/Transforms/ArgumentPromotion/X86/thiscall.ll +++ b/llvm/test/Transforms/ArgumentPromotion/X86/thiscall.ll @@ -12,25 +12,25 @@ target triple = "i386-pc-windows-msvc19.11.0" %struct.a = type { i8 } -define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca) { +define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca(<{ %struct.a }>)) { ; ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun -; ARGPROMOTION-SAME: (%struct.a* [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca [[TMP0:%.*]]) +; ARGPROMOTION-SAME: (%struct.a* [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca(<{ [[STRUCT_A]] }>) [[TMP0:%.*]]) { ; ARGPROMOTION-NEXT: entry: ; ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 ; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 ; ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 ; ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]]) -; ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) +; ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]]) ; ARGPROMOTION-NEXT: ret void ; ; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun -; GLOBALOPT_ARGPROMOTION-SAME: (<{ [[STRUCT_A:%.*]] }>* [[TMP0:%.*]]) unnamed_addr +; GLOBALOPT_ARGPROMOTION-SAME: (<{ [[STRUCT_A:%.*]] }>* [[TMP0:%.*]]) unnamed_addr { ; GLOBALOPT_ARGPROMOTION-NEXT: entry: ; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 ; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 ; GLOBALOPT_ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 ; GLOBALOPT_ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]]) -; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) +; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]]) ; GLOBALOPT_ARGPROMOTION-NEXT: ret void ; entry: @@ -38,22 +38,22 @@ entry: %argmem = alloca inalloca <{ %struct.a }>, align 4 %1 = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %argmem, i32 0, i32 0 %call = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* %1, %struct.a* dereferenceable(1) %a) - call void @ext(<{ %struct.a }>* inalloca %argmem) + call void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem) ret void } ; This is here to ensure @internalfun is live. define void @exportedfun(%struct.a* %a) { ; ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun -; ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) +; ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) { ; ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() ; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(%struct.a* [[A]], <{ [[STRUCT_A]] }>* inalloca [[ARGMEM]]) +; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(%struct.a* [[A]], <{ [[STRUCT_A]] }>* inalloca(<{ [[STRUCT_A]] }>) [[ARGMEM]]) ; ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8* [[INALLOCA_SAVE]]) ; ARGPROMOTION-NEXT: ret void ; ; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun -; GLOBALOPT_ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) local_unnamed_addr +; GLOBALOPT_ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) local_unnamed_addr { ; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() ; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 ; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(<{ [[STRUCT_A]] }>* [[ARGMEM]]) @@ -62,12 +62,12 @@ define void @exportedfun(%struct.a* %a) { ; %inalloca.save = tail call i8* @llvm.stacksave() %argmem = alloca inalloca <{ %struct.a }>, align 4 - call x86_thiscallcc void @internalfun(%struct.a* %a, <{ %struct.a }>* inalloca %argmem) + call x86_thiscallcc void @internalfun(%struct.a* %a, <{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem) call void @llvm.stackrestore(i8* %inalloca.save) ret void } declare x86_thiscallcc %struct.a* @copy_ctor(%struct.a* returned, %struct.a* dereferenceable(1)) -declare void @ext(<{ %struct.a }>* inalloca) +declare void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>)) declare i8* @llvm.stacksave() declare void @llvm.stackrestore(i8*) diff --git a/llvm/test/Transforms/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/ArgumentPromotion/inalloca.ll index ebf3d18f2fc5cd..7eaa7499af6b40 100644 --- a/llvm/test/Transforms/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/ArgumentPromotion/inalloca.ll @@ -7,9 +7,9 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1 %struct.ss = type { i32, i32 } ; Argpromote + sroa should change this to passing the two integers by value. -define internal i32 @f(%struct.ss* inalloca %s) { +define internal i32 @f(%struct.ss* inalloca(%struct.ss) %s) { ; CHECK-LABEL: define {{[^@]+}}@f -; CHECK-SAME: (i32 [[S_0_0_VAL:%.*]], i32 [[S_0_1_VAL:%.*]]) unnamed_addr +; CHECK-SAME: (i32 [[S_0_0_VAL:%.*]], i32 [[S_0_1_VAL:%.*]]) unnamed_addr { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[R:%.*]] = add i32 [[S_0_0_VAL]], [[S_0_1_VAL]] ; CHECK-NEXT: ret i32 [[R]] @@ -24,7 +24,7 @@ entry: } define i32 @main() { -; CHECK-LABEL: define {{[^@]+}}@main() local_unnamed_addr +; CHECK-LABEL: define {{[^@]+}}@main() local_unnamed_addr { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[R:%.*]] = call fastcc i32 @f(i32 1, i32 2) ; CHECK-NEXT: ret i32 [[R]] @@ -35,14 +35,14 @@ entry: %f1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 store i32 1, i32* %f0, align 4 store i32 2, i32* %f1, align 4 - %r = call i32 @f(%struct.ss* inalloca %S) + %r = call i32 @f(%struct.ss* inalloca(%struct.ss) %S) ret i32 %r } ; Argpromote can't promote %a because of the icmp use. -define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind { +define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca(%struct.ss) %b) nounwind { ; CHECK-LABEL: define {{[^@]+}}@g -; CHECK-SAME: (%struct.ss* [[A:%.*]], %struct.ss* [[B:%.*]]) unnamed_addr +; CHECK-SAME: (%struct.ss* [[A:%.*]], %struct.ss* [[B:%.*]]) unnamed_addr #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = icmp eq %struct.ss* [[A]], [[B]] ; CHECK-NEXT: ret i1 [[C]] @@ -53,14 +53,14 @@ entry: } define i32 @test() { -; CHECK-LABEL: define {{[^@]+}}@test() local_unnamed_addr +; CHECK-LABEL: define {{[^@]+}}@test() local_unnamed_addr { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]] +; CHECK-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4 ; CHECK-NEXT: [[C:%.*]] = call fastcc i1 @g(%struct.ss* [[S]], %struct.ss* [[S]]) ; CHECK-NEXT: ret i32 0 ; entry: %S = alloca inalloca %struct.ss - %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) + %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca(%struct.ss) %S) ret i32 0 } diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll index 9937e6cf20729c..ad452d68acbdcc 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll @@ -14,15 +14,15 @@ target triple = "i386-pc-windows-msvc19.11.0" %struct.a = type { i8 } -define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca) { +define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{ %struct.a }>* inalloca(<{ %struct.a }>)) { ; CHECK-LABEL: define {{[^@]+}}@internalfun -; CHECK-SAME: (%struct.a* noalias nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[TMP0:%.*]]) { +; CHECK-SAME: (%struct.a* noalias nocapture nofree readnone [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* noundef nonnull inalloca(<{ [[STRUCT_A]] }>) align 4 dereferenceable(1) [[TMP0:%.*]]) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0 ; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]] }>, align 4 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0 ; CHECK-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* noundef nonnull align 4 dereferenceable(1) [[TMP1]], %struct.a* noundef nonnull align 4 dereferenceable(1) [[A]]) -; CHECK-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; CHECK-NEXT: call void @ext(<{ [[STRUCT_A]] }>* noundef nonnull inalloca(<{ [[STRUCT_A]] }>) align 4 dereferenceable(1) [[ARGMEM]]) ; CHECK-NEXT: ret void ; entry: @@ -30,7 +30,7 @@ entry: %argmem = alloca inalloca <{ %struct.a }>, align 4 %1 = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %argmem, i32 0, i32 0 %call = call x86_thiscallcc %struct.a* @copy_ctor(%struct.a* %1, %struct.a* dereferenceable(1) %a) - call void @ext(<{ %struct.a }>* inalloca %argmem) + call void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem) ret void } @@ -40,19 +40,19 @@ define void @exportedfun(%struct.a* %a) { ; CHECK-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]]) { ; CHECK-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8* @llvm.stacksave() #[[ATTR1:[0-9]+]] ; CHECK-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A:%.*]] }>, align 4 -; CHECK-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone undef, <{ [[STRUCT_A]] }>* inalloca noundef nonnull align 4 dereferenceable(1) [[ARGMEM]]) +; CHECK-NEXT: call x86_thiscallcc void @internalfun(%struct.a* noalias nocapture nofree readnone undef, <{ [[STRUCT_A]] }>* noundef nonnull inalloca(<{ [[STRUCT_A]] }>) align 4 dereferenceable(1) [[ARGMEM]]) ; CHECK-NEXT: call void @llvm.stackrestore(i8* nofree [[INALLOCA_SAVE]]) ; CHECK-NEXT: ret void ; %inalloca.save = tail call i8* @llvm.stacksave() %argmem = alloca inalloca <{ %struct.a }>, align 4 - call x86_thiscallcc void @internalfun(%struct.a* %a, <{ %struct.a }>* inalloca %argmem) + call x86_thiscallcc void @internalfun(%struct.a* %a, <{ %struct.a }>* inalloca(<{ %struct.a }>) %argmem) call void @llvm.stackrestore(i8* %inalloca.save) ret void } declare x86_thiscallcc %struct.a* @copy_ctor(%struct.a* returned, %struct.a* dereferenceable(1)) -declare void @ext(<{ %struct.a }>* inalloca) +declare void @ext(<{ %struct.a }>* inalloca(<{ %struct.a }>)) declare i8* @llvm.stacksave() declare void @llvm.stackrestore(i8*) ;. diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll index 30575fe8bde93c..0b82eac6b982ae 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll @@ -9,12 +9,12 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1 %struct.ss = type { i32, i32 } ; Argpromote + sroa should change this to passing the two integers by value. -define internal i32 @f(%struct.ss* inalloca %s) { +define internal i32 @f(%struct.ss* inalloca(%struct.ss) %s) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@f -; IS__TUNIT____-SAME: (%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__TUNIT____-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 +; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 ; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 @@ -23,9 +23,9 @@ define internal i32 @f(%struct.ss* inalloca %s) { ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@f -; IS__CGSCC____-SAME: (%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[S:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[S]], i32 0, i32 0 +; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0 ; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4 ; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4 @@ -51,7 +51,7 @@ define i32 @main() { ; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__TUNIT____-NEXT: store i32 1, i32* [[F0]], align 4 ; IS__TUNIT____-NEXT: store i32 2, i32* [[F1]], align 4 -; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] +; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 [[R]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn @@ -63,7 +63,7 @@ define i32 @main() { ; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1 ; IS__CGSCC____-NEXT: store i32 1, i32* [[F0]], align 4 ; IS__CGSCC____-NEXT: store i32 2, i32* [[F1]], align 4 -; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree noundef nonnull align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull inalloca([[STRUCT_SS]]) align 4 dereferenceable(8) [[S]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 [[R]] ; entry: @@ -72,15 +72,15 @@ entry: %f1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 store i32 1, i32* %f0, align 4 store i32 2, i32* %f1, align 4 - %r = call i32 @f(%struct.ss* inalloca %S) + %r = call i32 @f(%struct.ss* inalloca(%struct.ss) %S) ret i32 %r } ; Argpromote can't promote %a because of the icmp use. -define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind { +define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca(%struct.ss) %b) nounwind { ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@g -; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca noalias nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (%struct.ss* noalias nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* noalias nocapture nofree nonnull writeonly inalloca([[STRUCT_SS:%.*]]) align 4 dereferenceable(8) [[B:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: ret i1 undef ; @@ -104,7 +104,7 @@ define i32 @test() { ; entry: %S = alloca inalloca %struct.ss - %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca %S) + %c = call i1 @g(%struct.ss* %S, %struct.ss* inalloca(%struct.ss) %S) ret i32 0 } ;. diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll index 9f28407c76c472..c440e12ddfce44 100644 --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -107,15 +107,15 @@ define void @test6_2(i8** %p, i8* %q) { } ; inalloca parameters are always considered written -define void @test7_1(i32* inalloca %a) { +define void @test7_1(i32* inalloca(i32) %a) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test7_1 -; IS__TUNIT____-SAME: (i32* inalloca nocapture nofree nonnull writeonly dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly inalloca(i32) dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test7_1 -; IS__CGSCC____-SAME: (i32* inalloca nocapture nofree nonnull writeonly dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly inalloca(i32) dereferenceable(4) [[A:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret void ; ret void diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll index 41fa16c0284a88..0ed93a912789bc 100644 --- a/llvm/test/Transforms/Attributor/value-simplify.ll +++ b/llvm/test/Transforms/Attributor/value-simplify.ll @@ -332,15 +332,15 @@ define i32 @ipccp3() { ; Do not touch complicated arguments (for now) %struct.X = type { i8* } -define internal i32* @test_inalloca(i32* inalloca %a) { +define internal i32* @test_inalloca(i32* inalloca(i32) %a) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_inalloca -; IS__TUNIT____-SAME: (i32* inalloca noalias nofree nonnull returned writeonly dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { +; IS__TUNIT____-SAME: (i32* noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: ret i32* [[A]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inalloca -; IS__CGSCC____-SAME: (i32* inalloca noalias nofree noundef nonnull returned writeonly dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { +; IS__CGSCC____-SAME: (i32* noalias nofree noundef nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { ; IS__CGSCC____-NEXT: ret i32* [[A]] ; ret i32* %a diff --git a/llvm/test/Transforms/DeadArgElim/keepalive.ll b/llvm/test/Transforms/DeadArgElim/keepalive.ll index fff14a7f52a852..b9be83e5cdf94c 100644 --- a/llvm/test/Transforms/DeadArgElim/keepalive.ll +++ b/llvm/test/Transforms/DeadArgElim/keepalive.ll @@ -39,13 +39,13 @@ define void @caller() { ; We can't remove 'this' here, as that would put argmem in ecx instead of ; memory. -define internal x86_thiscallcc i32 @unused_this(i32* %this, i32* inalloca %argmem) { +define internal x86_thiscallcc i32 @unused_this(i32* %this, i32* inalloca(i32) %argmem) { ; ; %v = load i32, i32* %argmem ret i32 %v } -; CHECK-LABEL: define internal x86_thiscallcc i32 @unused_this(i32* %this, i32* inalloca %argmem) +; CHECK-LABEL: define internal x86_thiscallcc i32 @unused_this(i32* %this, i32* inalloca(i32) %argmem) define i32 @caller2() { ; @@ -53,7 +53,7 @@ define i32 @caller2() { %t = alloca i32 %m = alloca inalloca i32 store i32 42, i32* %m - %v = call x86_thiscallcc i32 @unused_this(i32* %t, i32* inalloca %m) + %v = call x86_thiscallcc i32 @unused_this(i32* %t, i32* inalloca(i32) %m) ret i32 %v } diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index 48a939c1228f9b..361b243f512101 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -148,7 +148,7 @@ define void @test9(%struct.x* byval(%struct.x) %a) nounwind { } ; Test for inalloca handling. -define void @test9_2(%struct.x* inalloca %a) nounwind { +define void @test9_2(%struct.x* inalloca(%struct.x) %a) nounwind { ; CHECK-LABEL: @test9_2( ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll index ae34219bd011ea..6585ee4d244825 100644 --- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -50,9 +50,9 @@ define void @test6_2(i8** %p, i8* %q) { ret void } -; CHECK: define void @test7_1(i32* inalloca nocapture %a) +; CHECK: define void @test7_1(i32* nocapture inalloca(i32) %a) ; inalloca parameters are always considered written -define void @test7_1(i32* inalloca %a) { +define void @test7_1(i32* inalloca(i32) %a) { ret void } diff --git a/llvm/test/Transforms/GVNHoist/hoist-pr28606.ll b/llvm/test/Transforms/GVNHoist/hoist-pr28606.ll index 2c588283ea914f..d8bad7ae45638a 100644 --- a/llvm/test/Transforms/GVNHoist/hoist-pr28606.ll +++ b/llvm/test/Transforms/GVNHoist/hoist-pr28606.ll @@ -5,7 +5,7 @@ target triple = "i686-pc-windows-msvc18.0.0" %struct.S = type { i8* } -declare void @f(<{ %struct.S }>* inalloca) +declare void @f(<{ %struct.S }>* inalloca(<{ %struct.S }>)) ; Check that we don't clone the %x alloca and insert it in the live range of @@ -41,7 +41,7 @@ false: br label %exit exit: - call void @f(<{ %struct.S }>* inalloca %argmem) + call void @f(<{ %struct.S }>* inalloca(<{ %struct.S }>) %argmem) call void @llvm.stackrestore(i8* %inalloca.save) ret void } diff --git a/llvm/test/Transforms/GlobalOpt/fastcc.ll b/llvm/test/Transforms/GlobalOpt/fastcc.ll index edd0688ea92b7f..0278d83d209f3d 100644 --- a/llvm/test/Transforms/GlobalOpt/fastcc.ll +++ b/llvm/test/Transforms/GlobalOpt/fastcc.ll @@ -29,19 +29,19 @@ define internal i32 @j(i32* %m) { ret i32 %v } -define internal i32 @inalloca(i32* inalloca %p) { +define internal i32 @inalloca(i32* inalloca(i32) %p) { ; CHECK-LABEL: define internal fastcc i32 @inalloca(i32* %p) %rv = load i32, i32* %p ret i32 %rv } -define i32 @inalloca2_caller(i32* inalloca %p) { - %rv = musttail call i32 @inalloca2(i32* inalloca %p) +define i32 @inalloca2_caller(i32* inalloca(i32) %p) { + %rv = musttail call i32 @inalloca2(i32* inalloca(i32) %p) ret i32 %rv } -define internal i32 @inalloca2(i32* inalloca %p) { +define internal i32 @inalloca2(i32* inalloca(i32) %p) { ; Because of the musttail caller, this inalloca cannot be dropped. -; CHECK-LABEL: define internal i32 @inalloca2(i32* inalloca %p) +; CHECK-LABEL: define internal i32 @inalloca2(i32* inalloca(i32) %p) %rv = load i32, i32* %p ret i32 %rv } @@ -59,7 +59,7 @@ define void @call_things() { call coldcc i32 @h(i32* %m) call i32 @j(i32* %m) %args = alloca inalloca i32 - call i32 @inalloca(i32* inalloca %args) + call i32 @inalloca(i32* inalloca(i32) %args) %c = call token @llvm.call.preallocated.setup(i32 1) %N = call i8* @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32) %n = bitcast i8* %N to i32* diff --git a/llvm/test/Transforms/Inline/inalloca-not-static.ll b/llvm/test/Transforms/Inline/inalloca-not-static.ll index 74b5ecf420ce98..1a6dd75a017812 100644 --- a/llvm/test/Transforms/Inline/inalloca-not-static.ll +++ b/llvm/test/Transforms/Inline/inalloca-not-static.ll @@ -41,13 +41,13 @@ entry: %argmem = alloca inalloca <{ %struct.Foo }>, align 4 %0 = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %argmem, i32 0, i32 0 %call = call x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* %0) - call void @h(<{ %struct.Foo }>* inalloca %argmem) + call void @h(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>) %argmem) call void @llvm.stackrestore(i8* %inalloca.save) ret void } ; Function Attrs: alwaysinline inlinehint nounwind -define internal void @h(<{ %struct.Foo }>* inalloca) alwaysinline { +define internal void @h(<{ %struct.Foo }>* inalloca(<{ %struct.Foo }>)) alwaysinline { entry: %o = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 call x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo* %o) diff --git a/llvm/test/Transforms/InstCombine/alloca.ll b/llvm/test/Transforms/InstCombine/alloca.ll index 072d5f2fe9f94a..fee8e0ef70f14b 100644 --- a/llvm/test/Transforms/InstCombine/alloca.ll +++ b/llvm/test/Transforms/InstCombine/alloca.ll @@ -207,7 +207,7 @@ define void @test8() { ; PR19569 %struct_type = type { i32, i32 } -declare void @test9_aux(<{ %struct_type }>* inalloca) +declare void @test9_aux(<{ %struct_type }>* inalloca(<{ %struct_type }>)) declare i8* @llvm.stacksave() declare void @llvm.stackrestore(i8*) @@ -219,7 +219,7 @@ define void @test9(%struct_type* %a) { ; ALL-NEXT: [[TMP0:%.*]] = bitcast %struct_type* [[A:%.*]] to i64* ; ALL-NEXT: [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 4 ; ALL-NEXT: store i64 [[TMP1]], i64* [[ARGMEM]], align 8 -; ALL-NEXT: call void @test9_aux(<{ [[STRUCT_TYPE]] }>* inalloca nonnull [[TMPCAST]]) +; ALL-NEXT: call void @test9_aux(<{ [[STRUCT_TYPE]] }>* nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[TMPCAST]]) ; ALL-NEXT: ret void ; entry: @@ -229,7 +229,7 @@ entry: %1 = bitcast %struct_type* %0 to i8* %2 = bitcast %struct_type* %a to i8* call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %1, i8* align 4 %2, i32 8, i1 false) - call void @test9_aux(<{ %struct_type }>* inalloca %argmem) + call void @test9_aux(<{ %struct_type }>* inalloca(<{ %struct_type }>) %argmem) call void @llvm.stackrestore(i8* %inalloca.save) ret void } diff --git a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll index 90289e2468f85b..bbf2008d585449 100644 --- a/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll +++ b/llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll @@ -4,12 +4,12 @@ target datalayout = "e-p:32:32" target triple = "i686-pc-linux-gnu" declare void @takes_i32(i32) -declare void @takes_i32_inalloca(i32* inalloca) +declare void @takes_i32_inalloca(i32* inalloca(i32)) define void @f() { ; CHECK-LABEL: define void @f() %args = alloca inalloca i32 - call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca %args) + call void bitcast (void (i32)* @takes_i32 to void (i32*)*)(i32* inalloca(i32) %args) ; CHECK: call void bitcast ret void } diff --git a/llvm/test/Transforms/InstCombine/stacksaverestore.ll b/llvm/test/Transforms/InstCombine/stacksaverestore.ll index 9eb0efb1911ba6..cbc353afe61909 100644 --- a/llvm/test/Transforms/InstCombine/stacksaverestore.ll +++ b/llvm/test/Transforms/InstCombine/stacksaverestore.ll @@ -9,7 +9,7 @@ declare void @llvm.stackrestore(i8*) define i32* @test1(i32 %P) { %tmp = call i8* @llvm.stacksave( ) call void @llvm.stackrestore( i8* %tmp ) ;; not restoring anything - %A = alloca i32, i32 %P + %A = alloca i32, i32 %P ret i32* %A } @@ -49,7 +49,7 @@ bb: ; preds = %bb, %bb.preheader %tmp77 = alloca i8, i32 %size ; [#uses=1] %tmp78 = call i8* @llvm.stacksave( ) ; [#uses=1] %tmp102 = alloca i8, i32 %size ; [#uses=1] - call void @bar( i32 %i.0.reg2mem.0, i8* %tmp23, i8* %tmp52, i8* %tmp77, i8* %tmp102, i32 %size ) nounwind + call void @bar( i32 %i.0.reg2mem.0, i8* %tmp23, i8* %tmp52, i8* %tmp77, i8* %tmp102, i32 %size ) nounwind call void @llvm.stackrestore( i8* %tmp78 ) call void @llvm.stackrestore( i8* %tmp53 ) call void @llvm.stackrestore( i8* %tmp28 ) @@ -72,7 +72,7 @@ return: ; preds = %bb, %entry declare void @bar(i32, i8*, i8*, i8*, i8*, i32) -declare void @inalloca_callee(i32* inalloca) +declare void @inalloca_callee(i32* inalloca(i32)) define void @test3(i32 %c) { entry: @@ -83,7 +83,7 @@ loop: %save1 = call i8* @llvm.stacksave() %argmem = alloca inalloca i32 store i32 0, i32* %argmem - call void @inalloca_callee(i32* inalloca %argmem) + call void @inalloca_callee(i32* inalloca(i32) %argmem) ; This restore cannot be deleted, the restore below does not make it dead. call void @llvm.stackrestore(i8* %save1) @@ -106,7 +106,7 @@ return: ; CHECK: %save1 = call i8* @llvm.stacksave() ; CHECK: %argmem = alloca inalloca i32 ; CHECK: store i32 0, i32* %argmem -; CHECK: call void @inalloca_callee(i32* inalloca {{.*}} %argmem) +; CHECK: call void @inalloca_callee(i32* {{.*}} inalloca(i32) %argmem) ; CHECK: call void @llvm.stackrestore(i8* %save1) ; CHECK: br i1 %done, label %loop, label %return ; CHECK: ret void diff --git a/llvm/test/Verifier/align.ll b/llvm/test/Verifier/align.ll index 38ce3772e76525..1f5c8da7654a44 100644 --- a/llvm/test/Verifier/align.ll +++ b/llvm/test/Verifier/align.ll @@ -1,12 +1,12 @@ ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: @align_non_pointer1 define void @align_non_pointer1(i32 align 4 %a) { ret void } -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) inalloca(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: @align_non_pointer2 define align 4 void @align_non_pointer2(i32 %a) { ret void diff --git a/llvm/test/Verifier/amdgpu-cc.ll b/llvm/test/Verifier/amdgpu-cc.ll index b9b4c5027a1986..61f1c68cd5b3d4 100644 --- a/llvm/test/Verifier/amdgpu-cc.ll +++ b/llvm/test/Verifier/amdgpu-cc.ll @@ -118,7 +118,7 @@ define amdgpu_kernel void @preallocated_as0_cc_amdgpu_kernel(i32* preallocated(i ; CHECK: Calling convention disallows inalloca ; CHECK-NEXT: void (i32*)* @inalloca_as0_cc_amdgpu_kernel -define amdgpu_kernel void @inalloca_as0_cc_amdgpu_kernel(i32* inalloca %ptr) { +define amdgpu_kernel void @inalloca_as0_cc_amdgpu_kernel(i32* inalloca(i32) %ptr) { ret void } diff --git a/llvm/test/Verifier/byref.ll b/llvm/test/Verifier/byref.ll index 2f22ee37292e71..d5921bf5b2614b 100644 --- a/llvm/test/Verifier/byref.ll +++ b/llvm/test/Verifier/byref.ll @@ -28,7 +28,7 @@ define void @byref_byval(i32* byref(i32) byval(i32)) { ; CHECK: Attributes 'byval', 'inalloca', 'preallocated', 'inreg', 'nest', 'byref', and 'sret' are incompatible! ; CHECK-NEXT: void (i32*)* @byref_inalloca -define void @byref_inalloca(i32* byref(i32) inalloca) { +define void @byref_inalloca(i32* byref(i32) inalloca(i32)) { ret void } @@ -56,7 +56,7 @@ define void @byref_nest(i32* byref(i32) nest) { ret void } -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: void (i32)* @byref_non_pointer define void @byref_non_pointer(i32 byref(i32)) { ret void diff --git a/llvm/test/Verifier/byval-1.ll b/llvm/test/Verifier/byval-1.ll index e2b4519b17cb98..6344371bba5e04 100644 --- a/llvm/test/Verifier/byval-1.ll +++ b/llvm/test/Verifier/byval-1.ll @@ -1,5 +1,5 @@ ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: nest noalias nocapture nonnull readnone readonly byref(i32) byval(i32) inalloca(i32) preallocated(i32) sret(i32) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: void (i32)* @h declare void @h(i32 byval(i32) %num) diff --git a/llvm/test/Verifier/inalloca-vararg.ll b/llvm/test/Verifier/inalloca-vararg.ll index 428f89ec88f102..de7622b638d884 100644 --- a/llvm/test/Verifier/inalloca-vararg.ll +++ b/llvm/test/Verifier/inalloca-vararg.ll @@ -3,7 +3,7 @@ declare void @h(i32, ...) define void @i() { %args = alloca inalloca i32 - call void (i32, ...) @h(i32 1, i32* inalloca %args, i32 3) + call void (i32, ...) @h(i32 1, i32* inalloca(i32) %args, i32 3) ; CHECK: inalloca isn't on the last argument! ret void } diff --git a/llvm/test/Verifier/inalloca1.ll b/llvm/test/Verifier/inalloca1.ll index 7ee2cba5ac1749..76da66adc7983c 100644 --- a/llvm/test/Verifier/inalloca1.ll +++ b/llvm/test/Verifier/inalloca1.ll @@ -1,22 +1,34 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -declare void @a(i64* byval(i64) inalloca %p) +declare void @a(i64* byval(i64) inalloca(i64) %p) ; CHECK: Attributes {{.*}} are incompatible -declare void @b(i64* inreg inalloca %p) +declare void @b(i64* inreg inalloca(i64) %p) ; CHECK: Attributes {{.*}} are incompatible -declare void @c(i64* sret(i64) inalloca %p) +declare void @c(i64* sret(i64) inalloca(i64) %p) ; CHECK: Attributes {{.*}} are incompatible -declare void @d(i64* nest inalloca %p) +declare void @d(i64* nest inalloca(i64) %p) ; CHECK: Attributes {{.*}} are incompatible -declare void @e(i64* readonly inalloca %p) +declare void @e(i64* readonly inalloca(i64) %p) ; CHECK: Attributes {{.*}} are incompatible -declare void @f(void ()* inalloca %p) +declare void @f(void ()* inalloca(void()) %p) ; CHECK: do not support unsized types -declare void @g(i32* inalloca %p, i32 %p2) +declare void @g(i32* inalloca(i32) %p, i32 %p2) ; CHECK: inalloca isn't on the last parameter! + +; CHECK: Attribute 'inalloca' type does not match parameter! +; CHECK-NEXT: void (i32*)* @inalloca_mismatched_pointee_type0 +define void @inalloca_mismatched_pointee_type0(i32* inalloca(i8)) { + ret void +} + +; CHECK: Wrong types for attribute: +; CHECK-NEXT: void (i8)* @inalloca_not_pointer +define void @inalloca_not_pointer(i8 byref(i8)) { + ret void +} diff --git a/llvm/test/Verifier/inalloca2.ll b/llvm/test/Verifier/inalloca2.ll index 12a45499928573..21fc2517cd0a7b 100644 --- a/llvm/test/Verifier/inalloca2.ll +++ b/llvm/test/Verifier/inalloca2.ll @@ -2,21 +2,21 @@ ; doesn't reject it. ; RUN: llvm-as %s -o /dev/null -declare void @doit(i64* inalloca %a) +declare void @doit(i64* inalloca(i64) %a) define void @a() { entry: %a = alloca inalloca [2 x i32] %b = bitcast [2 x i32]* %a to i64* - call void @doit(i64* inalloca %b) + call void @doit(i64* inalloca(i64) %b) ret void } define void @b() { entry: %a = alloca inalloca i64 - call void @doit(i64* inalloca %a) - call void @doit(i64* inalloca %a) + call void @doit(i64* inalloca(i64) %a) + call void @doit(i64* inalloca(i64) %a) ret void } @@ -34,6 +34,6 @@ else: call: %args = phi i64* [ %a, %if ], [ %b, %else ] - call void @doit(i64* inalloca %args) + call void @doit(i64* inalloca(i64) %args) ret void } diff --git a/llvm/test/Verifier/inalloca3.ll b/llvm/test/Verifier/inalloca3.ll index c09ce100849b55..28cdbfef97857b 100644 --- a/llvm/test/Verifier/inalloca3.ll +++ b/llvm/test/Verifier/inalloca3.ll @@ -1,13 +1,13 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -declare void @doit(i64* inalloca %a) +declare void @doit(i64* inalloca(i64) %a) define void @a() { entry: %a = alloca [2 x i32] %b = bitcast [2 x i32]* %a to i64* - call void @doit(i64* inalloca %b) + call void @doit(i64* inalloca(i64) %b) ; CHECK: inalloca argument for call has mismatched alloca ret void } diff --git a/llvm/test/Verifier/noundef.ll b/llvm/test/Verifier/noundef.ll index 7b199cd6d2dee5..2ece2dd1a9ac1c 100644 --- a/llvm/test/Verifier/noundef.ll +++ b/llvm/test/Verifier/noundef.ll @@ -1,6 +1,6 @@ ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) inalloca(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: @noundef_void define noundef void @noundef_void() { ret void diff --git a/llvm/unittests/IR/AttributesTest.cpp b/llvm/unittests/IR/AttributesTest.cpp index 2c191264a892e2..11b1598979896e 100644 --- a/llvm/unittests/IR/AttributesTest.cpp +++ b/llvm/unittests/IR/AttributesTest.cpp @@ -180,9 +180,6 @@ TEST(Attributes, StringRepresentation) { Attribute A = Attribute::getWithByValType(C, Ty); EXPECT_EQ(A.getAsString(), "byval(%mystruct)"); - A = Attribute::getWithByValType(C, nullptr); - EXPECT_EQ(A.getAsString(), "byval"); - A = Attribute::getWithByValType(C, Type::getInt32Ty(C)); EXPECT_EQ(A.getAsString(), "byval(i32)"); } diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index 6bab80215c0b1c..34802b63aae845 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -718,10 +718,10 @@ TEST(CloneFunction, CloneEmptyFunction) { TEST(CloneFunction, CloneFunctionWithInalloca) { StringRef ImplAssembly = R"( - declare void @a(i32* inalloca) + declare void @a(i32* inalloca(i32)) define void @foo() { %a = alloca inalloca i32 - call void @a(i32* inalloca %a) + call void @a(i32* inalloca(i32) %a) ret void } declare void @bar()