summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorShuxin Yang <shuxin.llvm@gmail.com>2013-06-08 04:56:05 +0000
committerShuxin Yang <shuxin.llvm@gmail.com>2013-06-08 04:56:05 +0000
commit140d592d8481be67d4886f9d1b9dec1a5cd531b0 (patch)
tree8857e6f54e5886ac4eccfb33c21e0dbc55d83892 /llvm
parent4bf5c4b7460ca7e663d0ae8f3011a019812544b3 (diff)
downloadbcm5719-llvm-140d592d8481be67d4886f9d1b9dec1a5cd531b0.tar.gz
bcm5719-llvm-140d592d8481be67d4886f9d1b9dec1a5cd531b0.zip
Fix a potential bug in r183584.
r183584 tries to derive some info from the code *AFTER* a call and apply these derived info to the code *BEFORE* the call, which is not always safe as the call in question may never return, and in this case, the derived info is invalid. Thank Duncan for pointing out this potential bug. rdar://14073661 llvm-svn: 183606
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp12
-rw-r--r--llvm/test/Transforms/MemCpyOpt/memcpy.ll22
2 files changed, 8 insertions, 26 deletions
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 8600c9ebf79..c3259254f8b 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -626,10 +626,14 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
return false;
Type *StructTy = cast<PointerType>(A->getType())->getElementType();
- // If StructTy is an opaque type, it should have at least <cpyLen> 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 <cpyLen> bytes, as implied by the copy-instruction",
+ return false;
+ }
+
+ uint64_t destSize = TD->getTypeAllocSize(StructTy);
if (destSize < srcSize)
return false;
} else {
diff --git a/llvm/test/Transforms/MemCpyOpt/memcpy.ll b/llvm/test/Transforms/MemCpyOpt/memcpy.ll
index fa768712ec9..148623a6ce7 100644
--- a/llvm/test/Transforms/MemCpyOpt/memcpy.ll
+++ b/llvm/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*)
OpenPOWER on IntegriCloud