From 223df2269da508eadc160e34e0dc03c9e02e7d0b Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Thu, 8 Sep 2005 20:18:10 +0000 Subject: [PATCH] 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 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 69 +++++++++++++++++++---- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 11 +++- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 945c21fb615..67c5762f1d5 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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(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(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(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(N1); ConstantFPSDNode *N0CFP = dyn_cast(N0); ConstantFPSDNode *N1CFP = dyn_cast(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(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(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(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(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(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(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(N0.getOperand(0)); + ConstantSDNode *N01C = dyn_cast(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(N->getOperand(1))->getVT(); ConstantFPSDNode *N0CFP = dyn_cast(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); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 7d9f79fed3a..055caad70a2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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(N1.Val->getOperand(1))) return getNode(Opcode, VT, N1.Val->getOperand(0), getNode(Opcode, VT, N2, N1.Val->getOperand(1))); + } } ConstantFPSDNode *N1CFP = dyn_cast(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(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(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; }