[clang] fc9df30 - Reapply "OpaquePtr: Turn inalloca into a type attribute"

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 30 11:55:23 PDT 2021


Could you include some details (in a reply here - in the future, in the
commit message) about why the commit was reverted and what changed in the
recommit to address that issue? (helps folks review the changes) - /maybe/
if the Differential Revision line is included in th ecommit message some of
this would also be more conveniently accessed (like the diff between the
two committed versions) in Phab too, which would be handy.

On Sun, Mar 28, 2021 at 10:35 AM Matt Arsenault via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

>
> Author: Matt Arsenault
> Date: 2021-03-28T13:35:21-04:00
> New Revision: fc9df309917e57de704f3ce4372138a8d4a23d7a
>
> URL:
> https://github.com/llvm/llvm-project/commit/fc9df309917e57de704f3ce4372138a8d4a23d7a
> DIFF:
> https://github.com/llvm/llvm-project/commit/fc9df309917e57de704f3ce4372138a8d4a23d7a.diff
>
> LOG: Reapply "OpaquePtr: Turn inalloca into a type attribute"
>
> This reverts commit 20d5c42e0ef5d252b434bcb610b04f1cb79fe771.
>
> Added:
>     llvm/test/Assembler/inalloca-parse-error0.ll
>     llvm/test/Bitcode/Inputs/inalloca-upgrade.bc
>     llvm/test/Bitcode/inalloca-upgrade.test
>     llvm/test/Linker/Inputs/inalloca-type-input.ll
>     llvm/test/Linker/inalloca-types.ll
>
> Modified:
>     clang/lib/CodeGen/CGCall.cpp
>     clang/test/CodeGenCXX/attr-target-mv-inalloca.cpp
>     clang/test/CodeGenCXX/inalloca-overaligned.cpp
>     clang/test/CodeGenCXX/inalloca-stmtexpr.cpp
>     clang/test/CodeGenCXX/inalloca-vector.cpp
>     clang/test/CodeGenCXX/inheriting-constructor.cpp
>     clang/test/CodeGenCXX/microsoft-abi-arg-order.cpp
>     clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp
>     clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
>     clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
>     clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
>     clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
>     clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp
>
> clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
>     clang/test/CodeGenCXX/ms-thunks-ehspec.cpp
>     clang/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp
>     clang/test/CodeGenObjCXX/arc-indirect.mm
>     clang/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
>     llvm/docs/LangRef.rst
>     llvm/docs/ReleaseNotes.rst
>     llvm/include/llvm/IR/Argument.h
>     llvm/include/llvm/IR/Attributes.h
>     llvm/include/llvm/IR/Attributes.td
>     llvm/include/llvm/IR/Function.h
>     llvm/lib/AsmParser/LLParser.cpp
>     llvm/lib/AsmParser/LLParser.h
>     llvm/lib/Bitcode/Reader/BitcodeReader.cpp
>     llvm/lib/IR/AsmWriter.cpp
>     llvm/lib/IR/AttributeImpl.h
>     llvm/lib/IR/Attributes.cpp
>     llvm/lib/IR/Function.cpp
>     llvm/lib/IR/Verifier.cpp
>     llvm/lib/Linker/IRMover.cpp
>     llvm/lib/Transforms/Utils/ValueMapper.cpp
>     llvm/test/Assembler/invalid-immarg.ll
>     llvm/test/Bitcode/attributes.ll
>     llvm/test/Bitcode/compatibility-3.6.ll
>     llvm/test/Bitcode/compatibility-3.7.ll
>     llvm/test/Bitcode/compatibility-3.8.ll
>     llvm/test/Bitcode/compatibility-3.9.ll
>     llvm/test/Bitcode/compatibility-4.0.ll
>     llvm/test/Bitcode/compatibility-5.0.ll
>     llvm/test/Bitcode/compatibility-6.0.ll
>     llvm/test/Bitcode/compatibility.ll
>     llvm/test/Bitcode/inalloca.ll
>     llvm/test/CodeGen/X86/arg-copy-elide.ll
>     llvm/test/CodeGen/X86/cleanuppad-inalloca.ll
>     llvm/test/CodeGen/X86/inalloca-ctor.ll
>     llvm/test/CodeGen/X86/inalloca-invoke.ll
>     llvm/test/CodeGen/X86/inalloca-regparm.ll
>     llvm/test/CodeGen/X86/inalloca-stdcall.ll
>     llvm/test/CodeGen/X86/inalloca.ll
>     llvm/test/CodeGen/X86/movtopush.ll
>     llvm/test/CodeGen/X86/musttail-inalloca.ll
>     llvm/test/CodeGen/X86/musttail-indirect.ll
>     llvm/test/CodeGen/X86/musttail-thiscall.ll
>     llvm/test/CodeGen/X86/shrink-wrap-chkstk.ll
>     llvm/test/CodeGen/X86/tail-call-mutable-memarg.ll
>     llvm/test/CodeGen/X86/x86-repmov-copy-eflags.ll
>     llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll
>
> llvm/test/Instrumentation/AddressSanitizer/instrument-dynamic-allocas.ll
>     llvm/test/Transforms/ArgumentPromotion/X86/thiscall.ll
>     llvm/test/Transforms/ArgumentPromotion/inalloca.ll
>     llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
>     llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
>     llvm/test/Transforms/Attributor/readattrs.ll
>     llvm/test/Transforms/Attributor/value-simplify.ll
>     llvm/test/Transforms/DeadArgElim/keepalive.ll
>     llvm/test/Transforms/DeadStoreElimination/simple.ll
>     llvm/test/Transforms/FunctionAttrs/readattrs.ll
>     llvm/test/Transforms/GVNHoist/hoist-pr28606.ll
>     llvm/test/Transforms/GlobalOpt/fastcc.ll
>     llvm/test/Transforms/Inline/inalloca-not-static.ll
>     llvm/test/Transforms/InstCombine/alloca.ll
>     llvm/test/Transforms/InstCombine/call-cast-target-inalloca.ll
>     llvm/test/Transforms/InstCombine/stacksaverestore.ll
>     llvm/test/Verifier/align.ll
>     llvm/test/Verifier/amdgpu-cc.ll
>     llvm/test/Verifier/byref.ll
>     llvm/test/Verifier/byval-1.ll
>     llvm/test/Verifier/inalloca-vararg.ll
>     llvm/test/Verifier/inalloca1.ll
>     llvm/test/Verifier/inalloca2.ll
>     llvm/test/Verifier/inalloca3.ll
>     llvm/test/Verifier/noundef.ll
>     llvm/unittests/IR/AttributesTest.cpp
>     llvm/unittests/Transforms/Utils/CloningTest.cpp
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
> index dc73e3260891..1d71148d67e6 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 a611587b56f7..be9fc941c480 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 48a6183db8eb..0a51875bb592 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 at 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 e7ae2cb4e703..090953ae3b1d 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 at Z"(<{ %struct.Foo,
> %struct.Foo }>* inalloca %{{.*}})
> +// CHECK: call void @"?inalloca@@YAXUFoo@@0 at 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 bf71fac37b6a..e052d2e6728d 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 6de8e92186dd..c338edcc76ae 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 at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call {{.*}} @"??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]])
>    // WIN32: call void @llvm.stackrestore(
>    // WIN32: call {{.*}} @"??0Z@@QAE at XZ"(
>    // WIN32: call {{.*}} @"??1Q@@QAE at 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 at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call {{.*}} @"??0A at inalloca_nonvirt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca(<{{.*}}>) %[[ARGMEM]])
>    // WIN32: call void @llvm.stackrestore(
>    // WIN32: call {{.*}} @"??0Z@@QAE at XZ"(
>    // WIN32: call {{.*}} @"??1Q@@QAE at 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 at inalloca_virt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call {{.*}} @"??0A at inalloca_virt@@QAE at 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 at inalloca_virt@@QAE at UQ@@H0$$QAU2@@Z"(%{{[^,]*}},
> <{{.*}}>* inalloca %[[ARGMEM]])
> +  // WIN32: call {{.*}} @"??0A at inalloca_virt@@QAE at 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 4da04a43ff61..215a39ec7d48 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 at 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 at 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 at H@Z"(%struct.A*
> {{[^,]*}} %[[arg1]], i32 1)
> -// X86: call void @"?foo@@YAXUA@@00 at Z"([[argmem_ty]]* inalloca
> %[[argmem]])
> +// X86: call void @"?foo@@YAXUA@@00 at 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 7f8730080a09..adf3921f7115 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 917a7677c41e..65e789ce5c63 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 at C@byval_thunk@@W3AEXUAgg at 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 at C@byval_thunk@
> @UAEXUAgg at 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 at C
> @byval_thunk@@W7EAAXUAgg at 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 at C@stdcall_thunk@@W3AGXUAgg at 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 at C@stdcall_thunk@
> @UAGXUAgg at 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 at C
> @stdcall_thunk@@W7EAAXUAgg at 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 at C@sret_thunk@@W3AA?AUAgg at 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 at C@sret_thunk@@UAA?AUAgg at 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 at C@sret_thunk@
> @W7EAA?AUAgg at 2@U32@@Z"
>
> diff  --git a/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
> b/clang/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
> index 26f6814cc1d4..18333f36c239 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 7e173668f26f..0b6b4385a352 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 at XZ"
>  // WIN32:   store i1 false, i1* %[[isactive]]
>  //
> -// WIN32:   invoke i32 @"?TakesTwo@@YAHUA@@0 at Z"([[argmem_ty]]* inalloca
> %[[argmem]])
> +// WIN32:   invoke i32 @"?TakesTwo@@YAHUA@@0 at Z"([[argmem_ty]]*
> inalloca([[argmem_ty]]) %[[argmem]])
>  //        Destroy the two const ref temporaries.
>  // WIN32:   call x86_thiscallcc void @"??1A@@QAE at XZ"({{.*}})
>  // WIN32:   call x86_thiscallcc void @"??1A@@QAE at XZ"({{.*}})
>
> diff  --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
> b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
> index e0e4ba9e41b5..b36ea9ccd9f0 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 at 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 at 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 at test2@@QAE at XZ"
> -// WIN32:   call i32 @"?foo at test2@@YAHUNonTrivial at 1@UPOD at 1@@Z"([[argmem_ty]]*
> inalloca %argmem)
> +// WIN32:   call i32 @"?foo at test2@@YAHUNonTrivial at 1@UPOD at 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 at test3@@YAXUNonTrivial at 1@_N at Z"(<{
> %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca %0)
> +// WIN32-LABEL: define dso_local void @"?foo at test3@@YAXUNonTrivial at 1@_N at 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 at C@pr30293@@QAEXXZ"(%"struct.pr30293::C"*
> {{[^,]*}} %this)
>  // WIN32: call x86_thiscallcc %struct.SmallWithDtor* @"??0SmallWithDtor@
> @QAE at XZ"
> -// WIN32: call void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*,
> %struct.SmallWithDtor }>* inalloca %{{[^,)]*}})
> -// WIN32: declare dso_local void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{
> i8*, %struct.SmallWithDtor }>* inalloca)
> +// WIN32: call void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{ i8*,
> %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>)
> %{{[^,)]*}})
> +// WIN32: declare dso_local void @"?h at C@pr30293@@UAAXUSmallWithDtor@@@Z"(<{
> i8*, %struct.SmallWithDtor }>* inalloca(<{ i8*, %struct.SmallWithDtor }>))
>
>  // WIN64-LABEL: define dso_local void @"?g at C@pr30293@@QEAAXXZ"(%"struct.pr30293::C"*
> {{[^,]*}} %this)
>  // WIN64: declare dso_local void @"?h at 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 6082228d36b6..e71d6238c53a 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 at cdecl_inalloca@@YAXPAUC at 1@@Z"(%"struct.cdecl_inalloca::C"*
> %c)
>  // CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)*
> @"??_9C at cdecl_inalloca@@$BA at AA" to void
> (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* {{[^,]*}}
> %{{.*}})
> -// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)*
> @"??_9C at cdecl_inalloca@@$BA at 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 at cdecl_inalloca@@$BA at 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 at cdecl_inalloca@@$BA at 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 93a7d4602223..5cced42834e1 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 at C@pr30293@@UAAXUNonTrivial at 2@@Z"(<{
> i8*, %"struct.pr30293::NonTrivial" }>* inalloca %0)
> +// BITCODE-LABEL: define dso_local void @"?g at C@pr30293@@UAAXUNonTrivial at 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 256f7123ee51..b8ebe2dd9f39 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 at C
> @@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>*
> inalloca %0)
> +// CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?f at C
> @@G3AEXUNonTrivial@@@Z"(%class.C* %this, <{ %struct.NonTrivial }>*
> inalloca(<{ %struct.NonTrivial }>) %0)
>  // CHECK-NOT: invoke
> -// CHECK: musttail call x86_thiscallcc void @"?f at C@@EAEXUNonTrivial@@@Z"(%class.C*
> %{{.*}}, <{ %struct.NonTrivial }>* inalloca %0)
> +// CHECK: musttail call x86_thiscallcc void @"?f at 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 8f413021b3d0..dd1c88a65334 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 de7566fcf987..40543c054ea5 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 6be7995f5f01..26c13acf8959 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 at 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 at 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 09a8933c110a..794ca1092eaf 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(<ty>)``
>
>      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
>      <int_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 e35dfddbe043..e751ed90db2a 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 e8ca8a6e81b9..4b13e2d2a9e8 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 d21d65bc4e79..a8c401711858 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<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
>    std::pair<unsigned, unsigned> 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<unsigned, Optional<unsigned>> 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 9f62723646e5..9684ffa0009b 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 ab20cc4b68c8..a24b12c1a470 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<Function> {
>      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 0372da19df55..ee84424b31f6 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(<ty>)
> +bool LLParser::parseInalloca(Type *&Result) {
> +  return parseRequiredTypeAttr(Result, lltok::kw_inalloca);
> +}
> +
>  /// parseByRef
>  ///   ::= byref(<type>)
>  bool LLParser::parseByRef(Type *&Result) {
>
> diff  --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
> index 1205394ff67f..3d9ffe6e90da 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 951e32e36dd6..46db3edcc342 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<uint64_t> 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<uint64_t> Record) {
>
>        Type *PTy = cast<FunctionType>(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<Type *> 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 09f21d26971d..91f8939a8ffa 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 53c2228658b5..60e2ec2c21be 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 831186a49fca..c174e4f93196 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<unsigned> &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<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs()
> const {
>    return SetNode ? SetNode->getAllocSizeArgs()
>                   : std::pair<unsigned, Optional<unsigned>>(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 7389ec6858ed..1001607403d2 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 0a96b29407bb..b6952f703041 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 f9b9b94911a7..1433d074595b 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 ae839bd3a3d3..d8751888ad21 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 000000000000..24fe82baaeff
> --- /dev/null
> +++ b/llvm/test/Assembler/inalloca-parse-error0.ll
> @@ -0,0 +1,6 @@
> +; RUN: not llvm-as < %s 2>&1 | FileCheck %s
> +
> +; CHECK: <stdin>:[[@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 f2203d2609fd..023a528ea7bb 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 000000000000..51012caacddc
> Binary files /dev/null and b/llvm/test/Bitcode/Inputs/inalloca-upgrade.bc
> diff er
>
> diff  --git a/llvm/test/Bitcode/attributes.ll
> b/llvm/test/Bitcode/attributes.ll
> index b8b41e5c4e5c..936a2953901a 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 05e6b71f1477..882f0416e893 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 b31509ec0a86..65dae1b6a755 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 72b01f6a1d98..51b4740ea42e 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 f5b409ab2578..e203e5144c28 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 c7874106d2b9..b0b65fe75da8 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 e63ff3a7cc06..93916d9ff890 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 980dd92563c7..bd5dfd345792 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 34c5cfd41204..95bb2639e09b 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 000000000000..20d41365b360
> --- /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 84abe176d65e..3b56f571b15b 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 f8761bd0ac9b..36510e09beba 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 4e28b5f1a3e9..927956d44129 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 at XZ"(%struct.A*
> returned) #0
>
>
> diff  --git a/llvm/test/CodeGen/X86/inalloca-ctor.ll
> b/llvm/test/CodeGen/X86/inalloca-ctor.ll
> index f13d537d90b8..740c61a3e7d3 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 4623c58210a3..39a9ac5751f2 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 d379333a962f..24a7d17d4b4a 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 69d94d8bfa74..e0a292b866f2 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 at 8
>  ; CHECK-NOT: %esp
>  ; CHECK: pushl
>
> diff  --git a/llvm/test/CodeGen/X86/inalloca.ll
> b/llvm/test/CodeGen/X86/inalloca.ll
> index 134de2f58dda..ed85c79f6d44 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 fa200c2253b9..33e11235fe83 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 c0e571a7213b..f3e27fac3a9d 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 f30d775a343b..cb7a31433e27 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 682f85e1eb85..b9994963132c 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 32e046df6bb0..241d42c3227b 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 34db632ec205..e4b9dada399d 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 at 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 91bce1610c8b..110691504655 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 ce5e583f9115..d6920a7f9a59 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 434e4be4e8e6..257c0cbf0c7e 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 000000000000..7fa2d8fdb3f3
> --- /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 000000000000..36cc9c3f7ef4
> --- /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 d9f3681ba4ab..0643397be099 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 ebf3d18f2fc5..7eaa7499af6b 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 9937e6cf2072..ad452d68acbd 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 30575fe8bde9..0b82eac6b982 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 9f28407c76c4..c440e12ddfce 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 41fa16c0284a..0ed93a912789 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 fff14a7f52a8..b9be83e5cdf9 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 48a939c1228f..361b243f5121 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 ae34219bd011..6585ee4d2448 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 2c588283ea91..d8bad7ae4563 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 edd0688ea92b..0278d83d209f 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 74b5ecf420ce..1a6dd75a0178 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 at 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 at XZ"(%struct.Foo* %o)
>
> diff  --git a/llvm/test/Transforms/InstCombine/alloca.ll
> b/llvm/test/Transforms/InstCombine/alloca.ll
> index 072d5f2fe9f9..fee8e0ef70f1 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 90289e2468f8..bbf2008d5854 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 9eb0efb1911b..cbc353afe619 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           ; <i8*> [#uses=1]
>         %tmp78 = call i8* @llvm.stacksave( )            ; <i8*> [#uses=1]
>         %tmp102 = alloca i8, i32 %size          ; <i8*> [#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 38ce3772e765..1f5c8da7654a 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 b9b4c5027a19..61f1c68cd5b3 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 2f22ee37292e..d5921bf5b261 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 e2b4519b17cb..6344371bba5e 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 428f89ec88f1..de7622b638d8 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 7ee2cba5ac17..76da66adc798 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 12a454999285..21fc2517cd0a 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 c09ce100849b..28cdbfef9785 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 7b199cd6d2de..2ece2dd1a9ac 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 2c191264a892..11b159897989 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 6bab80215c0b..34802b63aae8 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()
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210330/6fccd940/attachment-0001.html>


More information about the cfe-commits mailing list