summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-08-16 16:54:06 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-08-16 16:54:06 +0000
commitede4905375a88865e19183f4e03714217652f4d8 (patch)
treee76d627d15aea96f11c14daa8d39e58043275caa /llvm/lib/CodeGen
parentb25e645ef11d1b38644d91d43de1b52068cc379d (diff)
downloadbcm5719-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.cpp60
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));
OpenPOWER on IntegriCloud