diff options
-rw-r--r-- | lib/Transforms/Scalar/ScalarReplAggregates.cpp | 16 | ||||
-rw-r--r-- | test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll | 18 |
2 files changed, 28 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 9e1e79a..336da50 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -752,9 +752,16 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, } break; } - // If OtherPtr has already been rewritten, this intrinsic will be dead. - if (OtherPtr == NewElts[0]) + // Copying the alloca to itself is a no-op: just delete it. + if (OtherPtr == AI || OtherPtr == NewElts[0]) { + // This code will run twice for a no-op memcpy -- once for each operand. + // Put only one reference to MI on the DeadInsts list. + for (SmallVector<Value*, 32>::const_iterator I = DeadInsts.begin(), + E = DeadInsts.end(); I != E; ++I) + if (*I == MI) return; + DeadInsts.push_back(MI); return; + } if (ConstantExpr *BCE = dyn_cast<ConstantExpr>(OtherPtr)) if (BCE->getOpcode() == Instruction::BitCast) @@ -779,10 +786,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, Value *OtherElt = 0; unsigned OtherEltAlign = MemAlignment; - if (OtherPtr == AI) { - OtherElt = NewElts[i]; - OtherEltAlign = 0; - } else if (OtherPtr) { + if (OtherPtr) { Value *Idx[2] = { Zero, ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) }; OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx, Idx + 2, diff --git a/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll b/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll new file mode 100644 index 0000000..74cf251 --- /dev/null +++ b/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +; Radar 7552893 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" + +%struct.test = type { [3 x double ] } + +define arm_apcscc void @test_memcpy_self() nounwind { +; CHECK: @test_memcpy_self +; CHECK-NOT: alloca +; CHECK: ret void + %1 = alloca %struct.test + %2 = bitcast %struct.test* %1 to i8* + call void @llvm.memcpy.i32(i8* %2, i8* %2, i32 24, i32 4) + ret void +} + +declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind |