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

Shreyansh Chouhan via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 17 09:43:41 PST 2023


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

If a store is dominated by a condition that ensures that the value being stored in a memory location is already present at that memory location, consider the store a noop.

Fixes #63419

Needed help with two things:
1. I feel that the code can be written in a separate function, but I was not able to come up with a succinct name for it 😅 
2. How do I go about writing a test for this. I tried writing a separate one and calling `update_test_checks.py` but the script crashed when it tried to run opt it seems:
```
bk1603 at 192 /w/llvm-project (DeadStoreEliminationOpt) [1]> /work/llvm-project/llvm/utils/update_test_checks.py /work/llvm-project/llvm/test/Transforms/DeadStoreElimination/assume.ll
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: opt -passes=dse -S
^CTraceback (most recent call last):
  File "/work/llvm-project/llvm/utils/update_test_checks.py", line 333, in <module>
    main()
  File "/work/llvm-project/llvm/utils/update_test_checks.py", line 157, in main
    raw_tool_output = common.invoke_tool(
                      ^^^^^^^^^^^^^^^^^^^
  File "/work/llvm-project/llvm/utils/UpdateTestChecks/common.py", line 465, in invoke_tool
    stdout = subprocess.check_output(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/subprocess.py", line 466, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/subprocess.py", line 550, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/subprocess.py", line 1196, in communicate
    stdout = self.stdout.read()
             ^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
```

cc @nikic for review

>From 8bc635a2cb310aeecf96cc67bffbcb841c16a29a Mon Sep 17 00:00:00 2001
From: Shreyansh Chouhan <chouhan.shreyansh2702 at gmail.com>
Date: Sun, 17 Dec 2023 22:48:51 +0530
Subject: [PATCH] [DeadStoreElimination] Optimize tautological assignments

If a store is immediately dominated by a condition that ensures that the value
being stored in a memory location is already present at that memory location,
consider the store a noop.

Fixes #63419
---
 .../Scalar/DeadStoreElimination.cpp           | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index dd0a290252dae3..0455fa1770e50a 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -1926,6 +1926,36 @@ struct DSEState {
       if (InitC && InitC == StoredConstant)
         return MSSA.isLiveOnEntryDef(
             MSSA.getSkipSelfWalker()->getClobberingMemoryAccess(Def, BatchAA));
+
+      // 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();
+      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());
+      if (!DT.dominates(CDom, IDom))
+        return false;
+
+      if (Pred == ICmpInst::ICMP_EQ && StoreBB == TrueBB)
+        return true;
+
+      if (Pred == ICmpInst::ICMP_NE && StoreBB == FalseBB)
+        return true;
+
+      return false;
     }
 
     if (!Store)



More information about the llvm-commits mailing list