mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 12:33:33 +02:00
[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
This commit is contained in:
parent
67273784b1
commit
61f0571008
@ -3522,6 +3522,23 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
|
|||||||
if (N->getFlags().hasExact())
|
if (N->getFlags().hasExact())
|
||||||
return BuildExactSDIV(*this, N, dl, DAG, Created);
|
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 N0 = N->getOperand(0);
|
||||||
SDValue N1 = N->getOperand(1);
|
SDValue N1 = N->getOperand(1);
|
||||||
|
|
||||||
@ -3529,41 +3546,36 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
|
|||||||
ConstantSDNode *C = isConstOrConstSplat(N1);
|
ConstantSDNode *C = isConstOrConstSplat(N1);
|
||||||
if (!C || C->isNullValue())
|
if (!C || C->isNullValue())
|
||||||
return SDValue();
|
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
|
// Multiply the numerator (operand 0) by the magic value
|
||||||
// FIXME: We should support doing a MUL in a wider type
|
// FIXME: We should support doing a MUL in a wider type
|
||||||
SDValue Q;
|
SDValue Q;
|
||||||
if (IsAfterLegalization ? isOperationLegal(ISD::MULHS, VT)
|
if (IsAfterLegalization ? isOperationLegal(ISD::MULHS, VT)
|
||||||
: isOperationLegalOrCustom(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)
|
else if (IsAfterLegalization ? isOperationLegal(ISD::SMUL_LOHI, VT)
|
||||||
: isOperationLegalOrCustom(ISD::SMUL_LOHI, VT))
|
: isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) {
|
||||||
Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), N0,
|
SDValue LoHi =
|
||||||
DAG.getConstant(magics.m, dl, VT))
|
DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), N0, MagicFactor);
|
||||||
.getNode(), 1);
|
Q = SDValue(LoHi.getNode(), 1);
|
||||||
else
|
} else
|
||||||
return SDValue(); // No mulhs or equvialent
|
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());
|
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
|
// Extract the sign bit and add it to the quotient
|
||||||
SDValue T =
|
SDValue T =
|
||||||
DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(EltBits - 1, dl, ShVT));
|
DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(EltBits - 1, dl, ShVT));
|
||||||
|
Loading…
Reference in New Issue
Block a user