mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-19 18:24:00 +00:00
Convert MaskedValueIsZero and all its users to use APInt. Also add
a SignBitIsZero function to simplify a common use case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47561 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -555,10 +555,14 @@ public:
|
|||||||
SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1,
|
SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1,
|
||||||
SDOperand N2, ISD::CondCode Cond);
|
SDOperand N2, ISD::CondCode Cond);
|
||||||
|
|
||||||
|
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
|
||||||
|
/// use this predicate to simplify operations downstream.
|
||||||
|
bool SignBitIsZero(SDOperand Op, unsigned Depth = 0) const;
|
||||||
|
|
||||||
/// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
|
/// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
|
||||||
/// use this predicate to simplify operations downstream. Op and Mask are
|
/// use this predicate to simplify operations downstream. Op and Mask are
|
||||||
/// known to be the same type.
|
/// known to be the same type.
|
||||||
bool MaskedValueIsZero(SDOperand Op, uint64_t Mask, unsigned Depth = 0)
|
bool MaskedValueIsZero(SDOperand Op, const APInt &Mask, unsigned Depth = 0)
|
||||||
const;
|
const;
|
||||||
|
|
||||||
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
|
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
|
||||||
|
@ -218,7 +218,7 @@ namespace {
|
|||||||
SDNode *MatchRotate(SDOperand LHS, SDOperand RHS);
|
SDNode *MatchRotate(SDOperand LHS, SDOperand RHS);
|
||||||
SDOperand ReduceLoadWidth(SDNode *N);
|
SDOperand ReduceLoadWidth(SDNode *N);
|
||||||
|
|
||||||
SDOperand GetDemandedBits(SDOperand V, uint64_t Mask);
|
SDOperand GetDemandedBits(SDOperand V, const APInt &Mask);
|
||||||
|
|
||||||
/// GatherAllAliases - Walk up chain skipping non-aliasing memory nodes,
|
/// GatherAllAliases - Walk up chain skipping non-aliasing memory nodes,
|
||||||
/// looking for aliasing nodes and adding them to the Aliases vector.
|
/// looking for aliasing nodes and adding them to the Aliases vector.
|
||||||
@ -1226,9 +1226,7 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
|
|||||||
// If we know the sign bits of both operands are zero, strength reduce to a
|
// If we know the sign bits of both operands are zero, strength reduce to a
|
||||||
// udiv instead. Handles (X&15) /s 4 -> X&15 >> 2
|
// udiv instead. Handles (X&15) /s 4 -> X&15 >> 2
|
||||||
if (!MVT::isVector(VT)) {
|
if (!MVT::isVector(VT)) {
|
||||||
uint64_t SignBit = MVT::getIntVTSignBit(VT);
|
if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
|
||||||
if (DAG.MaskedValueIsZero(N1, SignBit) &&
|
|
||||||
DAG.MaskedValueIsZero(N0, SignBit))
|
|
||||||
return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
|
return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
|
||||||
}
|
}
|
||||||
// fold (sdiv X, pow2) -> simple ops after legalize
|
// fold (sdiv X, pow2) -> simple ops after legalize
|
||||||
@ -1344,9 +1342,7 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) {
|
|||||||
// If we know the sign bits of both operands are zero, strength reduce to a
|
// If we know the sign bits of both operands are zero, strength reduce to a
|
||||||
// urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15
|
// urem instead. Handles (X & 0x0FFFFFFF) %s 16 -> X&15
|
||||||
if (!MVT::isVector(VT)) {
|
if (!MVT::isVector(VT)) {
|
||||||
uint64_t SignBit = MVT::getIntVTSignBit(VT);
|
if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
|
||||||
if (DAG.MaskedValueIsZero(N1, SignBit) &&
|
|
||||||
DAG.MaskedValueIsZero(N0, SignBit))
|
|
||||||
return DAG.getNode(ISD::UREM, VT, N0, N1);
|
return DAG.getNode(ISD::UREM, VT, N0, N1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1588,6 +1584,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
|||||||
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
||||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||||
MVT::ValueType VT = N1.getValueType();
|
MVT::ValueType VT = N1.getValueType();
|
||||||
|
unsigned BitWidth = MVT::getSizeInBits(VT);
|
||||||
|
|
||||||
// fold vector ops
|
// fold vector ops
|
||||||
if (MVT::isVector(VT)) {
|
if (MVT::isVector(VT)) {
|
||||||
@ -1608,7 +1605,8 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
|||||||
if (N1C && N1C->isAllOnesValue())
|
if (N1C && N1C->isAllOnesValue())
|
||||||
return N0;
|
return N0;
|
||||||
// if (and x, c) is known to be zero, return 0
|
// if (and x, c) is known to be zero, return 0
|
||||||
if (N1C && DAG.MaskedValueIsZero(SDOperand(N, 0), MVT::getIntVTBitMask(VT)))
|
if (N1C && DAG.MaskedValueIsZero(SDOperand(N, 0),
|
||||||
|
APInt::getAllOnesValue(BitWidth)))
|
||||||
return DAG.getConstant(0, VT);
|
return DAG.getConstant(0, VT);
|
||||||
// reassociate and
|
// reassociate and
|
||||||
SDOperand RAND = ReassociateOps(ISD::AND, N0, N1);
|
SDOperand RAND = ReassociateOps(ISD::AND, N0, N1);
|
||||||
@ -1621,11 +1619,12 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
|||||||
return N1;
|
return N1;
|
||||||
// fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits.
|
// fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits.
|
||||||
if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
|
if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
|
||||||
unsigned InMask = MVT::getIntVTBitMask(N0.getOperand(0).getValueType());
|
SDOperand N0Op0 = N0.getOperand(0);
|
||||||
if (DAG.MaskedValueIsZero(N0.getOperand(0),
|
APInt Mask = ~N1C->getAPIntValue();
|
||||||
~N1C->getValue() & InMask)) {
|
Mask.trunc(N0Op0.getValueSizeInBits());
|
||||||
|
if (DAG.MaskedValueIsZero(N0Op0, Mask)) {
|
||||||
SDOperand Zext = DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(),
|
SDOperand Zext = DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(),
|
||||||
N0.getOperand(0));
|
N0Op0);
|
||||||
|
|
||||||
// Replace uses of the AND with uses of the Zero extend node.
|
// Replace uses of the AND with uses of the Zero extend node.
|
||||||
CombineTo(N, Zext);
|
CombineTo(N, Zext);
|
||||||
@ -1693,7 +1692,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
|||||||
MVT::ValueType EVT = LN0->getMemoryVT();
|
MVT::ValueType EVT = LN0->getMemoryVT();
|
||||||
// If we zero all the possible extended bits, then we can turn this into
|
// If we zero all the possible extended bits, then we can turn this into
|
||||||
// a zextload if we are running before legalize or the operation is legal.
|
// a zextload if we are running before legalize or the operation is legal.
|
||||||
if (DAG.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
|
unsigned BitWidth = N1.getValueSizeInBits();
|
||||||
|
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
|
||||||
|
BitWidth - MVT::getSizeInBits(EVT))) &&
|
||||||
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
|
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
|
||||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
|
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
|
||||||
LN0->getBasePtr(), LN0->getSrcValue(),
|
LN0->getBasePtr(), LN0->getSrcValue(),
|
||||||
@ -1712,7 +1713,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
|
|||||||
MVT::ValueType EVT = LN0->getMemoryVT();
|
MVT::ValueType EVT = LN0->getMemoryVT();
|
||||||
// If we zero all the possible extended bits, then we can turn this into
|
// If we zero all the possible extended bits, then we can turn this into
|
||||||
// a zextload if we are running before legalize or the operation is legal.
|
// a zextload if we are running before legalize or the operation is legal.
|
||||||
if (DAG.MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT)) &&
|
unsigned BitWidth = N1.getValueSizeInBits();
|
||||||
|
if (DAG.MaskedValueIsZero(N1, APInt::getHighBitsSet(BitWidth,
|
||||||
|
BitWidth - MVT::getSizeInBits(EVT))) &&
|
||||||
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
|
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
|
||||||
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
|
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
|
||||||
LN0->getBasePtr(), LN0->getSrcValue(),
|
LN0->getBasePtr(), LN0->getSrcValue(),
|
||||||
@ -1780,7 +1783,6 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
|
|||||||
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
|
||||||
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
|
||||||
MVT::ValueType VT = N1.getValueType();
|
MVT::ValueType VT = N1.getValueType();
|
||||||
unsigned OpSizeInBits = MVT::getSizeInBits(VT);
|
|
||||||
|
|
||||||
// fold vector ops
|
// fold vector ops
|
||||||
if (MVT::isVector(VT)) {
|
if (MVT::isVector(VT)) {
|
||||||
@ -1804,8 +1806,7 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
|
|||||||
if (N1C && N1C->isAllOnesValue())
|
if (N1C && N1C->isAllOnesValue())
|
||||||
return N1;
|
return N1;
|
||||||
// fold (or x, c) -> c iff (x & ~c) == 0
|
// fold (or x, c) -> c iff (x & ~c) == 0
|
||||||
if (N1C &&
|
if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue()))
|
||||||
DAG.MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
|
|
||||||
return N1;
|
return N1;
|
||||||
// reassociate or
|
// reassociate or
|
||||||
SDOperand ROR = ReassociateOps(ISD::OR, N0, N1);
|
SDOperand ROR = ReassociateOps(ISD::OR, N0, N1);
|
||||||
@ -1871,8 +1872,10 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
|
|||||||
(N0.Val->hasOneUse() || N1.Val->hasOneUse())) {
|
(N0.Val->hasOneUse() || N1.Val->hasOneUse())) {
|
||||||
// We can only do this xform if we know that bits from X that are set in C2
|
// We can only do this xform if we know that bits from X that are set in C2
|
||||||
// but not in C1 are already zero. Likewise for Y.
|
// but not in C1 are already zero. Likewise for Y.
|
||||||
uint64_t LHSMask = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
|
const APInt &LHSMask =
|
||||||
uint64_t RHSMask = cast<ConstantSDNode>(N1.getOperand(1))->getValue();
|
cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue();
|
||||||
|
const APInt &RHSMask =
|
||||||
|
cast<ConstantSDNode>(N1.getOperand(1))->getAPIntValue();
|
||||||
|
|
||||||
if (DAG.MaskedValueIsZero(N0.getOperand(0), RHSMask&~LHSMask) &&
|
if (DAG.MaskedValueIsZero(N0.getOperand(0), RHSMask&~LHSMask) &&
|
||||||
DAG.MaskedValueIsZero(N1.getOperand(0), LHSMask&~RHSMask)) {
|
DAG.MaskedValueIsZero(N1.getOperand(0), LHSMask&~RHSMask)) {
|
||||||
@ -2271,7 +2274,8 @@ SDOperand DAGCombiner::visitSHL(SDNode *N) {
|
|||||||
if (N1C && N1C->isNullValue())
|
if (N1C && N1C->isNullValue())
|
||||||
return N0;
|
return N0;
|
||||||
// if (shl x, c) is known to be zero, return 0
|
// if (shl x, c) is known to be zero, return 0
|
||||||
if (DAG.MaskedValueIsZero(SDOperand(N, 0), MVT::getIntVTBitMask(VT)))
|
if (DAG.MaskedValueIsZero(SDOperand(N, 0),
|
||||||
|
APInt::getAllOnesValue(MVT::getSizeInBits(VT))))
|
||||||
return DAG.getConstant(0, VT);
|
return DAG.getConstant(0, VT);
|
||||||
if (N1C && SimplifyDemandedBits(SDOperand(N, 0)))
|
if (N1C && SimplifyDemandedBits(SDOperand(N, 0)))
|
||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
@ -2363,7 +2367,7 @@ SDOperand DAGCombiner::visitSRA(SDNode *N) {
|
|||||||
|
|
||||||
|
|
||||||
// If the sign bit is known to be zero, switch this to a SRL.
|
// If the sign bit is known to be zero, switch this to a SRL.
|
||||||
if (DAG.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT)))
|
if (DAG.SignBitIsZero(N0))
|
||||||
return DAG.getNode(ISD::SRL, VT, N0, N1);
|
return DAG.getNode(ISD::SRL, VT, N0, N1);
|
||||||
|
|
||||||
return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDOperand();
|
return N1C ? visitShiftByConstant(N, N1C->getValue()) : SDOperand();
|
||||||
@ -2390,7 +2394,8 @@ SDOperand DAGCombiner::visitSRL(SDNode *N) {
|
|||||||
if (N1C && N1C->isNullValue())
|
if (N1C && N1C->isNullValue())
|
||||||
return N0;
|
return N0;
|
||||||
// if (srl x, c) is known to be zero, return 0
|
// if (srl x, c) is known to be zero, return 0
|
||||||
if (N1C && DAG.MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits)))
|
if (N1C && DAG.MaskedValueIsZero(SDOperand(N, 0),
|
||||||
|
APInt::getAllOnesValue(OpSizeInBits)))
|
||||||
return DAG.getConstant(0, VT);
|
return DAG.getConstant(0, VT);
|
||||||
|
|
||||||
// fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2)
|
// fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2)
|
||||||
@ -3026,7 +3031,7 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
|
|||||||
/// GetDemandedBits - See if the specified operand can be simplified with the
|
/// GetDemandedBits - See if the specified operand can be simplified with the
|
||||||
/// knowledge that only the bits specified by Mask are used. If so, return the
|
/// knowledge that only the bits specified by Mask are used. If so, return the
|
||||||
/// simpler operand, otherwise return a null SDOperand.
|
/// simpler operand, otherwise return a null SDOperand.
|
||||||
SDOperand DAGCombiner::GetDemandedBits(SDOperand V, uint64_t Mask) {
|
SDOperand DAGCombiner::GetDemandedBits(SDOperand V, const APInt &Mask) {
|
||||||
switch (V.getOpcode()) {
|
switch (V.getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
@ -3044,8 +3049,8 @@ SDOperand DAGCombiner::GetDemandedBits(SDOperand V, uint64_t Mask) {
|
|||||||
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
|
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(V.getOperand(1))) {
|
||||||
// See if we can recursively simplify the LHS.
|
// See if we can recursively simplify the LHS.
|
||||||
unsigned Amt = RHSC->getValue();
|
unsigned Amt = RHSC->getValue();
|
||||||
Mask = (Mask << Amt) & MVT::getIntVTBitMask(V.getValueType());
|
APInt NewMask = Mask << Amt;
|
||||||
SDOperand SimplifyLHS = GetDemandedBits(V.getOperand(0), Mask);
|
SDOperand SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask);
|
||||||
if (SimplifyLHS.Val) {
|
if (SimplifyLHS.Val) {
|
||||||
return DAG.getNode(ISD::SRL, V.getValueType(),
|
return DAG.getNode(ISD::SRL, V.getValueType(),
|
||||||
SimplifyLHS, V.getOperand(1));
|
SimplifyLHS, V.getOperand(1));
|
||||||
@ -3147,6 +3152,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
|
|||||||
SDOperand N1 = N->getOperand(1);
|
SDOperand N1 = N->getOperand(1);
|
||||||
MVT::ValueType VT = N->getValueType(0);
|
MVT::ValueType VT = N->getValueType(0);
|
||||||
MVT::ValueType EVT = cast<VTSDNode>(N1)->getVT();
|
MVT::ValueType EVT = cast<VTSDNode>(N1)->getVT();
|
||||||
|
unsigned VTBits = MVT::getSizeInBits(VT);
|
||||||
unsigned EVTBits = MVT::getSizeInBits(EVT);
|
unsigned EVTBits = MVT::getSizeInBits(EVT);
|
||||||
|
|
||||||
// fold (sext_in_reg c1) -> c1
|
// fold (sext_in_reg c1) -> c1
|
||||||
@ -3164,7 +3170,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero.
|
// fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero.
|
||||||
if (DAG.MaskedValueIsZero(N0, 1ULL << (EVTBits-1)))
|
if (DAG.MaskedValueIsZero(N0, APInt::getBitsSet(VTBits, EVTBits-1, EVTBits)))
|
||||||
return DAG.getZeroExtendInReg(N0, EVT);
|
return DAG.getZeroExtendInReg(N0, EVT);
|
||||||
|
|
||||||
// fold operands of sext_in_reg based on knowledge that the top bits are not
|
// fold operands of sext_in_reg based on knowledge that the top bits are not
|
||||||
@ -3256,7 +3262,9 @@ SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) {
|
|||||||
// See if we can simplify the input to this truncate through knowledge that
|
// See if we can simplify the input to this truncate through knowledge that
|
||||||
// only the low bits are being used. For example "trunc (or (shl x, 8), y)"
|
// only the low bits are being used. For example "trunc (or (shl x, 8), y)"
|
||||||
// -> trunc y
|
// -> trunc y
|
||||||
SDOperand Shorter = GetDemandedBits(N0, MVT::getIntVTBitMask(VT));
|
SDOperand Shorter =
|
||||||
|
GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(),
|
||||||
|
MVT::getSizeInBits(VT)));
|
||||||
if (Shorter.Val)
|
if (Shorter.Val)
|
||||||
return DAG.getNode(ISD::TRUNCATE, VT, Shorter);
|
return DAG.getNode(ISD::TRUNCATE, VT, Shorter);
|
||||||
|
|
||||||
@ -4468,7 +4476,9 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
|
|||||||
// only the low bits are being used. For example:
|
// only the low bits are being used. For example:
|
||||||
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
|
// "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8"
|
||||||
SDOperand Shorter =
|
SDOperand Shorter =
|
||||||
GetDemandedBits(Value, MVT::getIntVTBitMask(ST->getMemoryVT()));
|
GetDemandedBits(Value,
|
||||||
|
APInt::getLowBitsSet(Value.getValueSizeInBits(),
|
||||||
|
MVT::getSizeInBits(ST->getMemoryVT())));
|
||||||
AddToWorkList(Value.Val);
|
AddToWorkList(Value.Val);
|
||||||
if (Shorter.Val)
|
if (Shorter.Val)
|
||||||
return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(),
|
return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(),
|
||||||
|
@ -1779,16 +1779,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
case Legal:
|
case Legal:
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition.
|
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition.
|
||||||
break;
|
break;
|
||||||
case Promote:
|
case Promote: {
|
||||||
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the condition.
|
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the condition.
|
||||||
|
|
||||||
// The top bits of the promoted condition are not necessarily zero, ensure
|
// The top bits of the promoted condition are not necessarily zero, ensure
|
||||||
// that the value is properly zero extended.
|
// that the value is properly zero extended.
|
||||||
|
unsigned BitWidth = Tmp2.getValueSizeInBits();
|
||||||
if (!DAG.MaskedValueIsZero(Tmp2,
|
if (!DAG.MaskedValueIsZero(Tmp2,
|
||||||
MVT::getIntVTBitMask(Tmp2.getValueType())^1))
|
APInt::getHighBitsSet(BitWidth, BitWidth-1)))
|
||||||
Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1);
|
Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Basic block destination (Op#2) is always legal.
|
// Basic block destination (Op#2) is always legal.
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
|
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
|
||||||
@ -2642,14 +2644,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
case Legal:
|
case Legal:
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition.
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition.
|
||||||
break;
|
break;
|
||||||
case Promote:
|
case Promote: {
|
||||||
Tmp1 = PromoteOp(Node->getOperand(0)); // Promote the condition.
|
Tmp1 = PromoteOp(Node->getOperand(0)); // Promote the condition.
|
||||||
// Make sure the condition is either zero or one.
|
// Make sure the condition is either zero or one.
|
||||||
|
unsigned BitWidth = Tmp1.getValueSizeInBits();
|
||||||
if (!DAG.MaskedValueIsZero(Tmp1,
|
if (!DAG.MaskedValueIsZero(Tmp1,
|
||||||
MVT::getIntVTBitMask(Tmp1.getValueType())^1))
|
APInt::getHighBitsSet(BitWidth, BitWidth-1)))
|
||||||
Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1);
|
Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // TrueVal
|
Tmp2 = LegalizeOp(Node->getOperand(1)); // TrueVal
|
||||||
Tmp3 = LegalizeOp(Node->getOperand(2)); // FalseVal
|
Tmp3 = LegalizeOp(Node->getOperand(2)); // FalseVal
|
||||||
|
|
||||||
@ -6338,13 +6342,14 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
|||||||
SDOperand LL, LH, RL, RH;
|
SDOperand LL, LH, RL, RH;
|
||||||
ExpandOp(Node->getOperand(0), LL, LH);
|
ExpandOp(Node->getOperand(0), LL, LH);
|
||||||
ExpandOp(Node->getOperand(1), RL, RH);
|
ExpandOp(Node->getOperand(1), RL, RH);
|
||||||
unsigned BitSize = MVT::getSizeInBits(RH.getValueType());
|
unsigned OuterBitSize = Op.getValueSizeInBits();
|
||||||
|
unsigned InnerBitSize = RH.getValueSizeInBits();
|
||||||
unsigned LHSSB = DAG.ComputeNumSignBits(Op.getOperand(0));
|
unsigned LHSSB = DAG.ComputeNumSignBits(Op.getOperand(0));
|
||||||
unsigned RHSSB = DAG.ComputeNumSignBits(Op.getOperand(1));
|
unsigned RHSSB = DAG.ComputeNumSignBits(Op.getOperand(1));
|
||||||
// FIXME: generalize this to handle other bit sizes
|
if (DAG.MaskedValueIsZero(Op.getOperand(0),
|
||||||
if (LHSSB == 32 && RHSSB == 32 &&
|
APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
|
||||||
DAG.MaskedValueIsZero(Op.getOperand(0), 0xFFFFFFFF00000000ULL) &&
|
DAG.MaskedValueIsZero(Op.getOperand(1),
|
||||||
DAG.MaskedValueIsZero(Op.getOperand(1), 0xFFFFFFFF00000000ULL)) {
|
APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
|
||||||
// The inputs are both zero-extended.
|
// The inputs are both zero-extended.
|
||||||
if (HasUMUL_LOHI) {
|
if (HasUMUL_LOHI) {
|
||||||
// We can emit a umul_lohi.
|
// We can emit a umul_lohi.
|
||||||
@ -6359,7 +6364,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (LHSSB > BitSize && RHSSB > BitSize) {
|
if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
|
||||||
// The input values are both sign-extended.
|
// The input values are both sign-extended.
|
||||||
if (HasSMUL_LOHI) {
|
if (HasSMUL_LOHI) {
|
||||||
// We can emit a smul_lohi.
|
// We can emit a smul_lohi.
|
||||||
|
@ -507,14 +507,15 @@ void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
|
|||||||
SDOperand LL, LH, RL, RH;
|
SDOperand LL, LH, RL, RH;
|
||||||
GetExpandedOp(N->getOperand(0), LL, LH);
|
GetExpandedOp(N->getOperand(0), LL, LH);
|
||||||
GetExpandedOp(N->getOperand(1), RL, RH);
|
GetExpandedOp(N->getOperand(1), RL, RH);
|
||||||
|
unsigned OuterBitSize = MVT::getSizeInBits(VT);
|
||||||
unsigned BitSize = MVT::getSizeInBits(NVT);
|
unsigned BitSize = MVT::getSizeInBits(NVT);
|
||||||
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
|
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
|
||||||
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
|
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
|
||||||
|
|
||||||
// FIXME: generalize this to handle other bit sizes
|
if (DAG.MaskedValueIsZero(N->getOperand(0),
|
||||||
if (LHSSB == 32 && RHSSB == 32 &&
|
APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
|
||||||
DAG.MaskedValueIsZero(N->getOperand(0), 0xFFFFFFFF00000000ULL) &&
|
DAG.MaskedValueIsZero(N->getOperand(1),
|
||||||
DAG.MaskedValueIsZero(N->getOperand(1), 0xFFFFFFFF00000000ULL)) {
|
APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
|
||||||
// The inputs are both zero-extended.
|
// The inputs are both zero-extended.
|
||||||
if (HasUMUL_LOHI) {
|
if (HasUMUL_LOHI) {
|
||||||
// We can emit a umul_lohi.
|
// We can emit a umul_lohi.
|
||||||
|
@ -446,8 +446,9 @@ SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
|
|||||||
|
|
||||||
// The top bits of the promoted condition are not necessarily zero, ensure
|
// The top bits of the promoted condition are not necessarily zero, ensure
|
||||||
// that the value is properly zero extended.
|
// that the value is properly zero extended.
|
||||||
|
unsigned BitWidth = Cond.getValueSizeInBits();
|
||||||
if (!DAG.MaskedValueIsZero(Cond,
|
if (!DAG.MaskedValueIsZero(Cond,
|
||||||
MVT::getIntVTBitMask(Cond.getValueType())^1)) {
|
APInt::getHighBitsSet(BitWidth, BitWidth-1))) {
|
||||||
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
|
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
|
||||||
MarkNewNodes(Cond.Val);
|
MarkNewNodes(Cond.Val);
|
||||||
}
|
}
|
||||||
@ -463,8 +464,9 @@ SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
|
|||||||
|
|
||||||
// The top bits of the promoted condition are not necessarily zero, ensure
|
// The top bits of the promoted condition are not necessarily zero, ensure
|
||||||
// that the value is properly zero extended.
|
// that the value is properly zero extended.
|
||||||
|
unsigned BitWidth = Cond.getValueSizeInBits();
|
||||||
if (!DAG.MaskedValueIsZero(Cond,
|
if (!DAG.MaskedValueIsZero(Cond,
|
||||||
MVT::getIntVTBitMask(Cond.getValueType())^1)) {
|
APInt::getHighBitsSet(BitWidth, BitWidth-1))) {
|
||||||
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
|
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
|
||||||
MarkNewNodes(Cond.Val);
|
MarkNewNodes(Cond.Val);
|
||||||
}
|
}
|
||||||
|
@ -1133,16 +1133,19 @@ SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
|
|||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
|
||||||
|
/// use this predicate to simplify operations downstream.
|
||||||
|
bool SelectionDAG::SignBitIsZero(SDOperand Op, unsigned Depth) const {
|
||||||
|
unsigned BitWidth = Op.getValueSizeInBits();
|
||||||
|
return MaskedValueIsZero(Op, APInt::getSignBit(BitWidth), Depth);
|
||||||
|
}
|
||||||
|
|
||||||
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
|
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
|
||||||
/// this predicate to simplify operations downstream. Mask is known to be zero
|
/// this predicate to simplify operations downstream. Mask is known to be zero
|
||||||
/// for bits that V cannot have.
|
/// for bits that V cannot have.
|
||||||
bool SelectionDAG::MaskedValueIsZero(SDOperand Op, uint64_t Mask,
|
bool SelectionDAG::MaskedValueIsZero(SDOperand Op, const APInt &Mask,
|
||||||
unsigned Depth) const {
|
unsigned Depth) const {
|
||||||
// The masks are not wide enough to represent this type! Should use APInt.
|
APInt KnownZero, KnownOne;
|
||||||
if (Op.getValueType() == MVT::i128)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint64_t KnownZero, KnownOne;
|
|
||||||
ComputeMaskedBits(Op, Mask, KnownZero, KnownOne, Depth);
|
ComputeMaskedBits(Op, Mask, KnownZero, KnownOne, Depth);
|
||||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
return (KnownZero & Mask) == Mask;
|
return (KnownZero & Mask) == Mask;
|
||||||
|
@ -5211,20 +5211,20 @@ HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
|
|||||||
/// specified in the .td file (e.g. 255).
|
/// specified in the .td file (e.g. 255).
|
||||||
bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
|
bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
|
||||||
int64_t DesiredMaskS) const {
|
int64_t DesiredMaskS) const {
|
||||||
uint64_t ActualMask = RHS->getValue();
|
const APInt &ActualMask = RHS->getAPIntValue();
|
||||||
uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
|
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
|
||||||
|
|
||||||
// If the actual mask exactly matches, success!
|
// If the actual mask exactly matches, success!
|
||||||
if (ActualMask == DesiredMask)
|
if (ActualMask == DesiredMask)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the actual AND mask is allowing unallowed bits, this doesn't match.
|
// If the actual AND mask is allowing unallowed bits, this doesn't match.
|
||||||
if (ActualMask & ~DesiredMask)
|
if (ActualMask.intersects(~DesiredMask))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Otherwise, the DAG Combiner may have proven that the value coming in is
|
// Otherwise, the DAG Combiner may have proven that the value coming in is
|
||||||
// either already zero or is not demanded. Check for known zero input bits.
|
// either already zero or is not demanded. Check for known zero input bits.
|
||||||
uint64_t NeededMask = DesiredMask & ~ActualMask;
|
APInt NeededMask = DesiredMask & ~ActualMask;
|
||||||
if (CurDAG->MaskedValueIsZero(LHS, NeededMask))
|
if (CurDAG->MaskedValueIsZero(LHS, NeededMask))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -5240,22 +5240,22 @@ bool SelectionDAGISel::CheckAndMask(SDOperand LHS, ConstantSDNode *RHS,
|
|||||||
/// specified in the .td file (e.g. 255).
|
/// specified in the .td file (e.g. 255).
|
||||||
bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS,
|
bool SelectionDAGISel::CheckOrMask(SDOperand LHS, ConstantSDNode *RHS,
|
||||||
int64_t DesiredMaskS) const {
|
int64_t DesiredMaskS) const {
|
||||||
uint64_t ActualMask = RHS->getValue();
|
const APInt &ActualMask = RHS->getAPIntValue();
|
||||||
uint64_t DesiredMask =DesiredMaskS & MVT::getIntVTBitMask(LHS.getValueType());
|
const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
|
||||||
|
|
||||||
// If the actual mask exactly matches, success!
|
// If the actual mask exactly matches, success!
|
||||||
if (ActualMask == DesiredMask)
|
if (ActualMask == DesiredMask)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the actual AND mask is allowing unallowed bits, this doesn't match.
|
// If the actual AND mask is allowing unallowed bits, this doesn't match.
|
||||||
if (ActualMask & ~DesiredMask)
|
if (ActualMask.intersects(~DesiredMask))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Otherwise, the DAG Combiner may have proven that the value coming in is
|
// Otherwise, the DAG Combiner may have proven that the value coming in is
|
||||||
// either already zero or is not demanded. Check for known zero input bits.
|
// either already zero or is not demanded. Check for known zero input bits.
|
||||||
uint64_t NeededMask = DesiredMask & ~ActualMask;
|
APInt NeededMask = DesiredMask & ~ActualMask;
|
||||||
|
|
||||||
uint64_t KnownZero, KnownOne;
|
APInt KnownZero, KnownOne;
|
||||||
CurDAG->ComputeMaskedBits(LHS, NeededMask, KnownZero, KnownOne);
|
CurDAG->ComputeMaskedBits(LHS, NeededMask, KnownZero, KnownOne);
|
||||||
|
|
||||||
// If all the missing bits in the or are already known to be set, match!
|
// If all the missing bits in the or are already known to be set, match!
|
||||||
|
@ -1187,8 +1187,10 @@ TargetLowering::SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1,
|
|||||||
cast<ConstantSDNode>(N0.getOperand(1))->getValue() == 1) {
|
cast<ConstantSDNode>(N0.getOperand(1))->getValue() == 1) {
|
||||||
// If this is (X^1) == 0/1, swap the RHS and eliminate the xor. We
|
// If this is (X^1) == 0/1, swap the RHS and eliminate the xor. We
|
||||||
// can only do this if the top bits are known zero.
|
// can only do this if the top bits are known zero.
|
||||||
|
unsigned BitWidth = N0.getValueSizeInBits();
|
||||||
if (DAG.MaskedValueIsZero(N0,
|
if (DAG.MaskedValueIsZero(N0,
|
||||||
MVT::getIntVTBitMask(N0.getValueType())-1)){
|
APInt::getHighBitsSet(BitWidth,
|
||||||
|
BitWidth-1))) {
|
||||||
// Okay, get the un-inverted input value.
|
// Okay, get the un-inverted input value.
|
||||||
SDOperand Val;
|
SDOperand Val;
|
||||||
if (N0.getOpcode() == ISD::XOR)
|
if (N0.getOpcode() == ISD::XOR)
|
||||||
@ -1374,18 +1376,24 @@ TargetLowering::SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1,
|
|||||||
if (N0.getOpcode() == ISD::XOR)
|
if (N0.getOpcode() == ISD::XOR)
|
||||||
// If we know that all of the inverted bits are zero, don't bother
|
// If we know that all of the inverted bits are zero, don't bother
|
||||||
// performing the inversion.
|
// performing the inversion.
|
||||||
if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getValue()))
|
if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getAPIntValue()))
|
||||||
return DAG.getSetCC(VT, N0.getOperand(0),
|
return
|
||||||
DAG.getConstant(LHSR->getValue()^RHSC->getValue(),
|
DAG.getSetCC(VT, N0.getOperand(0),
|
||||||
N0.getValueType()), Cond);
|
DAG.getConstant(LHSR->getAPIntValue() ^
|
||||||
|
RHSC->getAPIntValue(),
|
||||||
|
N0.getValueType()),
|
||||||
|
Cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn (C1-X) == C2 --> X == C1-C2
|
// Turn (C1-X) == C2 --> X == C1-C2
|
||||||
if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
|
if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
|
||||||
if (N0.getOpcode() == ISD::SUB && N0.Val->hasOneUse()) {
|
if (N0.getOpcode() == ISD::SUB && N0.Val->hasOneUse()) {
|
||||||
return DAG.getSetCC(VT, N0.getOperand(1),
|
return
|
||||||
DAG.getConstant(SUBC->getValue()-RHSC->getValue(),
|
DAG.getSetCC(VT, N0.getOperand(1),
|
||||||
N0.getValueType()), Cond);
|
DAG.getConstant(SUBC->getAPIntValue() -
|
||||||
|
RHSC->getAPIntValue(),
|
||||||
|
N0.getValueType()),
|
||||||
|
Cond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,9 @@ namespace {
|
|||||||
// see if the missing bits (0x1000) are already known zero if not, the zap
|
// see if the missing bits (0x1000) are already known zero if not, the zap
|
||||||
// isn't okay to do, as it won't clear all the required bits.
|
// isn't okay to do, as it won't clear all the required bits.
|
||||||
if (BitsToCheck &&
|
if (BitsToCheck &&
|
||||||
!CurDAG->MaskedValueIsZero(LHS, BitsToCheck))
|
!CurDAG->MaskedValueIsZero(LHS,
|
||||||
|
APInt(LHS.getValueSizeInBits(),
|
||||||
|
BitsToCheck)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -819,7 +819,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
|
|||||||
// On x86-64, the resultant disp must fit in 32-bits.
|
// On x86-64, the resultant disp must fit in 32-bits.
|
||||||
isInt32(AM.Disp + CN->getSignExtended()) &&
|
isInt32(AM.Disp + CN->getSignExtended()) &&
|
||||||
// Check to see if the LHS & C is zero.
|
// Check to see if the LHS & C is zero.
|
||||||
CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) {
|
CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
|
||||||
AM.Disp += CN->getValue();
|
AM.Disp += CN->getValue();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user