diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 8600c9ebf79..c3259254f8b 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -626,10 +626,14 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy, return false; Type *StructTy = cast(A->getType())->getElementType(); - // If StructTy is an opaque type, it should have at least bytes, - // as implified by the copy-instruction. - uint64_t destSize = StructTy->isSized() ? - TD->getTypeAllocSize(StructTy) : cpyLen; + 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 = TD->getTypeAllocSize(StructTy); if (destSize < srcSize) return false; } else { diff --git a/test/Transforms/MemCpyOpt/memcpy.ll b/test/Transforms/MemCpyOpt/memcpy.ll index fa768712ec9..148623a6ce7 100644 --- a/test/Transforms/MemCpyOpt/memcpy.ll +++ b/test/Transforms/MemCpyOpt/memcpy.ll @@ -185,28 +185,6 @@ define void @test10(%opaque* noalias nocapture sret %x, i32 %y) { ret void } -; Test11 is similar to test10 except that the instruction "store i32 %y, i32* %a" -; before the call-site is deleted. MemCopyOpt is able to optimize this snippet into -; -; %x1 = bitcast %opaque* %x to i32* -; call void @foo(i32* noalias nocapture %x1) -; ret void -; - -define void @test11(%opaque* noalias nocapture sret %x, i32 %y) { -; CHECK: test11 -; CHECK: %x1 = bitcast %opaque* %x to i32* -; CHECK: call void @foo(i32* noalias nocapture %x1) -; CHECK: ret void - - %a = alloca i32, align 4 - call void @foo(i32* noalias nocapture %a) - %c = load i32* %a - %d = bitcast %opaque* %x to i32* - store i32 %c, i32* %d - ret void -} - declare void @f1(%struct.big* sret) declare void @f2(%struct.big*)