Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 9792b64

Browse files
author
Shuxin Yang
committed
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183606 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent dbfb960 commit 9792b64

File tree

2 files changed

+8
-26
lines changed

2 files changed

+8
-26
lines changed

Diff for: lib/Transforms/Scalar/MemCpyOptimizer.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -626,10 +626,14 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
626626
return false;
627627

628628
Type *StructTy = cast<PointerType>(A->getType())->getElementType();
629-
// If StructTy is an opaque type, it should have at least <cpyLen> bytes,
630-
// as implified by the copy-instruction.
631-
uint64_t destSize = StructTy->isSized() ?
632-
TD->getTypeAllocSize(StructTy) : cpyLen;
629+
if (!StructTy->isSized()) {
630+
// The call may never return and hence the copy-instruction may never
631+
// be executed, and therefore it's not safe to say "the destination
632+
// has at least <cpyLen> bytes, as implied by the copy-instruction",
633+
return false;
634+
}
635+
636+
uint64_t destSize = TD->getTypeAllocSize(StructTy);
633637
if (destSize < srcSize)
634638
return false;
635639
} else {

Diff for: test/Transforms/MemCpyOpt/memcpy.ll

-22
Original file line numberDiff line numberDiff line change
@@ -185,28 +185,6 @@ define void @test10(%opaque* noalias nocapture sret %x, i32 %y) {
185185
ret void
186186
}
187187

188-
; Test11 is similar to test10 except that the instruction "store i32 %y, i32* %a"
189-
; before the call-site is deleted. MemCopyOpt is able to optimize this snippet into
190-
;
191-
; %x1 = bitcast %opaque* %x to i32*
192-
; call void @foo(i32* noalias nocapture %x1)
193-
; ret void
194-
;
195-
196-
define void @test11(%opaque* noalias nocapture sret %x, i32 %y) {
197-
; CHECK: test11
198-
; CHECK: %x1 = bitcast %opaque* %x to i32*
199-
; CHECK: call void @foo(i32* noalias nocapture %x1)
200-
; CHECK: ret void
201-
202-
%a = alloca i32, align 4
203-
call void @foo(i32* noalias nocapture %a)
204-
%c = load i32* %a
205-
%d = bitcast %opaque* %x to i32*
206-
store i32 %c, i32* %d
207-
ret void
208-
}
209-
210188
declare void @f1(%struct.big* sret)
211189
declare void @f2(%struct.big*)
212190

0 commit comments

Comments
 (0)