Move yet more folds over to the dag combiner from sd.cpp

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nate Begeman 2005-09-08 20:18:10 +00:00
parent 47f01f1b44
commit 223df2269d
2 changed files with 68 additions and 12 deletions

View File

@ -355,16 +355,20 @@ SDOperand DAGCombiner::visitADD(SDNode *N) {
// fold (add x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
// fold (add (add x, c1), c2) -> (add x, c1+c2)
if (N1C && N0.getOpcode() == ISD::ADD &&
N0.getOperand(1).getOpcode() == ISD::Constant)
return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue() +
cast<ConstantSDNode>(N0.getOperand(1))->getValue(),
VT));
// fold floating point (add c1, c2) -> c1+c2
if (N0CFP && N1CFP)
return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), VT);
// fold (add (add x, c1), c2) -> (add x, c1+c2)
if (N1C && N0.getOpcode() == ISD::ADD) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
return DAG.getNode(ISD::ADD, VT, N0.getOperand(1),
DAG.getConstant(N1C->getValue()+N00C->getValue(), VT));
if (N01C)
return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()+N01C->getValue(), VT));
}
// fold (A + (-B)) -> A-B
if (N1.getOpcode() == ISD::FNEG)
return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(0));
@ -426,6 +430,7 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
MVT::ValueType VT = N0.getValueType();
// fold (mul c1, c2) -> c1*c2
if (N0C && N1C)
@ -448,6 +453,17 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
return DAG.getNode(ISD::SHL, N->getValueType(0), N0,
DAG.getConstant(Log2_64(N1C->getValue()),
TLI.getShiftAmountTy()));
// fold (mul (mul x, c1), c2) -> (mul x, c1*c2)
if (N1C && N0.getOpcode() == ISD::MUL) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
return DAG.getNode(ISD::MUL, VT, N0.getOperand(1),
DAG.getConstant(N1C->getValue()*N00C->getValue(), VT));
if (N01C)
return DAG.getNode(ISD::MUL, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()*N01C->getValue(), VT));
}
// fold floating point (mul c1, c2) -> c1*c2
if (N0CFP && N1CFP)
return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(),
@ -581,6 +597,17 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)),
TLI))
return N0;
// fold (and (and x, c1), c2) -> (and x, c1^c2)
if (N1C && N0.getOpcode() == ISD::AND) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
return DAG.getNode(ISD::AND, VT, N0.getOperand(1),
DAG.getConstant(N1C->getValue()&N00C->getValue(), VT));
if (N01C)
return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()&N01C->getValue(), VT));
}
// fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
unsigned ExtendBits =
@ -623,6 +650,17 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
if (N1C && MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)),
TLI))
return N1;
// fold (or (or x, c1), c2) -> (or x, c1|c2)
if (N1C && N0.getOpcode() == ISD::OR) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
return DAG.getNode(ISD::OR, VT, N0.getOperand(1),
DAG.getConstant(N1C->getValue()|N00C->getValue(), VT));
if (N01C)
return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
}
return SDOperand();
}
@ -681,6 +719,20 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) {
return DAG.getNode(NewOpcode, VT, LHS, RHS);
}
}
// fold (xor (xor x, c1), c2) -> (xor x, c1^c2)
if (N1C && N0.getOpcode() == ISD::XOR) {
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
if (N00C)
return DAG.getNode(ISD::XOR, VT, N0.getOperand(1),
DAG.getConstant(N1C->getValue()^N00C->getValue(), VT));
if (N01C)
return DAG.getNode(ISD::XOR, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()^N01C->getValue(), VT));
}
// fold (xor x, x) -> 0
if (N0 == N1)
return DAG.getConstant(0, VT);
return SDOperand();
}
@ -1003,9 +1055,6 @@ SDOperand DAGCombiner::visitFP_ROUND_INREG(SDNode *N) {
MVT::ValueType EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
// noop fp_round_inreg
if (EVT == VT)
return N0;
// fold (fp_round_inreg c1fp) -> c1fp
if (N0CFP) {
SDOperand Round = DAG.getConstantFP(N0CFP->getValue(), EVT);

View File

@ -1480,13 +1480,13 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
}
break;
}
}
// Reassociate ((X op C1) op C2) if possible.
if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode))
if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N1.Val->getOperand(1)))
return getNode(Opcode, VT, N1.Val->getOperand(0),
getNode(Opcode, VT, N2, N1.Val->getOperand(1)));
}
}
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
@ -1597,9 +1597,12 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
N1.getOperand(0), N2.getOperand(0)));
break;
case ISD::XOR:
if (!CombinerEnabled) {
if (N1 == N2) return getConstant(0, VT); // xor X, Y -> 0
}
break;
case ISD::ADD:
if (!CombinerEnabled) {
if (N2.getOpcode() == ISD::FNEG) // (A+ (-B) -> A-B
return getNode(ISD::SUB, VT, N1, N2.getOperand(0));
if (N1.getOpcode() == ISD::FNEG) // ((-A)+B) -> B-A
@ -1613,8 +1616,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1) &&
!MVT::isFloatingPoint(N2.getValueType()))
return N2.Val->getOperand(0); // A+(B-A) -> B
}
break;
case ISD::SUB:
if (!CombinerEnabled) {
if (N1.getOpcode() == ISD::ADD) {
if (N1.Val->getOperand(0) == N2 &&
!MVT::isFloatingPoint(N2.getValueType()))
@ -1625,6 +1630,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
}
if (N2.getOpcode() == ISD::FNEG) // (A- (-B) -> A+B
return getNode(ISD::ADD, VT, N1, N2.getOperand(0));
}
break;
case ISD::FP_ROUND_INREG:
if (cast<VTSDNode>(N2)->getVT() == VT) return N1; // Not actually rounding.
@ -1632,7 +1638,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
case ISD::SIGN_EXTEND_INREG: {
MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
if (EVT == VT) return N1; // Not actually extending
if (!CombinerEnabled) {
// If we are sign extending an extension, use the original source.
if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG ||
N1.getOpcode() == ISD::AssertSext)
@ -1660,6 +1666,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
if ((Mask & (~0ULL << (NumBits-1))) == 0)
return N1;
}
}
break;
}