mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +00:00
Move Sub simplifications and additional Add simplifications out of
instcombine and into InstructionSimplify. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121861 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -242,17 +242,25 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
std::swap(Op0, Op1);
|
||||
}
|
||||
|
||||
if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
|
||||
// X + undef -> undef
|
||||
if (isa<UndefValue>(Op1C))
|
||||
return Op1C;
|
||||
// X + undef -> undef
|
||||
if (isa<UndefValue>(Op1))
|
||||
return Op1;
|
||||
|
||||
// X + 0 --> X
|
||||
if (Op1C->isNullValue())
|
||||
return Op0;
|
||||
}
|
||||
// X + 0 -> X
|
||||
if (match(Op1, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// FIXME: Could pull several more out of instcombine.
|
||||
// X + (Y - X) -> Y
|
||||
// (Y - X) + X -> Y
|
||||
Value *Y = 0;
|
||||
if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) ||
|
||||
match(Op0, m_Sub(m_Value(Y), m_Specific(Op1))))
|
||||
return Y;
|
||||
|
||||
// X + ~X -> -1 since ~X = -X-1
|
||||
if (match(Op0, m_Not(m_Specific(Op1))) ||
|
||||
match(Op1, m_Not(m_Specific(Op0))))
|
||||
return Constant::getAllOnesValue(Op0->getType());
|
||||
|
||||
// Threading Add over selects and phi nodes is pointless, so don't bother.
|
||||
// Threading over the select in "A + select(cond, B, C)" means evaluating
|
||||
@@ -266,6 +274,49 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifySubInst - Given operands for a Sub, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const TargetData *TD, const DominatorTree *) {
|
||||
if (Constant *CLHS = dyn_cast<Constant>(Op0))
|
||||
if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
|
||||
Constant *Ops[] = { CLHS, CRHS };
|
||||
return ConstantFoldInstOperands(Instruction::Sub, CLHS->getType(),
|
||||
Ops, 2, TD);
|
||||
}
|
||||
|
||||
// X - undef -> undef
|
||||
// undef - X -> undef
|
||||
if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
|
||||
return UndefValue::get(Op0->getType());
|
||||
|
||||
// X - 0 -> X
|
||||
if (match(Op1, m_Zero()))
|
||||
return Op0;
|
||||
|
||||
// X - X -> 0
|
||||
if (Op0 == Op1)
|
||||
return Constant::getNullValue(Op0->getType());
|
||||
|
||||
// (X + Y) - Y -> X
|
||||
// (Y + X) - Y -> X
|
||||
Value *X = 0;
|
||||
if (match(Op0, m_Add(m_Value(X), m_Specific(Op1))) ||
|
||||
match(Op0, m_Add(m_Specific(Op1), m_Value(X))))
|
||||
return X;
|
||||
|
||||
// Threading Sub over selects and phi nodes is pointless, so don't bother.
|
||||
// Threading over the select in "A - select(cond, B, C)" means evaluating
|
||||
// "A-B" and "A-C" and seeing if they are equal; but they are equal if and
|
||||
// only if B and C are equal. If B and C are equal then (since we assume
|
||||
// that operands have already been simplified) "select(cond, B, C)" should
|
||||
// have been simplified to the common value of B and C already. Analysing
|
||||
// "A-B" and "A-C" thus gains nothing, but costs compile time. Similarly
|
||||
// for threading over phi nodes.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SimplifyAndInst - Given operands for an And, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD,
|
||||
@@ -835,6 +886,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(),
|
||||
TD, DT);
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
Result = SimplifySubInst(I->getOperand(0), I->getOperand(1),
|
||||
cast<BinaryOperator>(I)->hasNoSignedWrap(),
|
||||
cast<BinaryOperator>(I)->hasNoUnsignedWrap(),
|
||||
TD, DT);
|
||||
break;
|
||||
case Instruction::And:
|
||||
Result = SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD, DT);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user