[llvm-commits] [llvm] r93848 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll

Bob Wilson bob.wilson at apple.com
Mon Jan 18 20:32:50 PST 2010


Author: bwilson
Date: Mon Jan 18 22:32:48 2010
New Revision: 93848

URL: http://llvm.org/viewvc/llvm-project?rev=93848&view=rev
Log:
Fix a crash in scalarrepl for memcpy/memmove where the source and destination
are the same.  I had already fixed a similar problem where the source and
destination were different bitcasts derived from the same alloca, but the
previous fix still did not handle the case where both operands are exactly
the same value.  Radar 7552893.

Added:
    llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=93848&r1=93847&r2=93848&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Mon Jan 18 22:32:48 2010
@@ -752,9 +752,16 @@
       }
       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 @@
     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,

Added: llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll?rev=93848&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll (added)
+++ llvm/trunk/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll Mon Jan 18 22:32:48 2010
@@ -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





More information about the llvm-commits mailing list