diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-08-16 16:54:06 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-08-16 16:54:06 +0000 |
commit | ede4905375a88865e19183f4e03714217652f4d8 (patch) | |
tree | e76d627d15aea96f11c14daa8d39e58043275caa /llvm/lib/CodeGen | |
parent | b25e645ef11d1b38644d91d43de1b52068cc379d (diff) | |
download | bcm5719-llvm-ede4905375a88865e19183f4e03714217652f4d8.tar.gz bcm5719-llvm-ede4905375a88865e19183f4e03714217652f4d8.zip |
[TargetLowering] Refactor BuildSDIV in preparation for D50765. NFCI.
Pull out magic factor calculators into a helper function, use 0/+1/-1 multiplication factor to (optionally) add/sub the numerator.
llvm-svn: 339898
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 13482e74c9e..dbc34442208 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3522,6 +3522,23 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, if (N->getFlags().hasExact()) return BuildExactSDIV(*this, N, dl, DAG, Created); + auto BuildSDIVPattern = [&](const APInt &Divisor, SDValue &MagicFactor, + SDValue &Factor, SDValue &Shift) { + APInt::ms magics = Divisor.magic(); + int NumeratorFactor = 0; + + // If d > 0 and m < 0, add the numerator. + if (Divisor.isStrictlyPositive() && magics.m.isNegative()) + NumeratorFactor = 1; + // If d < 0 and m > 0, subtract the numerator. + else if (Divisor.isNegative() && magics.m.isStrictlyPositive()) + NumeratorFactor = -1; + + MagicFactor = DAG.getConstant(magics.m, dl, VT); + Factor = DAG.getConstant(NumeratorFactor, dl, VT); + Shift = DAG.getConstant(magics.s, dl, ShVT); + }; + SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -3529,41 +3546,36 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, ConstantSDNode *C = isConstOrConstSplat(N1); if (!C || C->isNullValue()) return SDValue(); - const APInt &Divisor = C->getAPIntValue(); - APInt::ms magics = Divisor.magic(); + // Collect the shifts/magic values. + SDValue MagicFactor, Factor, Shift; + BuildSDIVPattern(C->getAPIntValue(), MagicFactor, Factor, Shift); // Multiply the numerator (operand 0) by the magic value // FIXME: We should support doing a MUL in a wider type SDValue Q; if (IsAfterLegalization ? isOperationLegal(ISD::MULHS, VT) : isOperationLegalOrCustom(ISD::MULHS, VT)) - Q = DAG.getNode(ISD::MULHS, dl, VT, N0, DAG.getConstant(magics.m, dl, VT)); + Q = DAG.getNode(ISD::MULHS, dl, VT, N0, MagicFactor); else if (IsAfterLegalization ? isOperationLegal(ISD::SMUL_LOHI, VT) - : isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) - Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), N0, - DAG.getConstant(magics.m, dl, VT)) - .getNode(), 1); - else - return SDValue(); // No mulhs or equvialent + : isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) { + SDValue LoHi = + DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), N0, MagicFactor); + Q = SDValue(LoHi.getNode(), 1); + } else + return SDValue(); // No mulhs or equivalent + Created.push_back(Q.getNode()); + // (Optionally) Add/subtract the numerator using Factor. + Factor = DAG.getNode(ISD::MUL, dl, VT, N0, Factor); + Created.push_back(Factor.getNode()); + Q = DAG.getNode(ISD::ADD, dl, VT, Q, Factor); + Created.push_back(Q.getNode()); + + // Shift right algebraic by shift value. + Q = DAG.getNode(ISD::SRA, dl, VT, Q, Shift); Created.push_back(Q.getNode()); - // If d > 0 and m < 0, add the numerator - if (Divisor.isStrictlyPositive() && magics.m.isNegative()) { - Q = DAG.getNode(ISD::ADD, dl, VT, Q, N0); - Created.push_back(Q.getNode()); - } - // If d < 0 and m > 0, subtract the numerator. - if (Divisor.isNegative() && magics.m.isStrictlyPositive()) { - Q = DAG.getNode(ISD::SUB, dl, VT, Q, N0); - Created.push_back(Q.getNode()); - } - // Shift right algebraic if shift value is nonzero - if (magics.s > 0) { - Q = DAG.getNode(ISD::SRA, dl, VT, Q, DAG.getConstant(magics.s, dl, ShVT)); - Created.push_back(Q.getNode()); - } // Extract the sign bit and add it to the quotient SDValue T = DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(EltBits - 1, dl, ShVT)); |