@@ -1901,6 +1901,57 @@ 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 = 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
+ Instruction *ICmpL;
1927
+ ICmpInst::Predicate Pred;
1928
+ if (!match (BI->getCondition (),
1929
+ m_c_ICmp (Pred,
1930
+ m_CombineAnd (m_Load (m_Specific (StorePtr)),
1931
+ m_Instruction (ICmpL)),
1932
+ m_Specific (StoreVal))) ||
1933
+ !ICmpInst::isEquality (Pred))
1934
+ return false ;
1935
+
1936
+ // In case the else blocks also branches to the if block or the other way
1937
+ // around it is not possible to determine if the optimization is possible.
1938
+ if (Pred == ICmpInst::ICMP_EQ &&
1939
+ !DT.dominates (BasicBlockEdge (BI->getParent (), BI->getSuccessor (0 )),
1940
+ StoreBB))
1941
+ return false ;
1942
+
1943
+ if (Pred == ICmpInst::ICMP_NE &&
1944
+ !DT.dominates (BasicBlockEdge (BI->getParent (), BI->getSuccessor (1 )),
1945
+ StoreBB))
1946
+ return false ;
1947
+
1948
+ MemoryAccess *LoadAcc = MSSA.getMemoryAccess (ICmpL);
1949
+ MemoryAccess *ClobAcc =
1950
+ MSSA.getSkipSelfWalker ()->getClobberingMemoryAccess (Def, BatchAA);
1951
+
1952
+ return MSSA.dominates (ClobAcc, LoadAcc);
1953
+ }
1954
+
1904
1955
// / \returns true if \p Def is a no-op store, either because it
1905
1956
// / directly stores back a loaded value or stores zero to a calloced object.
1906
1957
bool storeIsNoop (MemoryDef *Def, const Value *DefUO) {
@@ -1931,6 +1982,9 @@ struct DSEState {
1931
1982
if (!Store)
1932
1983
return false ;
1933
1984
1985
+ if (dominatingConditionImpliesValue (Def))
1986
+ return true ;
1987
+
1934
1988
if (auto *LoadI = dyn_cast<LoadInst>(Store->getOperand (0 ))) {
1935
1989
if (LoadI->getPointerOperand () == Store->getOperand (1 )) {
1936
1990
// Get the defining access for the load.
0 commit comments