@@ -1901,6 +1901,58 @@ struct DSEState {
1901
1901
return true ;
1902
1902
}
1903
1903
1904
+ // Check if there is a dominating condition, that implies that the value
1905
+ // being stored in a ptr is already present in the ptr.
1906
+ bool dominatingConditionImpliesValue (MemoryDef *Def) {
1907
+ auto *StoreI = dyn_cast<StoreInst>(Def->getMemoryInst ());
1908
+ BasicBlock *StoreBB = StoreI->getParent ();
1909
+ Value *StorePtr = StoreI->getPointerOperand ();
1910
+ Value *StoreVal = StoreI->getValueOperand ();
1911
+
1912
+ DomTreeNode *IDom = DT.getNode (StoreBB)->getIDom ();
1913
+ if (!IDom)
1914
+ return false ;
1915
+
1916
+ auto *BI = dyn_cast<BranchInst>(IDom->getBlock ()->getTerminator ());
1917
+ if (!BI || !BI->isConditional ())
1918
+ return false ;
1919
+
1920
+ // In case both blocks are the same, it is not possible to determine
1921
+ // if optimization is possible. (We would not want to optimize a store
1922
+ // in the FalseBB if condition is true and vice versa.)
1923
+ if (BI->getSuccessor (0 ) == BI->getSuccessor (1 ))
1924
+ return false ;
1925
+
1926
+ // In case the else blocks also branches to the if block or the other way
1927
+ // around it is not possible to determine if the optimization is possible.
1928
+
1929
+ Instruction *ICmpL;
1930
+ ICmpInst::Predicate Pred;
1931
+ if (!match (BI->getCondition (),
1932
+ m_c_ICmp (Pred,
1933
+ m_CombineAnd (m_Load (m_Specific (StorePtr)),
1934
+ m_Instruction (ICmpL)),
1935
+ m_Specific (StoreVal))) ||
1936
+ !ICmpInst::isEquality (Pred))
1937
+ return false ;
1938
+
1939
+ if (Pred == ICmpInst::ICMP_EQ &&
1940
+ !DT.dominates (BasicBlockEdge (BI->getParent (), BI->getSuccessor (0 )),
1941
+ StoreBB))
1942
+ return false ;
1943
+
1944
+ if (Pred == ICmpInst::ICMP_NE &&
1945
+ !DT.dominates (BasicBlockEdge (BI->getParent (), BI->getSuccessor (1 )),
1946
+ StoreBB))
1947
+ return false ;
1948
+
1949
+ MemoryAccess *LoadAcc = MSSA.getMemoryAccess (ICmpL);
1950
+ MemoryAccess *ClobAcc =
1951
+ MSSA.getSkipSelfWalker ()->getClobberingMemoryAccess (Def, BatchAA);
1952
+
1953
+ return MSSA.dominates (ClobAcc, LoadAcc);
1954
+ }
1955
+
1904
1956
// / \returns true if \p Def is a no-op store, either because it
1905
1957
// / directly stores back a loaded value or stores zero to a calloced object.
1906
1958
bool storeIsNoop (MemoryDef *Def, const Value *DefUO) {
@@ -1931,6 +1983,9 @@ struct DSEState {
1931
1983
if (!Store)
1932
1984
return false ;
1933
1985
1986
+ if (dominatingConditionImpliesValue (Def))
1987
+ return true ;
1988
+
1934
1989
if (auto *LoadI = dyn_cast<LoadInst>(Store->getOperand (0 ))) {
1935
1990
if (LoadI->getPointerOperand () == Store->getOperand (1 )) {
1936
1991
// Get the defining access for the load.
0 commit comments