From e5d63829fd62d815a330c21ea316e6b4cf943562 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Thu, 11 Aug 2005 01:12:20 +0000 Subject: [PATCH] Some SELECT_CC cleanups: 1. move assertions for node creation to getNode() 2. legalize the values returned in ExpandOp immediately 3. Move select_cc optimizations from SELECT's getNode() to SELECT_CC's, allowing them to be cleaned up significantly. This paves the way to pick up additional optimizations on SELECT_CC, such as sum-of-absolute-differences. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22757 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 4 - lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 + lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 112 ++++++++++++---------- 3 files changed, 61 insertions(+), 57 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index b84b9f25c7d..e23f32d9d7b 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -190,10 +190,6 @@ public: SDOperand getSelectCC(SDOperand LHS, SDOperand RHS, SDOperand True, SDOperand False, ISD::CondCode Cond) { MVT::ValueType VT = True.getValueType(); - assert(LHS.getValueType() == RHS.getValueType() && - "LHS and RHS of condition must have same type!"); - assert(True.getValueType() == False.getValueType() && - "True and False arms of SelectCC must have same type!"); return getNode(ISD::SELECT_CC, VT, LHS, RHS, True, False,getCondCode(Cond)); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index fc92933643a..0a50e2cbe95 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2782,6 +2782,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Node->getOperand(1), TL, FL, Node->getOperand(4)); Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0), Node->getOperand(1), TH, FH, Node->getOperand(4)); + Lo = LegalizeOp(Lo); + Hi = LegalizeOp(Hi); break; } case ISD::SIGN_EXTEND: { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a20c5176308..e331c4a60bd 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1397,59 +1397,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, if (N1 == N3) // X ? Y : X --> X ? Y : 0 --> X & Y return getNode(ISD::AND, VT, N1, N2); } - - // If this is a selectcc, check to see if we can simplify the result. - if (N1.Val->getOpcode() == ISD::SETCC) { - SDNode *SetCC = N1.Val; - ISD::CondCode CC = cast(SetCC->getOperand(2))->get(); - if (ConstantFPSDNode *CFP = - dyn_cast(SetCC->getOperand(1))) - if (CFP->getValue() == 0.0) { // Allow either -0.0 or 0.0 - // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs - if ((CC == ISD::SETGE || CC == ISD::SETGT) && - N2 == SetCC->getOperand(0) && N3.getOpcode() == ISD::FNEG && - N3.getOperand(0) == N2) - return getNode(ISD::FABS, VT, N2); - - // select (setl[te] X, +/-0.0), fneg(X), X -> fabs - if ((CC == ISD::SETLT || CC == ISD::SETLE) && - N3 == SetCC->getOperand(0) && N2.getOpcode() == ISD::FNEG && - N2.getOperand(0) == N3) - return getNode(ISD::FABS, VT, N3); - } - // select (setlt X, 0), A, 0 -> and (sra X, size(X)-1), A - if (ConstantSDNode *CN = - dyn_cast(SetCC->getOperand(1))) - if (CN->getValue() == 0 && N3C && N3C->getValue() == 0) - if (CC == ISD::SETLT) { - MVT::ValueType XType = SetCC->getOperand(0).getValueType(); - MVT::ValueType AType = N2.getValueType(); - if (XType >= AType) { - // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a - // single-bit constant. FIXME: remove once the dag combiner - // exists. - if (ConstantSDNode *AC = dyn_cast(N2)) - if ((AC->getValue() & (AC->getValue()-1)) == 0) { - unsigned ShCtV = Log2_64(AC->getValue()); - ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; - SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy()); - SDOperand Shift = getNode(ISD::SRL, XType, - SetCC->getOperand(0), ShCt); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N2); - } - - - SDOperand Shift = getNode(ISD::SRA, XType, SetCC->getOperand(0), - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N2); - } - } - } break; case ISD::BRCOND: if (N2C) @@ -1491,6 +1438,65 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, SDOperand N5) { + if (ISD::SELECT_CC == Opcode) { + assert(N1.getValueType() == N2.getValueType() && + "LHS and RHS of condition must have same type!"); + assert(N3.getValueType() == N4.getValueType() && + "True and False arms of SelectCC must have same type!"); + + ConstantSDNode *N2C = dyn_cast(N2.Val); + ConstantSDNode *N3C = dyn_cast(N3.Val); + ConstantSDNode *N4C = dyn_cast(N4.Val); + ISD::CondCode CC = cast(N5)->get(); + + // Check to see if we can simplify the select into an fabs node + if (ConstantFPSDNode *CFP = dyn_cast(N2)) { + // Allow either -0.0 or 0.0 + if (CFP->getValue() == 0.0) { + // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs + if ((CC == ISD::SETGE || CC == ISD::SETGT) && + N1 == N3 && N4.getOpcode() == ISD::FNEG && + N1 == N4.getOperand(0)) + return getNode(ISD::FABS, VT, N1); + + // select (setl[te] X, +/-0.0), fneg(X), X -> fabs + if ((CC == ISD::SETLT || CC == ISD::SETLE) && + N1 == N4 && N3.getOpcode() == ISD::FNEG && + N3.getOperand(0) == N4) + return getNode(ISD::FABS, VT, N4); + } + } + + // Check to see if we can perform the "gzip trick", transforming + // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A + if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() && + MVT::isInteger(N1.getValueType()) && + MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) { + MVT::ValueType XType = N1.getValueType(); + MVT::ValueType AType = N3.getValueType(); + if (XType >= AType) { + // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a + // single-bit constant. FIXME: remove once the dag combiner + // exists. + if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) { + unsigned ShCtV = Log2_64(N3C->getValue()); + ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; + SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy()); + SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt); + if (XType > AType) + Shift = getNode(ISD::TRUNCATE, AType, Shift); + return getNode(ISD::AND, AType, Shift, N3); + } + SDOperand Shift = getNode(ISD::SRA, XType, N1, + getConstant(MVT::getSizeInBits(XType)-1, + TLI.getShiftAmountTy())); + if (XType > AType) + Shift = getNode(ISD::TRUNCATE, AType, Shift); + return getNode(ISD::AND, AType, Shift, N3); + } + } + } + std::vector Ops; Ops.reserve(5); Ops.push_back(N1);