Skip to content

Commit ebb8ffd

Browse files
committed
[InstSimplify] Extract commutative and folds into helper (NFCI)
There are a number of and folds that are repeated for both operand orders. Move these into a helper that is invoked with both orders. This is conceptually NFC, but may not be entirely so, as the order of folds may change.
1 parent c350a1e commit ebb8ffd

File tree

1 file changed

+47
-56
lines changed

1 file changed

+47
-56
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 47 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,48 @@ static Value *simplifyLogicOfAddSub(Value *Op0, Value *Op1,
19931993
return nullptr;
19941994
}
19951995

1996+
// Commutative patterns for and that will be tried with both operand orders.
1997+
static Value *simplifyAndCommutative(Value *Op0, Value *Op1,
1998+
const SimplifyQuery &Q,
1999+
unsigned MaxRecurse) {
2000+
// ~A & A = 0
2001+
if (match(Op0, m_Not(m_Specific(Op1))))
2002+
return Constant::getNullValue(Op0->getType());
2003+
2004+
// (A | ?) & A = A
2005+
if (match(Op0, m_c_Or(m_Specific(Op1), m_Value())))
2006+
return Op1;
2007+
2008+
// (X | ~Y) & (X | Y) --> X
2009+
Value *X, *Y;
2010+
if (match(Op0, m_c_Or(m_Value(X), m_Not(m_Value(Y)))) &&
2011+
match(Op1, m_c_Or(m_Deferred(X), m_Deferred(Y))))
2012+
return X;
2013+
2014+
// If we have a multiplication overflow check that is being 'and'ed with a
2015+
// check that one of the multipliers is not zero, we can omit the 'and', and
2016+
// only keep the overflow check.
2017+
if (isCheckForZeroAndMulWithOverflow(Op0, Op1, true))
2018+
return Op1;
2019+
2020+
// -A & A = A if A is a power of two or zero.
2021+
if (match(Op0, m_Neg(m_Specific(Op1))) &&
2022+
isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
2023+
return Op1;
2024+
2025+
// This is a similar pattern used for checking if a value is a power-of-2:
2026+
// (A - 1) & A --> 0 (if A is a power-of-2 or 0)
2027+
if (match(Op0, m_Add(m_Specific(Op1), m_AllOnes())) &&
2028+
isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
2029+
return Constant::getNullValue(Op1->getType());
2030+
2031+
if (Value *V =
2032+
simplifyAndOrWithICmpEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
2033+
return V;
2034+
2035+
return nullptr;
2036+
}
2037+
19962038
/// Given operands for an And, see if we can fold the result.
19972039
/// If not, this returns null.
19982040
static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
@@ -2020,33 +2062,18 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
20202062
if (match(Op1, m_AllOnes()))
20212063
return Op0;
20222064

2023-
// A & ~A = ~A & A = 0
2024-
if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0))))
2025-
return Constant::getNullValue(Op0->getType());
2026-
2027-
// (A | ?) & A = A
2028-
if (match(Op0, m_c_Or(m_Specific(Op1), m_Value())))
2029-
return Op1;
2030-
2031-
// A & (A | ?) = A
2032-
if (match(Op1, m_c_Or(m_Specific(Op0), m_Value())))
2033-
return Op0;
2034-
2035-
// (X | Y) & (X | ~Y) --> X (commuted 8 ways)
2036-
Value *X, *Y;
2037-
if (match(Op0, m_c_Or(m_Value(X), m_Not(m_Value(Y)))) &&
2038-
match(Op1, m_c_Or(m_Deferred(X), m_Deferred(Y))))
2039-
return X;
2040-
if (match(Op1, m_c_Or(m_Value(X), m_Not(m_Value(Y)))) &&
2041-
match(Op0, m_c_Or(m_Deferred(X), m_Deferred(Y))))
2042-
return X;
2065+
if (Value *Res = simplifyAndCommutative(Op0, Op1, Q, MaxRecurse))
2066+
return Res;
2067+
if (Value *Res = simplifyAndCommutative(Op1, Op0, Q, MaxRecurse))
2068+
return Res;
20432069

20442070
if (Value *V = simplifyLogicOfAddSub(Op0, Op1, Instruction::And))
20452071
return V;
20462072

20472073
// A mask that only clears known zeros of a shifted value is a no-op.
20482074
const APInt *Mask;
20492075
const APInt *ShAmt;
2076+
Value *X, *Y;
20502077
if (match(Op1, m_APInt(Mask))) {
20512078
// If all bits in the inverted and shifted mask are clear:
20522079
// and (shl X, ShAmt), Mask --> shl X, ShAmt
@@ -2074,42 +2101,6 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
20742101
return ConstantInt::getNullValue(Op1->getType());
20752102
}
20762103

2077-
// If we have a multiplication overflow check that is being 'and'ed with a
2078-
// check that one of the multipliers is not zero, we can omit the 'and', and
2079-
// only keep the overflow check.
2080-
if (isCheckForZeroAndMulWithOverflow(Op0, Op1, true))
2081-
return Op1;
2082-
if (isCheckForZeroAndMulWithOverflow(Op1, Op0, true))
2083-
return Op0;
2084-
2085-
// A & (-A) = A if A is a power of two or zero.
2086-
if (match(Op0, m_Neg(m_Specific(Op1))) ||
2087-
match(Op1, m_Neg(m_Specific(Op0)))) {
2088-
if (isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI,
2089-
Q.DT))
2090-
return Op0;
2091-
if (isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI,
2092-
Q.DT))
2093-
return Op1;
2094-
}
2095-
2096-
// This is a similar pattern used for checking if a value is a power-of-2:
2097-
// (A - 1) & A --> 0 (if A is a power-of-2 or 0)
2098-
// A & (A - 1) --> 0 (if A is a power-of-2 or 0)
2099-
if (match(Op0, m_Add(m_Specific(Op1), m_AllOnes())) &&
2100-
isKnownToBeAPowerOfTwo(Op1, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
2101-
return Constant::getNullValue(Op1->getType());
2102-
if (match(Op1, m_Add(m_Specific(Op0), m_AllOnes())) &&
2103-
isKnownToBeAPowerOfTwo(Op0, Q.DL, /*OrZero*/ true, 0, Q.AC, Q.CxtI, Q.DT))
2104-
return Constant::getNullValue(Op0->getType());
2105-
2106-
if (Value *V =
2107-
simplifyAndOrWithICmpEq(Instruction::And, Op0, Op1, Q, MaxRecurse))
2108-
return V;
2109-
if (Value *V =
2110-
simplifyAndOrWithICmpEq(Instruction::And, Op1, Op0, Q, MaxRecurse))
2111-
return V;
2112-
21132104
if (Value *V = simplifyAndOrOfCmps(Q, Op0, Op1, true))
21142105
return V;
21152106

0 commit comments

Comments
 (0)