forked from OSchip/llvm-project
Add an m_Div pattern for matching either a udiv or an sdiv and use it
to simplify the "(X/Y)*Y->X when the division is exact" transform. llvm-svn: 125004
This commit is contained in:
parent
648f55b2b4
commit
867cb633b4
|
@ -346,6 +346,40 @@ inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
|
|||
return Shr_match<LHS, RHS>(L, R);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Matchers for either SDiv or UDiv .. for convenience
|
||||
//
|
||||
template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
|
||||
struct Div_match {
|
||||
LHS_t L;
|
||||
RHS_t R;
|
||||
|
||||
Div_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
|
||||
|
||||
template<typename OpTy>
|
||||
bool match(OpTy *V) {
|
||||
if (V->getValueID() == Value::InstructionVal + Instruction::SDiv ||
|
||||
V->getValueID() == Value::InstructionVal + Instruction::UDiv) {
|
||||
ConcreteTy *I = cast<ConcreteTy>(V);
|
||||
return (I->getOpcode() == Instruction::UDiv ||
|
||||
I->getOpcode() == Instruction::SDiv) &&
|
||||
L.match(I->getOperand(0)) &&
|
||||
R.match(I->getOperand(1));
|
||||
}
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
|
||||
return (CE->getOpcode() == Instruction::SDiv ||
|
||||
CE->getOpcode() == Instruction::UDiv) &&
|
||||
L.match(CE->getOperand(0)) &&
|
||||
R.match(CE->getOperand(1));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LHS, typename RHS>
|
||||
inline Div_match<LHS, RHS> m_Div(const LHS &L, const RHS &R) {
|
||||
return Div_match<LHS, RHS>(L, R);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Matchers for binary classes
|
||||
//
|
||||
|
|
|
@ -734,10 +734,8 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD,
|
|||
|
||||
// (X / Y) * Y -> X if the division is exact.
|
||||
Value *X = 0, *Y = 0;
|
||||
if ((match(Op0, m_SDiv(m_Value(X), m_Value(Y))) && Y == Op1) || // (X / Y) * Y
|
||||
(match(Op0, m_UDiv(m_Value(X), m_Value(Y))) && Y == Op1) ||
|
||||
(match(Op1, m_SDiv(m_Value(X), m_Value(Y))) && Y == Op0) || // Y * (X / Y)
|
||||
(match(Op1, m_UDiv(m_Value(X), m_Value(Y))) && Y == Op0)) {
|
||||
if ((match(Op0, m_Div(m_Value(X), m_Value(Y))) && Y == Op1) || // (X / Y) * Y
|
||||
(match(Op1, m_Div(m_Value(X), m_Value(Y))) && Y == Op0)) { // Y * (X / Y)
|
||||
BinaryOperator *Div = cast<BinaryOperator>(Y == Op1 ? Op0 : Op1);
|
||||
if (Div->isExact())
|
||||
return X;
|
||||
|
|
Loading…
Reference in New Issue