mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-11 06:56:12 +00:00
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:
parent
47f01f1b44
commit
223df2269d
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user