[llvm] r183584 - Fix an assertion in MemCpyOpt pass.
Shuxin Yang
shuxin.llvm at gmail.com
Fri Jun 7 15:45:21 PDT 2013
Author: shuxin_yang
Date: Fri Jun 7 17:45:21 2013
New Revision: 183584
URL: http://llvm.org/viewvc/llvm-project?rev=183584&view=rev
Log:
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
Modified:
llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll
Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=183584&r1=183583&r2=183584&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Fri Jun 7 17:45:21 2013
@@ -626,8 +626,10 @@ bool MemCpyOpt::performCallSlotOptzn(Ins
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 {
Modified: llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll?rev=183584&r1=183583&r2=183584&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll (original)
+++ llvm/trunk/test/Transforms/MemCpyOpt/memcpy.ll Fri Jun 7 17:45:21 2013
@@ -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*)
More information about the llvm-commits
mailing list