return N1;
// fold (add c1, c2) -> c1+c2
if (N0C && N1C)
- return DAG.getConstant(N0C->getAPIntValue() + N1C->getAPIntValue(), VT);
+ return DAG.FoldConstantArithmetic(ISD::ADD, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
return DAG.getNode(ISD::ADD, VT, N1, N0);
// fold (add x, 0) -> x
if (N1C && N1C->isNullValue())
return N0;
+ // fold (add Sym, c) -> Sym+c
+ if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))
+ if (!AfterLegalize && TLI.isOffsetFoldingLegal(GA) && N1C &&
+ GA->getOpcode() == ISD::GlobalAddress)
+ return DAG.getGlobalAddress(GA->getGlobal(), VT,
+ GA->getOffset() +
+ (uint64_t)N1C->getSExtValue());
// fold ((c1-A)+c2) -> (c1+c2)-A
if (N1C && N0.getOpcode() == ISD::SUB)
if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getOperand(0)))
return DAG.getConstant(0, N->getValueType(0));
// fold (sub c1, c2) -> c1-c2
if (N0C && N1C)
- return DAG.getNode(ISD::SUB, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SUB, VT, N0C, N1C);
// fold (sub x, c) -> (add x, -c)
if (N1C)
return DAG.getNode(ISD::ADD, VT, N0,
if (N1.getOpcode() == ISD::UNDEF)
return N1;
+ // If the relocation model supports it, consider symbol offsets.
+ if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))
+ if (!AfterLegalize && TLI.isOffsetFoldingLegal(GA)) {
+ // fold (sub Sym, c) -> Sym-c
+ if (N1C && GA->getOpcode() == ISD::GlobalAddress)
+ return DAG.getGlobalAddress(GA->getGlobal(), VT,
+ GA->getOffset() -
+ (uint64_t)N1C->getSExtValue());
+ // fold (sub Sym+c1, Sym+c2) -> c1-c2
+ if (GlobalAddressSDNode *GB = dyn_cast<GlobalAddressSDNode>(N1))
+ if (GA->getGlobal() == GB->getGlobal())
+ return DAG.getConstant((uint64_t)GA->getOffset() - GB->getOffset(),
+ VT);
+ }
+
return SDValue();
}
return DAG.getConstant(0, VT);
// fold (mul c1, c2) -> c1*c2
if (N0C && N1C)
- return DAG.getNode(ISD::MUL, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::MUL, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
return DAG.getNode(ISD::MUL, VT, N1, N0);
DAG.getConstant(N1C->getAPIntValue().logBase2(),
TLI.getShiftAmountTy()));
// fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
- if (N1C && isPowerOf2_64(-N1C->getSignExtended())) {
+ if (N1C && isPowerOf2_64(-N1C->getSExtValue())) {
// FIXME: If the input is something that is easily negated (e.g. a
// single-use add), we should put the negate there.
return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT),
DAG.getNode(ISD::SHL, VT, N0,
- DAG.getConstant(Log2_64(-N1C->getSignExtended()),
+ DAG.getConstant(Log2_64(-N1C->getSExtValue()),
TLI.getShiftAmountTy())));
}
// fold (sdiv c1, c2) -> c1/c2
if (N0C && N1C && !N1C->isNullValue())
- return DAG.getNode(ISD::SDIV, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SDIV, VT, N0C, N1C);
// fold (sdiv X, 1) -> X
- if (N1C && N1C->getSignExtended() == 1LL)
+ if (N1C && N1C->getSExtValue() == 1LL)
return N0;
// fold (sdiv X, -1) -> 0-X
if (N1C && N1C->isAllOnesValue())
}
// fold (sdiv X, pow2) -> simple ops after legalize
if (N1C && !N1C->isNullValue() && !TLI.isIntDivCheap() &&
- (isPowerOf2_64(N1C->getSignExtended()) ||
- isPowerOf2_64(-N1C->getSignExtended()))) {
+ (isPowerOf2_64(N1C->getSExtValue()) ||
+ isPowerOf2_64(-N1C->getSExtValue()))) {
// If dividing by powers of two is cheap, then don't perform the following
// fold.
if (TLI.isPow2DivCheap())
return SDValue();
- int64_t pow2 = N1C->getSignExtended();
+ int64_t pow2 = N1C->getSExtValue();
int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
unsigned lg2 = Log2_64(abs2);
// Splat the sign bit into the register
}
// if integer divide is expensive and we satisfy the requirements, emit an
// alternate sequence.
- if (N1C && (N1C->getSignExtended() < -1 || N1C->getSignExtended() > 1) &&
+ if (N1C && (N1C->getSExtValue() < -1 || N1C->getSExtValue() > 1) &&
!TLI.isIntDivCheap()) {
SDValue Op = BuildSDIV(N);
if (Op.getNode()) return Op;
// fold (udiv c1, c2) -> c1/c2
if (N0C && N1C && !N1C->isNullValue())
- return DAG.getNode(ISD::UDIV, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::UDIV, VT, N0C, N1C);
// fold (udiv x, (1 << c)) -> x >>u c
if (N1C && N1C->getAPIntValue().isPowerOf2())
return DAG.getNode(ISD::SRL, VT, N0,
// fold (srem c1, c2) -> c1%c2
if (N0C && N1C && !N1C->isNullValue())
- return DAG.getNode(ISD::SREM, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SREM, VT, N0C, N1C);
// If we know the sign bits of both operands are zero, strength reduce to a
// urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15
if (!VT.isVector()) {
// fold (urem c1, c2) -> c1%c2
if (N0C && N1C && !N1C->isNullValue())
- return DAG.getNode(ISD::UREM, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::UREM, VT, N0C, N1C);
// fold (urem x, pow2) -> (and x, pow2-1)
if (N1C && !N1C->isNullValue() && N1C->getAPIntValue().isPowerOf2())
return DAG.getNode(ISD::AND, VT, N0,
// X%C to the equivalent of X-X/C*C.
if (N1C && !N1C->isNullValue()) {
SDValue Div = DAG.getNode(ISD::UDIV, VT, N0, N1);
+ AddToWorkList(Div.getNode());
SDValue OptimizedDiv = combine(Div.getNode());
if (OptimizedDiv.getNode() && OptimizedDiv.getNode() != Div.getNode()) {
SDValue Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1);
return DAG.getConstant(0, VT);
// fold (and c1, c2) -> c1&c2
if (N0C && N1C)
- return DAG.getNode(ISD::AND, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::AND, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
return DAG.getNode(ISD::AND, VT, N1, N0);
if (LL == RL && LR == RR) {
bool isInteger = LL.getValueType().isInteger();
ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger);
- if (Result != ISD::SETCC_INVALID)
+ if (Result != ISD::SETCC_INVALID &&
+ (!AfterLegalize || TLI.isCondCodeLegal(Result, LL.getValueType())))
return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
}
}
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
BitWidth - EVT.getSizeInBits())) &&
((!AfterLegalize && !LN0->isVolatile()) ||
- TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
+ TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
BitWidth - EVT.getSizeInBits())) &&
((!AfterLegalize && !LN0->isVolatile()) ||
- TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
+ TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
// Do not generate loads of non-round integer types since these can
// be expensive (and would be wrong if the type is not byte sized).
if (EVT != MVT::Other && LoadedVT.bitsGT(EVT) && EVT.isRound() &&
- (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
+ (!AfterLegalize || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) {
MVT PtrType = N0.getOperand(1).getValueType();
// For big endian targets, we need to add an offset to the pointer to
// load the correct bytes. For little endian systems, we merely need to
return DAG.getConstant(~0ULL, VT);
// fold (or c1, c2) -> c1|c2
if (N0C && N1C)
- return DAG.getNode(ISD::OR, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::OR, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
return DAG.getNode(ISD::OR, VT, N1, N0);
if (LL == RL && LR == RR) {
bool isInteger = LL.getValueType().isInteger();
ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger);
- if (Result != ISD::SETCC_INVALID)
+ if (Result != ISD::SETCC_INVALID &&
+ (!AfterLegalize || TLI.isCondCodeLegal(Result, LL.getValueType())))
return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
}
}
// fold (or (shl x, C1), (srl x, C2)) -> (rotr x, C2)
if (LHSShiftAmt.getOpcode() == ISD::Constant &&
RHSShiftAmt.getOpcode() == ISD::Constant) {
- uint64_t LShVal = cast<ConstantSDNode>(LHSShiftAmt)->getValue();
- uint64_t RShVal = cast<ConstantSDNode>(RHSShiftAmt)->getValue();
+ uint64_t LShVal = cast<ConstantSDNode>(LHSShiftAmt)->getZExtValue();
+ uint64_t RShVal = cast<ConstantSDNode>(RHSShiftAmt)->getZExtValue();
if ((LShVal + RShVal) != OpSizeInBits)
return 0;
if (ConstantSDNode *SUBC =
dyn_cast<ConstantSDNode>(LHSShiftAmt.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
- if (HasROTL)
- return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode();
- else
+ if (HasROTR)
return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).getNode();
+ else
+ return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode();
}
}
}
- // Look for sign/zext/any-extended cases:
+ // Look for sign/zext/any-extended or truncate cases:
if ((LHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND
|| LHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND
- || LHSShiftAmt.getOpcode() == ISD::ANY_EXTEND) &&
+ || LHSShiftAmt.getOpcode() == ISD::ANY_EXTEND
+ || LHSShiftAmt.getOpcode() == ISD::TRUNCATE) &&
(RHSShiftAmt.getOpcode() == ISD::SIGN_EXTEND
|| RHSShiftAmt.getOpcode() == ISD::ZERO_EXTEND
- || RHSShiftAmt.getOpcode() == ISD::ANY_EXTEND)) {
+ || RHSShiftAmt.getOpcode() == ISD::ANY_EXTEND
+ || RHSShiftAmt.getOpcode() == ISD::TRUNCATE)) {
SDValue LExtOp0 = LHSShiftAmt.getOperand(0);
SDValue RExtOp0 = RHSShiftAmt.getOperand(0);
if (RExtOp0.getOpcode() == ISD::SUB &&
// (rotl x, y)
// fold (or (shl x, (*ext y)), (srl x, (*ext (sub 32, y)))) ->
// (rotr x, (sub 32, y))
- if (ConstantSDNode *SUBC = cast<ConstantSDNode>(RExtOp0.getOperand(0))) {
+ if (ConstantSDNode *SUBC =
+ dyn_cast<ConstantSDNode>(RExtOp0.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
return DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, VT, LHSShiftArg,
HasROTL ? LHSShiftAmt : RHSShiftAmt).getNode();
// (rotr x, y)
// fold (or (shl x, (*ext (sub 32, y))), (srl x, (*ext y))) ->
// (rotl x, (sub 32, y))
- if (ConstantSDNode *SUBC = cast<ConstantSDNode>(LExtOp0.getOperand(0))) {
+ if (ConstantSDNode *SUBC =
+ dyn_cast<ConstantSDNode>(LExtOp0.getOperand(0))) {
if (SUBC->getAPIntValue() == OpSizeInBits) {
return DAG.getNode(HasROTR ? ISD::ROTR : ISD::ROTL, VT, LHSShiftArg,
HasROTR ? RHSShiftAmt : LHSShiftAmt).getNode();
return N1;
// fold (xor c1, c2) -> c1^c2
if (N0C && N1C)
- return DAG.getNode(ISD::XOR, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::XOR, VT, N0C, N1C);
// canonicalize constant to RHS
if (N0C && !N1C)
return DAG.getNode(ISD::XOR, VT, N1, N0);
// fold (shl c1, c2) -> c1<<c2
if (N0C && N1C)
- return DAG.getNode(ISD::SHL, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SHL, VT, N0C, N1C);
// fold (shl 0, x) -> 0
if (N0C && N0C->isNullValue())
return N0;
// fold (shl x, c >= size(x)) -> undef
- if (N1C && N1C->getValue() >= OpSizeInBits)
+ if (N1C && N1C->getZExtValue() >= OpSizeInBits)
return DAG.getNode(ISD::UNDEF, VT);
// fold (shl x, 0) -> x
if (N1C && N1C->isNullValue())
// fold (shl x, (trunc (and y, c))) -> (shl x, (and (trunc y), c))
// iff (trunc c) == c
if (N1.getOpcode() == ISD::TRUNCATE &&
- N1.getOperand(0).getOpcode() == ISD::AND) {
+ N1.getOperand(0).getOpcode() == ISD::AND &&
+ N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
SDValue N101 = N1.getOperand(0).getOperand(1);
- ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101);
- if (N101C) {
+ if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
- unsigned TruncBitSize = TruncVT.getSizeInBits();
- APInt ShAmt = N101C->getAPIntValue();
- if (ShAmt.trunc(TruncBitSize).getZExtValue() == N101C->getValue()) {
- SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SHL, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getValue(), TruncVT)));
- }
+ SDValue N100 = N1.getOperand(0).getOperand(0);
+ return DAG.getNode(ISD::SHL, VT, N0,
+ DAG.getNode(ISD::AND, TruncVT,
+ DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
+ DAG.getConstant(N101C->getZExtValue(),
+ TruncVT)));
}
}
// fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2)
if (N1C && N0.getOpcode() == ISD::SHL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
- uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
- uint64_t c2 = N1C->getValue();
+ uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
+ uint64_t c2 = N1C->getZExtValue();
if (c1 + c2 > OpSizeInBits)
return DAG.getConstant(0, VT);
return DAG.getNode(ISD::SHL, VT, N0.getOperand(0),
// (srl (and x, -1 << c1), c1-c2)
if (N1C && N0.getOpcode() == ISD::SRL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
- uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
- uint64_t c2 = N1C->getValue();
+ uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
+ uint64_t c2 = N1C->getZExtValue();
SDValue Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0),
DAG.getConstant(~0ULL << c1, VT));
if (c2 > c1)
// fold (shl (sra x, c1), c1) -> (and x, -1 << c1)
if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1))
return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
- DAG.getConstant(~0ULL << N1C->getValue(), VT));
+ DAG.getConstant(~0ULL << N1C->getZExtValue(), VT));
- return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDValue();
+ return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
}
SDValue DAGCombiner::visitSRA(SDNode *N) {
// fold (sra c1, c2) -> c1>>c2
if (N0C && N1C)
- return DAG.getNode(ISD::SRA, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SRA, VT, N0C, N1C);
// fold (sra 0, x) -> 0
if (N0C && N0C->isNullValue())
return N0;
if (N0C && N0C->isAllOnesValue())
return N0;
// fold (sra x, c >= size(x)) -> undef
- if (N1C && N1C->getValue() >= VT.getSizeInBits())
+ if (N1C && N1C->getZExtValue() >= VT.getSizeInBits())
return DAG.getNode(ISD::UNDEF, VT);
// fold (sra x, 0) -> x
if (N1C && N1C->isNullValue())
// fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and target supports
// sext_inreg.
if (N1C && N0.getOpcode() == ISD::SHL && N1 == N0.getOperand(1)) {
- unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getValue();
+ unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getZExtValue();
MVT EVT = MVT::getIntegerVT(LowBits);
if (EVT.isSimple() && // TODO: remove when apint codegen support lands.
(!AfterLegalize || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT)))
// fold (sra (sra x, c1), c2) -> (sra x, c1+c2)
if (N1C && N0.getOpcode() == ISD::SRA) {
if (ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
- unsigned Sum = N1C->getValue() + C1->getValue();
+ unsigned Sum = N1C->getZExtValue() + C1->getZExtValue();
if (Sum >= VT.getSizeInBits()) Sum = VT.getSizeInBits()-1;
return DAG.getNode(ISD::SRA, VT, N0.getOperand(0),
DAG.getConstant(Sum, N1C->getValueType(0)));
// Determine what the truncate's result bitsize and type would be.
unsigned VTValSize = VT.getSizeInBits();
MVT TruncVT =
- MVT::getIntegerVT(VTValSize - N1C->getValue());
+ MVT::getIntegerVT(VTValSize - N1C->getZExtValue());
// Determine the residual right-shift amount.
- unsigned ShiftAmt = N1C->getValue() - N01C->getValue();
+ unsigned ShiftAmt = N1C->getZExtValue() - N01C->getZExtValue();
// If the shift is not a no-op (in which case this should be just a sign
// extend already), the truncated to type is legal, sign_extend is legal
// fold (sra x, (trunc (and y, c))) -> (sra x, (and (trunc y), c))
// iff (trunc c) == c
if (N1.getOpcode() == ISD::TRUNCATE &&
- N1.getOperand(0).getOpcode() == ISD::AND) {
+ N1.getOperand(0).getOpcode() == ISD::AND &&
+ N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
SDValue N101 = N1.getOperand(0).getOperand(1);
- ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101);
- if (N101C) {
+ if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
- unsigned TruncBitSize = TruncVT.getSizeInBits();
- APInt ShAmt = N101C->getAPIntValue();
- if (ShAmt.trunc(TruncBitSize).getZExtValue() == N101C->getValue()) {
- SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SRA, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getValue(), TruncVT)));
- }
+ SDValue N100 = N1.getOperand(0).getOperand(0);
+ return DAG.getNode(ISD::SRA, VT, N0,
+ DAG.getNode(ISD::AND, TruncVT,
+ DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
+ DAG.getConstant(N101C->getZExtValue(),
+ TruncVT)));
}
}
if (DAG.SignBitIsZero(N0))
return DAG.getNode(ISD::SRL, VT, N0, N1);
- return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDValue();
+ return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
}
SDValue DAGCombiner::visitSRL(SDNode *N) {
// fold (srl c1, c2) -> c1 >>u c2
if (N0C && N1C)
- return DAG.getNode(ISD::SRL, VT, N0, N1);
+ return DAG.FoldConstantArithmetic(ISD::SRL, VT, N0C, N1C);
// fold (srl 0, x) -> 0
if (N0C && N0C->isNullValue())
return N0;
// fold (srl x, c >= size(x)) -> undef
- if (N1C && N1C->getValue() >= OpSizeInBits)
+ if (N1C && N1C->getZExtValue() >= OpSizeInBits)
return DAG.getNode(ISD::UNDEF, VT);
// fold (srl x, 0) -> x
if (N1C && N1C->isNullValue())
// fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2)
if (N1C && N0.getOpcode() == ISD::SRL &&
N0.getOperand(1).getOpcode() == ISD::Constant) {
- uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
- uint64_t c2 = N1C->getValue();
+ uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
+ uint64_t c2 = N1C->getZExtValue();
if (c1 + c2 > OpSizeInBits)
return DAG.getConstant(0, VT);
return DAG.getNode(ISD::SRL, VT, N0.getOperand(0),
if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
// Shifting in all undef bits?
MVT SmallVT = N0.getOperand(0).getValueType();
- if (N1C->getValue() >= SmallVT.getSizeInBits())
+ if (N1C->getZExtValue() >= SmallVT.getSizeInBits())
return DAG.getNode(ISD::UNDEF, VT);
SDValue SmallShift = DAG.getNode(ISD::SRL, SmallVT, N0.getOperand(0), N1);
// fold (srl (sra X, Y), 31) -> (srl X, 31). This srl only looks at the sign
// bit, which is unmodified by sra.
- if (N1C && N1C->getValue()+1 == VT.getSizeInBits()) {
+ if (N1C && N1C->getZExtValue()+1 == VT.getSizeInBits()) {
if (N0.getOpcode() == ISD::SRA)
return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), N1);
}
// fold (srl x, (trunc (and y, c))) -> (srl x, (and (trunc y), c))
// iff (trunc c) == c
if (N1.getOpcode() == ISD::TRUNCATE &&
- N1.getOperand(0).getOpcode() == ISD::AND) {
+ N1.getOperand(0).getOpcode() == ISD::AND &&
+ N1.hasOneUse() && N1.getOperand(0).hasOneUse()) {
SDValue N101 = N1.getOperand(0).getOperand(1);
- ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101);
- if (N101C) {
+ if (ConstantSDNode *N101C = dyn_cast<ConstantSDNode>(N101)) {
MVT TruncVT = N1.getValueType();
- unsigned TruncBitSize = TruncVT.getSizeInBits();
- APInt ShAmt = N101C->getAPIntValue();
- if (ShAmt.trunc(TruncBitSize).getZExtValue() == N101C->getValue()) {
- SDValue N100 = N1.getOperand(0).getOperand(0);
- return DAG.getNode(ISD::SRL, VT, N0,
- DAG.getNode(ISD::AND, TruncVT,
- DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
- DAG.getConstant(N101C->getValue(), TruncVT)));
- }
+ SDValue N100 = N1.getOperand(0).getOperand(0);
+ return DAG.getNode(ISD::SRL, VT, N0,
+ DAG.getNode(ISD::AND, TruncVT,
+ DAG.getNode(ISD::TRUNCATE, TruncVT, N100),
+ DAG.getConstant(N101C->getZExtValue(),
+ TruncVT)));
}
}
if (N1C && SimplifyDemandedBits(SDValue(N, 0)))
return SDValue(N, 0);
- return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDValue();
+ return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue();
}
SDValue DAGCombiner::visitCTLZ(SDNode *N) {
// fold (sext (load x)) -> (sext (truncate (sextload x)))
if (ISD::isNON_EXTLoad(N0.getNode()) &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::SEXTLOAD, N0.getValueType()))) {
+ TLI.isLoadExtLegal(ISD::SEXTLOAD, N0.getValueType()))) {
bool DoXform = true;
SmallVector<SDNode*, 4> SetCCs;
if (!N0.hasOneUse())
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT EVT = LN0->getMemoryVT();
if ((!AfterLegalize && !LN0->isVolatile()) ||
- TLI.isLoadXLegal(ISD::SEXTLOAD, EVT)) {
+ TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) {
SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
// fold (zext (load x)) -> (zext (truncate (zextload x)))
if (ISD::isNON_EXTLoad(N0.getNode()) &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::ZEXTLOAD, N0.getValueType()))) {
+ TLI.isLoadExtLegal(ISD::ZEXTLOAD, N0.getValueType()))) {
bool DoXform = true;
SmallVector<SDNode*, 4> SetCCs;
if (!N0.hasOneUse())
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT EVT = LN0->getMemoryVT();
if ((!AfterLegalize && !LN0->isVolatile()) ||
- TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT)) {
+ TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT)) {
SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT,
// fold (aext (load x)) -> (aext (truncate (extload x)))
if (ISD::isNON_EXTLoad(N0.getNode()) && N0.hasOneUse() &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) {
+ TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
break;
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
// See if we can recursively simplify the LHS.
- unsigned Amt = RHSC->getValue();
+ unsigned Amt = RHSC->getZExtValue();
APInt NewMask = Mask << Amt;
SDValue SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask);
if (SimplifyLHS.getNode()) {
if (Opc == ISD::SIGN_EXTEND_INREG) {
ExtType = ISD::SEXTLOAD;
EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
- if (AfterLegalize && !TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))
+ if (AfterLegalize && !TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))
return SDValue();
}
bool CombineSRL = false;
if (N0.getOpcode() == ISD::SRL && N0.hasOneUse()) {
if (ConstantSDNode *N01 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
- ShAmt = N01->getValue();
+ ShAmt = N01->getZExtValue();
// Is the shift amount a multiple of size of VT?
if ((ShAmt & (EVTBits-1)) == 0) {
N0 = N0.getOperand(0);
// We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above.
if (N0.getOpcode() == ISD::SRL) {
if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
- if (ShAmt->getValue()+EVTBits <= VT.getSizeInBits()) {
+ if (ShAmt->getZExtValue()+EVTBits <= VT.getSizeInBits()) {
// We can turn this into an SRA iff the input to the SRL is already sign
// extended enough.
unsigned InSignBits = DAG.ComputeNumSignBits(N0.getOperand(0));
- if (VT.getSizeInBits()-(ShAmt->getValue()+EVTBits) < InSignBits)
+ if (VT.getSizeInBits()-(ShAmt->getZExtValue()+EVTBits) < InSignBits)
return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1));
}
}
ISD::isUNINDEXEDLoad(N0.getNode()) &&
EVT == cast<LoadSDNode>(N0)->getMemoryVT() &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) {
+ TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
N0.hasOneUse() &&
EVT == cast<LoadSDNode>(N0)->getMemoryVT() &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::SEXTLOAD, EVT))) {
+ TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
TLI.isConsecutiveLoad(LD2, LD1, LD1VT.getSizeInBits()/8, 1, MFI)) {
LoadSDNode *LD = cast<LoadSDNode>(LD1);
unsigned Align = LD->getAlignment();
- unsigned NewAlign = TLI.getTargetMachine().getTargetData()->
+ unsigned NewAlign = TLI.getTargetData()->
getABITypeAlignment(VT.getTypeForMVT());
if (NewAlign <= Align &&
(!AfterLegalize || TLI.isOperationLegal(ISD::LOAD, VT)))
}
}
- // If the input is a constant, let Val fold it.
+ // If the input is a constant, let getNode fold it.
if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
SDValue Res = DAG.getNode(ISD::BIT_CONVERT, VT, N0);
if (Res.getNode() != N) return Res;
!cast<LoadSDNode>(N0)->isVolatile() &&
(!AfterLegalize || TLI.isOperationLegal(ISD::LOAD, VT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- unsigned Align = TLI.getTargetMachine().getTargetData()->
+ unsigned Align = TLI.getTargetData()->
getABITypeAlignment(VT.getTypeForMVT());
unsigned OrigAlign = LN0->getAlignment();
if (Align <= OrigAlign) {
// fold (fp_round_inreg c1fp) -> c1fp
if (N0CFP) {
- SDValue Round = DAG.getConstantFP(N0CFP->getValueAPF(), EVT);
+ SDValue Round = DAG.getConstantFP(*N0CFP->getConstantFPValue(), EVT);
return DAG.getNode(ISD::FP_EXTEND, VT, Round);
}
return SDValue();
// fold (fpext (load x)) -> (fpext (fptrunc (extload x)))
if (ISD::isNON_EXTLoad(N0.getNode()) && N0.hasOneUse() &&
((!AfterLegalize && !cast<LoadSDNode>(N0)->isVolatile()) ||
- TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) {
+ TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(),
ST->isUnindexed()) {
unsigned Align = ST->getAlignment();
MVT SVT = Value.getOperand(0).getValueType();
- unsigned OrigAlign = TLI.getTargetMachine().getTargetData()->
+ unsigned OrigAlign = TLI.getTargetData()->
getABITypeAlignment(SVT.getTypeForMVT());
if (Align <= OrigAlign &&
((!AfterLegalize && !ST->isVolatile()) ||
if ((!AfterLegalize && !ST->isVolatile()) ||
TLI.isOperationLegal(ISD::STORE, MVT::i32)) {
Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF().
- convertToAPInt().getZExtValue(), MVT::i32);
+ bitcastToAPInt().getZExtValue(), MVT::i32);
return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
ST->getAlignment());
case MVT::f64:
if ((!AfterLegalize && !ST->isVolatile()) ||
TLI.isOperationLegal(ISD::STORE, MVT::i64)) {
- Tmp = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
+ Tmp = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt().
getZExtValue(), MVT::i64);
return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(),
ST->getSrcValueOffset(), ST->isVolatile(),
// Many FP stores are not made apparent until after legalize, e.g. for
// argument passing. Since this is so common, custom legalize the
// 64-bit integer store into two 32-bit stores.
- uint64_t Val = CFP->getValueAPF().convertToAPInt().getZExtValue();
+ uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
SDValue Lo = DAG.getConstant(Val & 0xFFFFFFFF, MVT::i32);
SDValue Hi = DAG.getConstant(Val >> 32, MVT::i32);
if (TLI.isBigEndian()) std::swap(Lo, Hi);
// If the invec is a BUILD_VECTOR and if EltNo is a constant, build a new
// vector with the inserted element.
if (InVec.getOpcode() == ISD::BUILD_VECTOR && isa<ConstantSDNode>(EltNo)) {
- unsigned Elt = cast<ConstantSDNode>(EltNo)->getValue();
+ unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
SmallVector<SDValue, 8> Ops(InVec.getNode()->op_begin(),
InVec.getNode()->op_end());
if (Elt < Ops.size())
SDValue EltNo = N->getOperand(1);
if (isa<ConstantSDNode>(EltNo)) {
- unsigned Elt = cast<ConstantSDNode>(EltNo)->getValue();
+ unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
bool NewLoad = false;
MVT VT = InVec.getValueType();
MVT EVT = VT.getVectorElementType();
// =>
// (load $addr+1*size)
unsigned Idx = cast<ConstantSDNode>(InVec.getOperand(2).
- getOperand(Elt))->getValue();
+ getOperand(Elt))->getZExtValue();
unsigned NumElems = InVec.getOperand(2).getNumOperands();
InVec = (Idx < NumElems) ? InVec.getOperand(0) : InVec.getOperand(1);
if (InVec.getOpcode() == ISD::BIT_CONVERT)
if (NewLoad) {
// Check the resultant load doesn't need a higher alignment than the
// original load.
- unsigned NewAlign = TLI.getTargetMachine().getTargetData()->
+ unsigned NewAlign = TLI.getTargetData()->
getABITypeAlignment(LVT.getTypeForMVT());
if (NewAlign > Align || !TLI.isOperationLegal(ISD::LOAD, LVT))
return SDValue();
}
// Otherwise, use InIdx + VecSize
- unsigned Idx = cast<ConstantSDNode>(Extract.getOperand(1))->getValue();
+ unsigned Idx =
+ cast<ConstantSDNode>(Extract.getOperand(1))->getZExtValue();
BuildVecIndices.push_back(DAG.getIntPtrConstant(Idx+NumInScalars));
}
SDValue ShufMask = N->getOperand(2);
unsigned NumElts = ShufMask.getNumOperands();
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+
+ assert(N0.getValueType().getVectorNumElements() == NumElts &&
+ "Vector shuffle must be normalized in DAG");
+
// If the shuffle mask is an identity operation on the LHS, return the LHS.
bool isIdentity = true;
for (unsigned i = 0; i != NumElts; ++i) {
if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF &&
- cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue() != i) {
+ cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue() != i) {
isIdentity = false;
break;
}
isIdentity = true;
for (unsigned i = 0; i != NumElts; ++i) {
if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF &&
- cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue() != i+NumElts) {
+ cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue() !=
+ i+NumElts) {
isIdentity = false;
break;
}
unsigned BaseIdx = 0;
for (unsigned i = 0; i != NumElts; ++i)
if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF) {
- unsigned Idx = cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue();
+ unsigned Idx=cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue();
int V = (Idx < NumElts) ? 0 : 1;
if (VecNum == -1) {
VecNum = V;
}
}
- SDValue N0 = N->getOperand(0);
- SDValue N1 = N->getOperand(1);
// Normalize unary shuffle so the RHS is undef.
if (isUnary && VecNum == 1)
std::swap(N0, N1);
SmallVector<SDValue, 8> MappedOps;
for (unsigned i = 0; i != NumElts; ++i) {
if (ShufMask.getOperand(i).getOpcode() == ISD::UNDEF ||
- cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue() < NumElts) {
+ cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue() <
+ NumElts) {
MappedOps.push_back(ShufMask.getOperand(i));
} else {
unsigned NewIdx =
- cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue() - NumElts;
+ cast<ConstantSDNode>(ShufMask.getOperand(i))->getZExtValue() -
+ NumElts;
MappedOps.push_back(DAG.getConstant(NewIdx,
ShufMask.getOperand(i).getValueType()));
}
std::vector<SDValue> IdxOps;
unsigned NumOps = RHS.getNumOperands();
unsigned NumElts = NumOps;
- MVT EVT = RHS.getValueType().getVectorElementType();
for (unsigned i = 0; i != NumElts; ++i) {
SDValue Elt = RHS.getOperand(i);
if (!isa<ConstantSDNode>(Elt))
return SDValue();
else if (cast<ConstantSDNode>(Elt)->isAllOnesValue())
- IdxOps.push_back(DAG.getConstant(i, EVT));
+ IdxOps.push_back(DAG.getIntPtrConstant(i));
else if (cast<ConstantSDNode>(Elt)->isNullValue())
- IdxOps.push_back(DAG.getConstant(NumElts, EVT));
+ IdxOps.push_back(DAG.getIntPtrConstant(NumElts));
else
return SDValue();
}
// Let's see if the target supports this vector_shuffle.
- if (!TLI.isVectorClearMaskLegal(IdxOps, EVT, DAG))
+ if (!TLI.isVectorClearMaskLegal(IdxOps, TLI.getPointerTy(), DAG))
return SDValue();
// Return the new VECTOR_SHUFFLE node.
+ MVT EVT = RHS.getValueType().getVectorElementType();
MVT VT = MVT::getVectorVT(EVT, NumElts);
+ MVT MaskVT = MVT::getVectorVT(TLI.getPointerTy(), NumElts);
std::vector<SDValue> Ops;
LHS = DAG.getNode(ISD::BIT_CONVERT, VT, LHS);
Ops.push_back(LHS);
std::vector<SDValue> ZeroOps(NumElts, DAG.getConstant(0, EVT));
Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, VT,
&ZeroOps[0], ZeroOps.size()));
- Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, VT,
+ Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
&IdxOps[0], IdxOps.size()));
SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, VT,
&Ops[0], Ops.size());
if (Base.getOpcode() == ISD::ADD) {
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Base.getOperand(1))) {
Base = Base.getOperand(0);
- Offset += C->getValue();
+ Offset += C->getZExtValue();
}
}