forked from OSchip/llvm-project
Fix an assertion in MemCpyOpt pass.
The MemCpyOpt pass is capable of optimizing: callee(&S); copy N bytes from S to D. into: callee(&D); subject to some legality constraints. Assertion is triggered when the compiler tries to evalute "sizeof(typeof(D))", while D is an opaque-typed, 'sret' formal argument of function being compiled. i.e. the signature of the func being compiled is something like this: T caller(...,%opaque* noalias nocapture sret %D, ...) The fix is that when come across such situation, instead of calling some utility functions to get the size of D's type (which will crash), we simply assume D has at least N bytes as implified by the copy-instruction. rdar://14073661 llvm-svn: 183584
This commit is contained in:
parent
f60b8ceb7e
commit
bd254f2601
|
@ -626,8 +626,10 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
|
|||
return false;
|
||||
|
||||
Type *StructTy = cast<PointerType>(A->getType())->getElementType();
|
||||
uint64_t destSize = TD->getTypeAllocSize(StructTy);
|
||||
|
||||
// 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 (destSize < srcSize)
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
@ -168,6 +168,45 @@ entry:
|
|||
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* %a
|
||||
%d = bitcast %opaque* %x to i32*
|
||||
store i32 %c, i32* %d
|
||||
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*)
|
||||
|
||||
|
|
Loading…
Reference in New Issue