}
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)
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,
--- /dev/null
+; 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