[llvm] cd8f3e7 - [DSE] Eliminate noop store even through has clobbering between LoadI and StoreI

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 1 23:41:18 PDT 2022


Author: luxufan
Date: 2022-09-02T06:37:41Z
New Revision: cd8f3e75813995c1d2da35370ffcf5af3aff9c2f

URL: https://github.com/llvm/llvm-project/commit/cd8f3e75813995c1d2da35370ffcf5af3aff9c2f
DIFF: https://github.com/llvm/llvm-project/commit/cd8f3e75813995c1d2da35370ffcf5af3aff9c2f.diff

LOG: [DSE] Eliminate noop store even through has clobbering between LoadI and StoreI

For noop store of the form of LoadI and StoreI,
An invariant should be kept is that the memory state of the related
MemoryLoc before LoadI is the same as before StoreI.
For this example:
```
define void @pr49927(i32* %q, i32* %p) {
  %v = load i32, i32* %p, align 4
  store i32 %v, i32* %q, align 4
  store i32 %v, i32* %p, align 4
  ret void
}
```
Here the definition of the store's destination is different with the
definition of the load's destination, which it seems that the
invariant mentioned above is broken. But the definition of the
store's destination would write a value that is LoadI, actually, the
invariant is still kept. So we can safely ignore it.

Differential Revision: https://reviews.llvm.org/D132657

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
    llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 45c404a140af3..d24c5a25abf61 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1864,8 +1864,16 @@ struct DSEState {
           // We are searching for the definition of the store's destination.
           // So, if that is the same definition as the load, then this is a
           // noop. Otherwise, fail.
-          if (LoadAccess != Current)
+          if (LoadAccess != Current) {
+            auto *CurrentStoreI =
+                dyn_cast<StoreInst>(cast<MemoryDef>(Current)->getMemoryInst());
+            if (CurrentStoreI && CurrentStoreI->getOperand(0) == LoadI) {
+              // This is a potentially clobbering store, but it writes the same value,
+              // so we can safely ignore it.
+              continue;
+            }
             return false;
+          }
         }
         return true;
       }

diff  --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
index e5630cca1aba5..06a5f8690c26a 100644
--- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
+++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll
@@ -612,12 +612,10 @@ define void @pr49927(i32* %q, i32* %p) {
 ; CHECK-LABEL: @pr49927(
 ; CHECK-NEXT:    [[V:%.*]] = load i32, i32* [[P:%.*]], align 4
 ; CHECK-NEXT:    store i32 [[V]], i32* [[Q:%.*]], align 4
-; CHECK-NEXT:    store i32 [[V]], i32* [[P]], align 4
 ; CHECK-NEXT:    ret void
 ;
   %v = load i32, i32* %p, align 4
   store i32 %v, i32* %q, align 4
-  ; FIXME: this store can be eliminated
   store i32 %v, i32* %p, align 4
   ret void
 }


        


More information about the llvm-commits mailing list