Index: llvm/lib/IR/Value.cpp =================================================================== --- llvm/lib/IR/Value.cpp +++ llvm/lib/IR/Value.cpp @@ -715,10 +715,8 @@ if (DerefBytes == 0) { // Handle byval/byref/inalloca/preallocated arguments if (Type *ArgMemTy = A->getPointeeInMemoryValueType()) { - if (ArgMemTy->isSized()) { - // FIXME: Why isn't this the type alloc size? - DerefBytes = DL.getTypeStoreSize(ArgMemTy).getKnownMinSize(); - } + // FIXME: Why isn't this the type alloc size? + DerefBytes = DL.getTypeStoreSize(ArgMemTy).getKnownMinSize(); } } @@ -810,8 +808,7 @@ if (!Alignment && A->hasStructRetAttr()) { // An sret parameter has at least the ABI alignment of the return type. Type *EltTy = A->getParamStructRetType(); - if (EltTy->isSized()) - return DL.getABITypeAlign(EltTy); + return DL.getABITypeAlign(EltTy); } return Alignment.valueOrOne(); } else if (const AllocaInst *AI = dyn_cast(this)) { Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -1744,10 +1744,11 @@ SmallPtrSet Visited; if (!PTy->getElementType()->isSized(&Visited)) { Assert(!Attrs.hasAttribute(Attribute::ByVal) && + !Attrs.hasAttribute(Attribute::StructRet) && !Attrs.hasAttribute(Attribute::ByRef) && !Attrs.hasAttribute(Attribute::InAlloca) && !Attrs.hasAttribute(Attribute::Preallocated), - "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not " + "Attributes 'byval', 'sret', 'byref', 'inalloca', and 'preallocated' do not " "support unsized types!", V); } Index: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -814,13 +814,6 @@ return false; Type *StructTy = A->getParamStructRetType(); - if (!StructTy->isSized()) { - // The call may never return and hence the copy-instruction may never - // be executed, and therefore it's not safe to say "the destination - // has at least bytes, as implied by the copy-instruction", - return false; - } - uint64_t destSize = DL.getTypeAllocSize(StructTy); if (destSize < srcSize) return false; Index: llvm/test/Transforms/MemCpyOpt/memcpy.ll =================================================================== --- llvm/test/Transforms/MemCpyOpt/memcpy.ll +++ llvm/test/Transforms/MemCpyOpt/memcpy.ll @@ -215,23 +215,6 @@ ret void } -; rdar://14073661. -; Test10 triggered assertion when the compiler try to get the size of the -; opaque type of *x, where the x is the formal argument with attribute 'sret'. - -%opaque = type opaque -declare void @foo(i32* noalias nocapture) - -define void @test10(%opaque* noalias nocapture sret %x, i32 %y) { - %a = alloca i32, align 4 - store i32 %y, i32* %a - call void @foo(i32* noalias nocapture %a) - %c = load i32, i32* %a - %d = bitcast %opaque* %x to i32* - store i32 %c, i32* %d - ret void -} - ; don't create new addressspacecasts when we don't know they're safe for the target define void @test11([20 x i32] addrspace(1)* nocapture dereferenceable(80) %P) { %A = alloca [20 x i32], align 4 Index: llvm/test/Transforms/MergeFunc/apply_function_attributes.ll =================================================================== --- llvm/test/Transforms/MergeFunc/apply_function_attributes.ll +++ llvm/test/Transforms/MergeFunc/apply_function_attributes.ll @@ -1,12 +1,12 @@ ; RUN: opt -S -mergefunc < %s | FileCheck %s -%Opaque_type = type opaque +%Empty_type = type {} %S2i = type <{ i64, i64 }> %D2i = type <{ i64, i64 }> %Di = type <{ i32 }> %Si = type <{ i32 }> -define void @B(%Opaque_type* sret %a, %S2i* %b, i32* %xp, i32* %yp) { +define void @B(%Empty_type* sret %a, %S2i* %b, i32* %xp, i32* %yp) { %x = load i32, i32* %xp %y = load i32, i32* %yp %sum = add i32 %x, %y @@ -15,7 +15,7 @@ ret void } -define void @C(%Opaque_type* sret %a, %S2i* %b, i32* %xp, i32* %yp) { +define void @C(%Empty_type* sret %a, %S2i* %b, i32* %xp, i32* %yp) { %x = load i32, i32* %xp %y = load i32, i32* %yp %sum = add i32 %x, %y @@ -24,7 +24,7 @@ ret void } -define void @A(%Opaque_type* sret %a, %D2i* %b, i32* %xp, i32* %yp) { +define void @A(%Empty_type* sret %a, %D2i* %b, i32* %xp, i32* %yp) { %x = load i32, i32* %xp %y = load i32, i32* %yp %sum = add i32 %x, %y @@ -34,14 +34,14 @@ } ; Make sure we transfer the parameter attributes to the call site. -; CHECK-LABEL: define void @C(%Opaque_type* sret -; CHECK: tail call void bitcast (void (%Opaque_type*, %D2i*, i32*, i32*)* @A to void (%Opaque_type*, %S2i*, i32*, i32*)*)(%Opaque_type* sret %0, %S2i* %1, i32* %2, i32* %3) +; CHECK-LABEL: define void @C(%Empty_type* sret +; CHECK: tail call void bitcast (void (%Empty_type*, %D2i*, i32*, i32*)* @A to void (%Empty_type*, %S2i*, i32*, i32*)*)(%Empty_type* sret %0, %S2i* %1, i32* %2, i32* %3) ; CHECK: ret void ; Make sure we transfer the parameter attributes to the call site. -; CHECK-LABEL: define void @B(%Opaque_type* sret +; CHECK-LABEL: define void @B(%Empty_type* sret ; CHECK: %5 = bitcast -; CHECK: tail call void @A(%Opaque_type* sret %0, %D2i* %5, i32* %2, i32* %3) +; CHECK: tail call void @A(%Empty_type* sret %0, %D2i* %5, i32* %2, i32* %3) ; CHECK: ret void Index: llvm/test/Verifier/byref.ll =================================================================== --- llvm/test/Verifier/byref.ll +++ llvm/test/Verifier/byref.ll @@ -14,7 +14,7 @@ %opaque.ty = type opaque -; CHECK: Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not support unsized types! +; CHECK: Attributes 'byval', 'sret', 'byref', 'inalloca', and 'preallocated' do not support unsized types! ; CHECK-NEXT: void (%opaque.ty*)* @byref_unsized define void @byref_unsized(%opaque.ty* byref(%opaque.ty)) { ret void Index: llvm/test/Verifier/sret.ll =================================================================== --- llvm/test/Verifier/sret.ll +++ llvm/test/Verifier/sret.ll @@ -5,3 +5,8 @@ declare void @b(i32* %a, i32* %b, i32* sret %c) ; CHECK: Attribute 'sret' is not on first or second parameter! + +%opaque.ty = type opaque + +declare void @c(%opaque.ty* sret %a) +; CHECK: Attributes 'byval', 'sret', 'byref', 'inalloca', and 'preallocated' do not support unsized types!