@@ -1886,59 +1886,83 @@ static Instruction *foldSelectICmpBinOp(SelectInst &SI, ICmpInst *ICI,
1886
1886
1887
1887
KnownBits Known;
1888
1888
if (TValBop->isBitwiseLogicOp ()) {
1889
+ // We handle if we know specific knownbits from cond of selectinst.
1890
+ // ex) X&Y==-1 ? X^Y : False
1889
1891
if (SKB != SpecialKnownBits::NothingSpecial && XOrder && YOrder) {
1892
+ // No common bits between X, Y
1890
1893
if (SKB & SpecialKnownBits::NoCommonBits) {
1891
1894
if (SKB & (SpecialKnownBits::AllBitsEnabled)) {
1895
+ // If X op Y == -1, then XOR must be -1
1892
1896
if (TValBop->getOpcode () == Instruction::Xor)
1893
1897
Known = KnownBits::makeConstant (APInt (BitWidth, -1 ));
1894
1898
}
1899
+ // If Trueval is X&Y then it should be 0.
1895
1900
if (TValBop->getOpcode () == Instruction::And)
1896
1901
Known = KnownBits::makeConstant (APInt (BitWidth, 0 ));
1902
+ // X|Y can be replace with X^Y, X^Y can be replace with X|Y
1903
+ // This replacing is meaningful when falseval is same.
1897
1904
else if ((match (TVal, m_c_Or (m_Specific (X), m_Specific (Y))) &&
1898
1905
match (FVal, m_c_Xor (m_Specific (X), m_Specific (Y)))) ||
1899
1906
(match (TVal, m_c_Xor (m_Specific (X), m_Specific (Y))) &&
1900
1907
match (FVal, m_c_Or (m_Specific (X), m_Specific (Y)))))
1901
1908
return IC.replaceInstUsesWith (SI, FVal);
1909
+ // All common bits between X, Y
1902
1910
} else if (SKB & SpecialKnownBits::AllCommonBits) {
1911
+ // We can replace (X&Y) and (X|Y) to X or Y
1903
1912
if (TValBop->getOpcode () == Instruction::And ||
1904
1913
TValBop->getOpcode () == Instruction::Or)
1905
1914
if (TValBop->hasOneUse ())
1906
1915
return IC.replaceOperand (SI, 1 , X);
1907
1916
} else if (SKB & SpecialKnownBits::AllBitsEnabled) {
1917
+ // We can replace (X|Y) to -1
1908
1918
if (TValBop->getOpcode () == Instruction::Or)
1909
1919
Known = KnownBits::makeConstant (APInt (BitWidth, -1 ));
1910
1920
}
1911
1921
} else {
1912
1922
KnownBits XKnown, YKnown, Temp;
1913
1923
KnownBits TValBop0KB, TValBop1KB;
1924
+ // computeKnowBits calculates the KnownBits in the branching condition
1925
+ // that the specified variable passes in the execution flow. however, it
1926
+ // does not contain the SelectInst condition, so there is an optimization
1927
+ // opportunity to update the knownbits obtained by calculating KnownBits
1928
+ // with the SelectInst condition.
1914
1929
XKnown = IC.computeKnownBits (X, 0 , &SI);
1915
1930
IC.computeKnownBitsFromCond (X, ICI, XKnown, 0 , &SI, false );
1916
1931
YKnown = IC.computeKnownBits (Y, 0 , &SI);
1917
1932
IC.computeKnownBitsFromCond (Y, ICI, YKnown, 0 , &SI, false );
1918
-
1919
- // Estimate additional KnownBits from the relationship between X and Y
1920
1933
CmpInst::Predicate Pred = ICI->getPredicate ();
1921
1934
if (Pred == ICmpInst::ICMP_EQ) {
1935
+ // Estimate additional KnownBits from the relationship between X and Y
1922
1936
if (CmpLHSBop->getOpcode () == Instruction::And) {
1937
+ // The bit that are set to 1 at `~C&Y` must be 0 in X
1938
+ // The bit that are set to 1 at `~C&X` must be 0 in Y
1923
1939
XKnown.Zero |= ~*C & YKnown.One ;
1924
1940
YKnown.Zero |= ~*C & XKnown.One ;
1925
1941
}
1926
1942
if (CmpLHSBop->getOpcode () == Instruction::Or) {
1943
+ // The bit that are set to 0 at `C&Y` must be 1 in X
1944
+ // The bit that are set to 0 at `C&X` must be 1 in Y
1927
1945
XKnown.One |= *C & YKnown.Zero ;
1928
1946
YKnown.One |= *C & XKnown.Zero ;
1929
1947
}
1930
1948
if (CmpLHSBop->getOpcode () == Instruction::Xor) {
1949
+ // If X^Y==C, then X and Y must be either (1,0) or (0,1) for the
1950
+ // enabled bits in C.
1931
1951
XKnown.One |= *C & YKnown.Zero ;
1932
1952
XKnown.Zero |= *C & YKnown.One ;
1933
1953
YKnown.One |= *C & XKnown.Zero ;
1934
1954
YKnown.Zero |= *C & XKnown.One ;
1955
+ // If X^Y==C, then X and Y must be either (0,0) or (1,1) for the
1956
+ // disabled bits in C.
1935
1957
XKnown.Zero |= ~*C & YKnown.Zero ;
1936
1958
XKnown.One |= ~*C & YKnown.One ;
1937
1959
YKnown.Zero |= ~*C & XKnown.Zero ;
1938
1960
YKnown.One |= ~*C & XKnown.One ;
1939
1961
}
1940
1962
}
1941
1963
1964
+ // If TrueVal has X or Y, return the corresponding KnownBits, otherwise
1965
+ // compute and return new KnownBits.
1942
1966
auto getTValBopKB = [&](unsigned OpNum) -> KnownBits {
1943
1967
unsigned Order = OpNum + 1 ;
1944
1968
if (Order == XOrder)
0 commit comments