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