forked from OSchip/llvm-project
[TargetLowering] Remove APInt divisor argument from BuildExactSDIV (NFCI).
As requested in D50392, this is a minor refactor to BuildExactSDIV to stop taking the uniform constant APInt divisor and instead extract it locally. I also cleanup the operands and valuetypes to better match BuildUDiv (and BuildSDIV in the near future). llvm-svn: 339246
This commit is contained in:
parent
81f1fbdf5a
commit
e4a4cf5a8b
|
@ -3432,22 +3432,32 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
|
||||||
|
|
||||||
/// Given an exact SDIV by a constant, create a multiplication
|
/// Given an exact SDIV by a constant, create a multiplication
|
||||||
/// with the multiplicative inverse of the constant.
|
/// with the multiplicative inverse of the constant.
|
||||||
static SDValue BuildExactSDIV(const TargetLowering &TLI, SDValue Op1, APInt d,
|
static SDValue BuildExactSDIV(const TargetLowering &TLI, SDNode *N,
|
||||||
const SDLoc &dl, SelectionDAG &DAG,
|
const SDLoc &dl, SelectionDAG &DAG,
|
||||||
SmallVectorImpl<SDNode *> &Created) {
|
SmallVectorImpl<SDNode *> &Created) {
|
||||||
|
SDValue Op0 = N->getOperand(0);
|
||||||
|
SDValue Op1 = N->getOperand(1);
|
||||||
|
EVT VT = N->getValueType(0);
|
||||||
|
EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
|
||||||
|
|
||||||
|
ConstantSDNode *C = isConstOrConstSplat(Op1);
|
||||||
|
if (!C || C->isNullValue())
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
APInt d = C->getAPIntValue();
|
||||||
assert(d != 0 && "Division by zero!");
|
assert(d != 0 && "Division by zero!");
|
||||||
|
|
||||||
|
SDValue Res = Op0;
|
||||||
|
|
||||||
// Shift the value upfront if it is even, so the LSB is one.
|
// Shift the value upfront if it is even, so the LSB is one.
|
||||||
unsigned ShAmt = d.countTrailingZeros();
|
unsigned ShAmt = d.countTrailingZeros();
|
||||||
if (ShAmt) {
|
if (ShAmt) {
|
||||||
// TODO: For UDIV use SRL instead of SRA.
|
// TODO: For UDIV use SRL instead of SRA.
|
||||||
SDValue Amt =
|
SDValue Amt = DAG.getConstant(ShAmt, dl, ShVT);
|
||||||
DAG.getConstant(ShAmt, dl, TLI.getShiftAmountTy(Op1.getValueType(),
|
|
||||||
DAG.getDataLayout()));
|
|
||||||
SDNodeFlags Flags;
|
SDNodeFlags Flags;
|
||||||
Flags.setExact(true);
|
Flags.setExact(true);
|
||||||
Op1 = DAG.getNode(ISD::SRA, dl, Op1.getValueType(), Op1, Amt, Flags);
|
Res = DAG.getNode(ISD::SRA, dl, VT, Res, Amt, Flags);
|
||||||
Created.push_back(Op1.getNode());
|
Created.push_back(Res.getNode());
|
||||||
d.ashrInPlace(ShAmt);
|
d.ashrInPlace(ShAmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3456,10 +3466,8 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDValue Op1, APInt d,
|
||||||
while ((t = d*xn) != 1)
|
while ((t = d*xn) != 1)
|
||||||
xn *= APInt(d.getBitWidth(), 2) - t;
|
xn *= APInt(d.getBitWidth(), 2) - t;
|
||||||
|
|
||||||
SDValue Op2 = DAG.getConstant(xn, dl, Op1.getValueType());
|
SDValue Mul = DAG.getConstant(xn, dl, VT);
|
||||||
SDValue Mul = DAG.getNode(ISD::MUL, dl, Op1.getValueType(), Op1, Op2);
|
return DAG.getNode(ISD::MUL, dl, VT, Res, Mul);
|
||||||
Created.push_back(Mul.getNode());
|
|
||||||
return Mul;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
|
SDValue TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
|
||||||
|
@ -3487,16 +3495,16 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
|
||||||
if (!isTypeLegal(VT))
|
if (!isTypeLegal(VT))
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
|
// If the sdiv has an 'exact' bit we can use a simpler lowering.
|
||||||
|
if (N->getFlags().hasExact())
|
||||||
|
return BuildExactSDIV(*this, N, dl, DAG, Created);
|
||||||
|
|
||||||
// TODO: Add non-uniform constant support.
|
// TODO: Add non-uniform constant support.
|
||||||
ConstantSDNode *C = isConstOrConstSplat(N->getOperand(1));
|
ConstantSDNode *C = isConstOrConstSplat(N->getOperand(1));
|
||||||
if (!C || C->isNullValue())
|
if (!C || C->isNullValue())
|
||||||
return SDValue();
|
return SDValue();
|
||||||
const APInt &Divisor = C->getAPIntValue();
|
const APInt &Divisor = C->getAPIntValue();
|
||||||
|
|
||||||
// If the sdiv has an 'exact' bit we can use a simpler lowering.
|
|
||||||
if (N->getFlags().hasExact())
|
|
||||||
return BuildExactSDIV(*this, N->getOperand(0), Divisor, dl, DAG, Created);
|
|
||||||
|
|
||||||
APInt::ms magics = Divisor.magic();
|
APInt::ms magics = Divisor.magic();
|
||||||
|
|
||||||
// Multiply the numerator (operand 0) by the magic value
|
// Multiply the numerator (operand 0) by the magic value
|
||||||
|
|
Loading…
Reference in New Issue