[llvm] [DeadStoreElimination] Optimize tautological assignments (PR #75744)

Shreyansh Chouhan via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 07:21:47 PST 2023


================
@@ -1926,6 +1926,43 @@ struct DSEState {
       if (InitC && InitC == StoredConstant)
         return MSSA.isLiveOnEntryDef(
             MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA));
+
+      if (!Store)
+        return false;
+
+      // If there is a dominating condition, that ensures that the value
+      // being stored in a memory location is already present at the
+      // memory location, the store is a noop.
+      BasicBlock *StoreBB = DefI->getParent();
+      auto *StorePtr = Store->getOperand(1);
+
+      DomTreeNode *IDom = DT.getNode(StoreBB)->getIDom();
+      if (!IDom)
+        return false;
+
+      auto *TI = IDom->getBlock()->getTerminator();
+      ICmpInst::Predicate Pred;
+      BasicBlock *TrueBB, *FalseBB;
+
+      if (!match(TI, m_Br(m_ICmp(Pred, m_Load(m_Specific(StorePtr)),
+                                 m_Specific(StoredConstant)),
+                          TrueBB, FalseBB)))
+        return false;
+
+      MemoryAccess *LastMod =
+          MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA);
+
+      DomTreeNode *CDom = DT.getNode(LastMod->getBlock());
----------------
BK1603 wrote:

Hi @nikic, while trying to test for this specific scenario I came accross the following observation:

If we have:
```
; *** IR Dump Before EarlyCSEPass on foo ***
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none, inaccessiblemem: none) uwtable
define dso_local void @foo() local_unnamed_addr #0 {
  %1 = load i32, ptr @x, align 4, !tbaa !3
  store i32 7, ptr @x, align 4, !tbaa !3
  %2 = icmp eq i32 %1, 4
  %spec.store.select = select i1 %2, i32 4, i32 7
  store i32 %spec.store.select, ptr @x, align 4
  ret void
}
```

The EarlyCSEPass optimizes it to:
```
EarlyCSE DEAD STORE:   store i32 7, ptr @x, align 4, !tbaa !3  due to:   store i32 %spec.store.select, ptr @x, align 4
; *** IR Dump After EarlyCSEPass on foo ***
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: none, inaccessiblemem: none) uwtable
define dso_local void @foo() local_unnamed_addr #0 {
  %1 = load i32, ptr @x, align 4, !tbaa !3
  %2 = icmp eq i32 %1, 4
  %spec.store.select = select i1 %2, i32 4, i32 7
  store i32 %spec.store.select, ptr @x, align 4
  ret void
}
```

And calls the clobbering store after `load` a "dead store". Is this expected? 
If it is then the clobber that you mentioned would be optimized away as well wouldn't it? Please let me know if I'm misunderstanding something here.

https://github.com/llvm/llvm-project/pull/75744


More information about the llvm-commits mailing list