SDValue reassociateOps(unsigned Opc, const SDLoc &DL, SDValue N0,
SDValue N1, SDNodeFlags Flags);
- SDValue visitShiftByConstant(SDNode *N, ConstantSDNode *Amt);
+ SDValue visitShiftByConstant(SDNode *N);
SDValue foldSelectOfConstants(SDNode *N);
SDValue foldVSelectOfConstants(SDNode *N);
/// shift (binop X, C0), C1
/// And want to transform into:
/// binop (shift X, C1), (shift C0, C1)
-SDValue DAGCombiner::visitShiftByConstant(SDNode *N, ConstantSDNode *Amt) {
+SDValue DAGCombiner::visitShiftByConstant(SDNode *N) {
+ assert(isConstOrConstSplat(N->getOperand(1)) && "Expected constant operand");
+
// Do not turn a 'not' into a regular xor.
if (isBitwiseNot(N->getOperand(0)))
return SDValue();
// The inner binop must be one-use, since we want to replace it.
- SDNode *LHS = N->getOperand(0).getNode();
- if (!LHS->hasOneUse()) return SDValue();
+ SDValue LHS = N->getOperand(0);
+ if (!LHS.hasOneUse() || !TLI.isDesirableToCommuteWithShift(N, Level))
+ return SDValue();
// We want to pull some binops through shifts, so that we have (and (shift))
// instead of (shift (and)), likewise for add, or, xor, etc. This sort of
// thing happens with address calculations, so it's important to canonicalize
// it.
- switch (LHS->getOpcode()) {
+ switch (LHS.getOpcode()) {
default:
return SDValue();
case ISD::OR:
}
// We require the RHS of the binop to be a constant and not opaque as well.
- ConstantSDNode *BinOpCst = getAsNonOpaqueConstant(LHS->getOperand(1));
+ ConstantSDNode *BinOpCst = getAsNonOpaqueConstant(LHS.getOperand(1));
if (!BinOpCst)
return SDValue();
// FIXME: disable this unless the input to the binop is a shift by a constant
// or is copy/select. Enable this in other cases when figure out it's exactly
// profitable.
- SDValue BinOpLHSVal = LHS->getOperand(0);
+ SDValue BinOpLHSVal = LHS.getOperand(0);
bool IsShiftByConstant = (BinOpLHSVal.getOpcode() == ISD::SHL ||
BinOpLHSVal.getOpcode() == ISD::SRA ||
BinOpLHSVal.getOpcode() == ISD::SRL) &&
if (IsCopyOrSelect && N->hasOneUse())
return SDValue();
- EVT VT = N->getValueType(0);
-
- if (!TLI.isDesirableToCommuteWithShift(N, Level))
- return SDValue();
-
// Fold the constants, shifting the binop RHS by the shift amount.
- SDValue NewRHS = DAG.getNode(N->getOpcode(), SDLoc(LHS->getOperand(1)),
- N->getValueType(0),
- LHS->getOperand(1), N->getOperand(1));
+ SDLoc DL(N);
+ EVT VT = N->getValueType(0);
+ SDValue NewRHS = DAG.getNode(N->getOpcode(), DL, VT, LHS.getOperand(1),
+ N->getOperand(1));
assert(isa<ConstantSDNode>(NewRHS) && "Folding was not successful!");
- // Create the new shift.
- SDValue NewShift = DAG.getNode(N->getOpcode(),
- SDLoc(LHS->getOperand(0)),
- VT, LHS->getOperand(0), N->getOperand(1));
-
- // Create the new binop.
- return DAG.getNode(LHS->getOpcode(), SDLoc(N), VT, NewShift, NewRHS);
+ SDValue NewShift = DAG.getNode(N->getOpcode(), DL, VT, LHS.getOperand(0),
+ N->getOperand(1));
+ return DAG.getNode(LHS.getOpcode(), DL, VT, NewShift, NewRHS);
}
SDValue DAGCombiner::distributeTruncateThroughAnd(SDNode *N) {
}
if (N1C && !N1C->isOpaque())
- if (SDValue NewSHL = visitShiftByConstant(N, N1C))
+ if (SDValue NewSHL = visitShiftByConstant(N))
return NewSHL;
return SDValue();
return DAG.getNode(ISD::SRL, SDLoc(N), VT, N0, N1);
if (N1C && !N1C->isOpaque())
- if (SDValue NewSRA = visitShiftByConstant(N, N1C))
+ if (SDValue NewSRA = visitShiftByConstant(N))
return NewSRA;
return SDValue();
return SDValue(N, 0);
if (N1C && !N1C->isOpaque())
- if (SDValue NewSRL = visitShiftByConstant(N, N1C))
+ if (SDValue NewSRL = visitShiftByConstant(N))
return NewSRL;
// Attempt to convert a srl of a load into a narrower zero-extending load.