if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N))
return CN;
- if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N))
- return BV->getConstantSplatValue();
+ if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N)) {
+ ConstantSDNode *CN = BV->getConstantSplatValue();
+
+ // BuildVectors can truncate their operands. Ignore that case here.
+ if (CN && CN->getValueType(0) == N.getValueType().getScalarType())
+ return CN;
+ }
return nullptr;
}
SDValue DAGCombiner::visitSDIV(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getNode());
- ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
+ ConstantSDNode *N0C = isConstOrConstSplat(N0);
+ ConstantSDNode *N1C = isConstOrConstSplat(N1);
EVT VT = N->getValueType(0);
// fold vector ops
N0, N1);
}
- const APInt *Divisor = nullptr;
- if (N1C) {
- Divisor = &N1C->getAPIntValue();
- } else if (N1.getValueType().isVector() &&
- N1->getOpcode() == ISD::BUILD_VECTOR) {
- BuildVectorSDNode *BV = cast<BuildVectorSDNode>(N->getOperand(1));
- if (ConstantSDNode *C = BV->getConstantSplatValue())
- Divisor = &C->getAPIntValue();
- }
-
// fold (sdiv X, pow2) -> simple ops after legalize
- if (Divisor && !!*Divisor &&
- (Divisor->isPowerOf2() || (-*Divisor).isPowerOf2())) {
+ if (N1C && !N1C->isNullValue() && (N1C->getAPIntValue().isPowerOf2() ||
+ (-N1C->getAPIntValue()).isPowerOf2())) {
// If dividing by powers of two is cheap, then don't perform the following
// fold.
if (TLI.isPow2DivCheap())
return SDValue();
- unsigned lg2 = Divisor->countTrailingZeros();
+ unsigned lg2 = N1C->getAPIntValue().countTrailingZeros();
// Splat the sign bit into the register
SDValue SGN =
// If we're dividing by a positive value, we're done. Otherwise, we must
// negate the result.
- if (Divisor->isNonNegative())
+ if (N1C->getAPIntValue().isNonNegative())
return SRA;
AddToWorkList(SRA.getNode());
// if integer divide is expensive and we satisfy the requirements, emit an
// alternate sequence.
- if ((N1C || N1->getOpcode() == ISD::BUILD_VECTOR) && !TLI.isIntDivCheap()) {
+ if (N1C && !TLI.isIntDivCheap()) {
SDValue Op = BuildSDIV(N);
if (Op.getNode()) return Op;
}
SDValue DAGCombiner::visitUDIV(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getNode());
- ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
+ ConstantSDNode *N0C = isConstOrConstSplat(N0);
+ ConstantSDNode *N1C = isConstOrConstSplat(N1);
EVT VT = N->getValueType(0);
// fold vector ops
}
}
// fold (udiv x, c) -> alternate
- if ((N1C || N1->getOpcode() == ISD::BUILD_VECTOR) && !TLI.isIntDivCheap()) {
+ if (N1C && !TLI.isIntDivCheap()) {
SDValue Op = BuildUDIV(N);
if (Op.getNode()) return Op;
}
SDValue DAGCombiner::visitSREM(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
- ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
+ ConstantSDNode *N0C = isConstOrConstSplat(N0);
+ ConstantSDNode *N1C = isConstOrConstSplat(N1);
EVT VT = N->getValueType(0);
// fold (srem c1, c2) -> c1%c2
SDValue DAGCombiner::visitUREM(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
- ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
- ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
+ ConstantSDNode *N0C = isConstOrConstSplat(N0);
+ ConstantSDNode *N1C = isConstOrConstSplat(N1);
EVT VT = N->getValueType(0);
// fold (urem c1, c2) -> c1%c2
/// multiplying by a magic number. See:
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
SDValue DAGCombiner::BuildSDIV(SDNode *N) {
- const APInt *Divisor;
- if (N->getValueType(0).isVector()) {
- // Handle splat vectors.
- BuildVectorSDNode *BV = cast<BuildVectorSDNode>(N->getOperand(1));
- if (ConstantSDNode *C = BV->getConstantSplatValue())
- Divisor = &C->getAPIntValue();
- else
- return SDValue();
- } else {
- Divisor = &cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue();
- }
+ ConstantSDNode *C = isConstOrConstSplat(N->getOperand(1));
+ if (!C)
+ return SDValue();
// Avoid division by zero.
- if (!*Divisor)
+ if (!C->getAPIntValue())
return SDValue();
std::vector<SDNode*> Built;
- SDValue S = TLI.BuildSDIV(N, *Divisor, DAG, LegalOperations, &Built);
+ SDValue S =
+ TLI.BuildSDIV(N, C->getAPIntValue(), DAG, LegalOperations, &Built);
- for (std::vector<SDNode*>::iterator ii = Built.begin(), ee = Built.end();
- ii != ee; ++ii)
- AddToWorkList(*ii);
+ for (SDNode *N : Built)
+ AddToWorkList(N);
return S;
}
/// multiplying by a magic number. See:
/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
SDValue DAGCombiner::BuildUDIV(SDNode *N) {
- const APInt *Divisor;
- if (N->getValueType(0).isVector()) {
- // Handle splat vectors.
- BuildVectorSDNode *BV = cast<BuildVectorSDNode>(N->getOperand(1));
- if (ConstantSDNode *C = BV->getConstantSplatValue())
- Divisor = &C->getAPIntValue();
- else
- return SDValue();
- } else {
- Divisor = &cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue();
- }
+ ConstantSDNode *C = isConstOrConstSplat(N->getOperand(1));
+ if (!C)
+ return SDValue();
// Avoid division by zero.
- if (!*Divisor)
+ if (!C->getAPIntValue())
return SDValue();
std::vector<SDNode*> Built;
- SDValue S = TLI.BuildUDIV(N, *Divisor, DAG, LegalOperations, &Built);
+ SDValue S =
+ TLI.BuildUDIV(N, C->getAPIntValue(), DAG, LegalOperations, &Built);
- for (std::vector<SDNode*>::iterator ii = Built.begin(), ee = Built.end();
- ii != ee; ++ii)
- AddToWorkList(*ii);
+ for (SDNode *N : Built)
+ AddToWorkList(N);
return S;
}