[llvm] r256923 - Improve load/store to memcpy for aggregate

Amaury Sechet via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 6 01:30:40 PST 2016


Author: deadalnix
Date: Wed Jan  6 03:30:39 2016
New Revision: 256923

URL: http://llvm.org/viewvc/llvm-project?rev=256923&view=rev
Log:
Improve load/store to memcpy for aggregate

Summary: It turns out that if we don't try to do it at the store location, we can do it before any operation that alias the load, as long as no operation alias the store.

Reviewers: craig.topper, spatel, dexonsmith, Prazek, chandlerc, joker.eph

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D15903

Modified:
    llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    llvm/trunk/test/Transforms/MemCpyOpt/fca2memcpy.ll

Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=256923&r1=256922&r2=256923&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Wed Jan  6 03:30:39 2016
@@ -519,19 +519,33 @@ bool MemCpyOpt::processStore(StoreInst *
 
         // We use alias analysis to check if an instruction may store to
         // the memory we load from in between the load and the store. If
-        // such an instruction is found, we store it in AI.
-        Instruction *AI = nullptr;
+        // such an instruction is found, we try to promote there instead
+        // of at the store position.
+        Instruction *P = SI;
         for (BasicBlock::iterator I = ++LI->getIterator(), E = SI->getIterator();
              I != E; ++I) {
-          if (AA.getModRefInfo(&*I, LoadLoc) & MRI_Mod) {
-            AI = &*I;
-            break;
+          if (!(AA.getModRefInfo(&*I, LoadLoc) & MRI_Mod))
+            continue;
+
+          // We found an instruction that may write to the loaded memory.
+          // We can try to promote at this position instead of the store
+          // position if nothing alias the store memory after this.
+          P = &*I;
+          for (; I != E; ++I) {
+            MemoryLocation StoreLoc = MemoryLocation::get(SI);
+            if (AA.getModRefInfo(&*I, StoreLoc) != MRI_NoModRef) {
+              DEBUG(dbgs() << "Alias " << *I << "\n");
+              P = nullptr;
+              break;
+            }
           }
+
+          break;
         }
 
-        // If no aliasing instruction is found, then we can promote the
-        // load/store pair to a memcpy at the store loaction.
-        if (!AI) {
+        // If a valid insertion position is found, then we can promote
+        // the load/store pair to a memcpy.
+        if (P) {
           // If we load from memory that may alias the memory we store to,
           // memmove must be used to preserve semantic. If not, memcpy can
           // be used.
@@ -542,7 +556,7 @@ bool MemCpyOpt::processStore(StoreInst *
           unsigned Align = findCommonAlignment(DL, SI, LI);
           uint64_t Size = DL.getTypeStoreSize(T);
 
-          IRBuilder<> Builder(SI);
+          IRBuilder<> Builder(P);
           Instruction *M;
           if (UseMemMove)
             M = Builder.CreateMemMove(SI->getPointerOperand(),

Modified: llvm/trunk/test/Transforms/MemCpyOpt/fca2memcpy.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/fca2memcpy.ll?rev=256923&r1=256922&r2=256923&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/MemCpyOpt/fca2memcpy.ll (original)
+++ llvm/trunk/test/Transforms/MemCpyOpt/fca2memcpy.ll Wed Jan  6 03:30:39 2016
@@ -7,6 +7,7 @@ target triple = "x86_64-unknown-linux-gn
 
 define void @copy(%S* %src, %S* %dst) {
 ; CHECK-LABEL: copy
+; CHECK-NOT: load
 ; CHECK: call void @llvm.memmove.p0i8.p0i8.i64
 ; CHECK-NEXT: ret void
   %1 = load %S, %S* %src
@@ -16,6 +17,7 @@ define void @copy(%S* %src, %S* %dst) {
 
 define void @noaliassrc(%S* noalias %src, %S* %dst) {
 ; CHECK-LABEL: noaliassrc
+; CHECK-NOT: load
 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
 ; CHECK-NEXT: ret void
   %1 = load %S, %S* %src
@@ -25,12 +27,35 @@ define void @noaliassrc(%S* noalias %src
 
 define void @noaliasdst(%S* %src, %S* noalias %dst) {
 ; CHECK-LABEL: noaliasdst
+; CHECK-NOT: load
 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
 ; CHECK-NEXT: ret void
   %1 = load %S, %S* %src
   store %S %1, %S* %dst
   ret void
 }
+
+define void @destroysrc(%S* %src, %S* %dst) {
+; CHECK-LABEL: destroysrc
+; CHECK-NOT: call
+; CHECK: ret void
+  %1 = load %S, %S* %src
+  store %S zeroinitializer, %S* %src
+  store %S %1, %S* %dst
+  ret void
+}
+
+define void @destroynoaliassrc(%S* noalias %src, %S* %dst) {
+; CHECK-LABEL: destroynoaliassrc
+; CHECK-NOT: load
+; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+; CHECK-NEXT: store %S zeroinitializer, %S* %src
+; CHECK-NEXT: ret void
+  %1 = load %S, %S* %src
+  store %S zeroinitializer, %S* %src
+  store %S %1, %S* %dst
+  ret void
+}
 
 define void @copyalias(%S* %src, %S* %dst) {
 ; CHECK-LABEL: copyalias




More information about the llvm-commits mailing list