mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
Add a bunch of missed cases. Perhaps the most significant of which is that
assertzext produces zero bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26386 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -141,7 +141,7 @@ const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
/// constant and return true.
|
/// constant and return true.
|
||||||
bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op,
|
bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op,
|
||||||
uint64_t Demanded) {
|
uint64_t Demanded) {
|
||||||
// FIXME: ISD::SELECT
|
// FIXME: ISD::SELECT, ISD::SELECT_CC
|
||||||
switch(Op.getOpcode()) {
|
switch(Op.getOpcode()) {
|
||||||
default: break;
|
default: break;
|
||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
@ -199,15 +199,13 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
|
|||||||
// We know all of the bits for a constant!
|
// We know all of the bits for a constant!
|
||||||
KnownOne = cast<ConstantSDNode>(Op)->getValue() & DemandedMask;
|
KnownOne = cast<ConstantSDNode>(Op)->getValue() & DemandedMask;
|
||||||
KnownZero = ~KnownOne & DemandedMask;
|
KnownZero = ~KnownOne & DemandedMask;
|
||||||
return false;
|
return false; // Don't fall through, will infinitely loop.
|
||||||
case ISD::AND:
|
case ISD::AND:
|
||||||
// If either the LHS or the RHS are Zero, the result is zero.
|
// If either the LHS or the RHS are Zero, the result is zero.
|
||||||
if (SimplifyDemandedBits(Op.getOperand(1), DemandedMask, KnownZero,
|
if (SimplifyDemandedBits(Op.getOperand(1), DemandedMask, KnownZero,
|
||||||
KnownOne, TLO, Depth+1))
|
KnownOne, TLO, Depth+1))
|
||||||
return true;
|
return true;
|
||||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
// If something is known zero on the RHS, the bits aren't demanded on the
|
|
||||||
// LHS.
|
|
||||||
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & ~KnownZero,
|
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & ~KnownZero,
|
||||||
KnownZero2, KnownOne2, TLO, Depth+1))
|
KnownZero2, KnownOne2, TLO, Depth+1))
|
||||||
return true;
|
return true;
|
||||||
@ -334,6 +332,24 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
|
|||||||
if (TLO.ShrinkDemandedConstant(Op, DemandedMask))
|
if (TLO.ShrinkDemandedConstant(Op, DemandedMask))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Only known if known in both the LHS and RHS.
|
||||||
|
KnownOne &= KnownOne2;
|
||||||
|
KnownZero &= KnownZero2;
|
||||||
|
break;
|
||||||
|
case ISD::SELECT_CC:
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(3), DemandedMask, KnownZero,
|
||||||
|
KnownOne, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(2), DemandedMask, KnownZero2,
|
||||||
|
KnownOne2, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
|
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
|
||||||
|
|
||||||
|
// If the operands are constants, see if we can simplify them.
|
||||||
|
if (TLO.ShrinkDemandedConstant(Op, DemandedMask))
|
||||||
|
return true;
|
||||||
|
|
||||||
// Only known if known in both the LHS and RHS.
|
// Only known if known in both the LHS and RHS.
|
||||||
KnownOne &= KnownOne2;
|
KnownOne &= KnownOne2;
|
||||||
KnownZero &= KnownZero2;
|
KnownZero &= KnownZero2;
|
||||||
@ -408,19 +424,20 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
|
|||||||
MVT::ValueType VT = Op.getValueType();
|
MVT::ValueType VT = Op.getValueType();
|
||||||
MVT::ValueType EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
|
MVT::ValueType EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
|
||||||
|
|
||||||
// Sign or Zero extension. Compute the bits in the result that are not
|
// Sign extension. Compute the demanded bits in the result that are not
|
||||||
// present in the input.
|
// present in the input.
|
||||||
uint64_t NotIn = ~MVT::getIntVTBitMask(EVT);
|
uint64_t NewBits = ~MVT::getIntVTBitMask(EVT) & DemandedMask;
|
||||||
uint64_t NewBits = MVT::getIntVTBitMask(VT) & NotIn;
|
|
||||||
|
|
||||||
// Sign extension.
|
// If none of the extended bits are demanded, eliminate the sextinreg.
|
||||||
|
if (NewBits == 0)
|
||||||
|
return TLO.CombineTo(Op, Op.getOperand(0));
|
||||||
|
|
||||||
uint64_t InSignBit = MVT::getIntVTSignBit(EVT);
|
uint64_t InSignBit = MVT::getIntVTSignBit(EVT);
|
||||||
int64_t InputDemandedBits = DemandedMask & MVT::getIntVTBitMask(EVT);
|
int64_t InputDemandedBits = DemandedMask & MVT::getIntVTBitMask(EVT);
|
||||||
|
|
||||||
// If any of the sign extended bits are demanded, we know that the sign
|
// Since the sign extended bits are demanded, we know that the sign
|
||||||
// bit is demanded.
|
// bit is demanded.
|
||||||
if (NewBits & DemandedMask)
|
InputDemandedBits |= InSignBit;
|
||||||
InputDemandedBits |= InSignBit;
|
|
||||||
|
|
||||||
if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits,
|
if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits,
|
||||||
KnownZero, KnownOne, TLO, Depth+1))
|
KnownZero, KnownOne, TLO, Depth+1))
|
||||||
@ -430,19 +447,105 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
|
|||||||
// If the sign bit of the input is known set or clear, then we know the
|
// If the sign bit of the input is known set or clear, then we know the
|
||||||
// top bits of the result.
|
// top bits of the result.
|
||||||
|
|
||||||
// If the input sign bit is known zero, or if the NewBits are not demanded
|
// If the input sign bit is known zero, convert this into a zero extension.
|
||||||
// convert this into a zero extension.
|
if (KnownZero & InSignBit)
|
||||||
if ((KnownZero & InSignBit) || (NewBits & ~DemandedMask) == NewBits) {
|
return TLO.CombineTo(Op,
|
||||||
return TLO.CombineTo(Op, Op.getOperand(0));
|
TLO.DAG.getZeroExtendInReg(Op.getOperand(0), EVT));
|
||||||
} else if (KnownOne & InSignBit) { // Input sign bit known set
|
|
||||||
|
if (KnownOne & InSignBit) { // Input sign bit known set
|
||||||
KnownOne |= NewBits;
|
KnownOne |= NewBits;
|
||||||
KnownZero &= ~NewBits;
|
KnownZero &= ~NewBits;
|
||||||
} else { // Input sign bit unknown
|
} else { // Input sign bit unknown
|
||||||
KnownZero &= ~NewBits;
|
KnownZero &= ~NewBits;
|
||||||
KnownOne &= ~NewBits;
|
KnownOne &= ~NewBits;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISD::CTTZ:
|
||||||
|
case ISD::CTLZ:
|
||||||
|
case ISD::CTPOP: {
|
||||||
|
MVT::ValueType VT = Op.getValueType();
|
||||||
|
unsigned LowBits = Log2_32(MVT::getSizeInBits(VT))+1;
|
||||||
|
KnownZero = ~((1ULL << LowBits)-1) & MVT::getIntVTBitMask(VT);
|
||||||
|
KnownOne = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::ZEXTLOAD: {
|
||||||
|
MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(3))->getVT();
|
||||||
|
KnownZero |= ~MVT::getIntVTBitMask(VT) & DemandedMask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::ZERO_EXTEND: {
|
||||||
|
uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType());
|
||||||
|
|
||||||
|
// If none of the top bits are demanded, convert this into an any_extend.
|
||||||
|
uint64_t NewBits = (~InMask) & DemandedMask;
|
||||||
|
if (NewBits == 0)
|
||||||
|
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND,
|
||||||
|
Op.getValueType(),
|
||||||
|
Op.getOperand(0)));
|
||||||
|
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask,
|
||||||
|
KnownZero, KnownOne, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
|
KnownZero |= NewBits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::SIGN_EXTEND: {
|
||||||
|
MVT::ValueType InVT = Op.getOperand(0).getValueType();
|
||||||
|
uint64_t InMask = MVT::getIntVTBitMask(InVT);
|
||||||
|
uint64_t InSignBit = MVT::getIntVTSignBit(InVT);
|
||||||
|
uint64_t NewBits = (~InMask) & DemandedMask;
|
||||||
|
|
||||||
|
// If none of the top bits are demanded, convert this into an any_extend.
|
||||||
|
if (NewBits == 0)
|
||||||
|
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND,Op.getValueType(),
|
||||||
|
Op.getOperand(0)));
|
||||||
|
|
||||||
|
// Since some of the sign extended bits are demanded, we know that the sign
|
||||||
|
// bit is demanded.
|
||||||
|
uint64_t InDemandedBits = DemandedMask & InMask;
|
||||||
|
InDemandedBits |= InSignBit;
|
||||||
|
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, KnownZero,
|
||||||
|
KnownOne, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If the sign bit is known zero, convert this to a zero extend.
|
||||||
|
if (KnownZero & InSignBit)
|
||||||
|
return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND,
|
||||||
|
Op.getValueType(),
|
||||||
|
Op.getOperand(0)));
|
||||||
|
|
||||||
|
// If the sign bit is known one, the top bits match.
|
||||||
|
if (KnownOne & InSignBit) {
|
||||||
|
KnownOne |= NewBits;
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
} else { // Otherwise, top bits aren't known.
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::ANY_EXTEND: {
|
||||||
|
uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType());
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask,
|
||||||
|
KnownZero, KnownOne, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ISD::AssertZext: {
|
||||||
|
MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(1))->getVT();
|
||||||
|
uint64_t InMask = MVT::getIntVTBitMask(VT);
|
||||||
|
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask & InMask,
|
||||||
|
KnownZero, KnownOne, TLO, Depth+1))
|
||||||
|
return true;
|
||||||
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
|
KnownZero |= ~InMask & DemandedMask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::ADD:
|
case ISD::ADD:
|
||||||
if (ConstantSDNode *AA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
|
if (ConstantSDNode *AA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
|
||||||
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask, KnownZero,
|
if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask, KnownZero,
|
||||||
@ -479,16 +582,13 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ISD::CTTZ:
|
|
||||||
case ISD::CTLZ:
|
|
||||||
case ISD::CTPOP: {
|
|
||||||
MVT::ValueType VT = Op.getValueType();
|
|
||||||
unsigned LowBits = Log2_32(MVT::getSizeInBits(VT))+1;
|
|
||||||
KnownZero = ~((1ULL << LowBits)-1) & MVT::getIntVTBitMask(VT);
|
|
||||||
KnownOne = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we know the value of all of the demanded bits, return this as a
|
||||||
|
// constant.
|
||||||
|
if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask)
|
||||||
|
return TLO.CombineTo(Op, TLO.DAG.getConstant(KnownOne, Op.getValueType()));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,6 +730,40 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case ISD::SIGN_EXTEND_INREG: {
|
||||||
|
MVT::ValueType VT = Op.getValueType();
|
||||||
|
MVT::ValueType EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();
|
||||||
|
|
||||||
|
// Sign extension. Compute the demanded bits in the result that are not
|
||||||
|
// present in the input.
|
||||||
|
uint64_t NewBits = ~MVT::getIntVTBitMask(EVT) & Mask;
|
||||||
|
|
||||||
|
uint64_t InSignBit = MVT::getIntVTSignBit(EVT);
|
||||||
|
int64_t InputDemandedBits = Mask & MVT::getIntVTBitMask(EVT);
|
||||||
|
|
||||||
|
// If the sign extended bits are demanded, we know that the sign
|
||||||
|
// bit is demanded.
|
||||||
|
if (NewBits)
|
||||||
|
InputDemandedBits |= InSignBit;
|
||||||
|
|
||||||
|
ComputeMaskedBits(Op.getOperand(0), InputDemandedBits,
|
||||||
|
KnownZero, KnownOne, Depth+1);
|
||||||
|
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||||
|
|
||||||
|
// If the sign bit of the input is known set or clear, then we know the
|
||||||
|
// top bits of the result.
|
||||||
|
if (KnownZero & InSignBit) { // Input sign bit known clear
|
||||||
|
KnownZero |= NewBits;
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
} else if (KnownOne & InSignBit) { // Input sign bit known set
|
||||||
|
KnownOne |= NewBits;
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
} else { // Input sign bit unknown
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
case ISD::CTTZ:
|
case ISD::CTTZ:
|
||||||
case ISD::CTLZ:
|
case ISD::CTLZ:
|
||||||
case ISD::CTPOP: {
|
case ISD::CTPOP: {
|
||||||
@ -640,28 +774,59 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::ZEXTLOAD: {
|
case ISD::ZEXTLOAD: {
|
||||||
unsigned SrcBits =
|
MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(3))->getVT();
|
||||||
MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
|
KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask;
|
||||||
KnownZero |= ~((1ULL << SrcBits)-1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::ZERO_EXTEND: {
|
case ISD::ZERO_EXTEND: {
|
||||||
unsigned SrcBits =
|
uint64_t InMask = MVT::getIntVTBitMask(Op.getOperand(0).getValueType());
|
||||||
MVT::getSizeInBits(Op.getOperand(0).getValueType());
|
uint64_t NewBits = (~InMask) & Mask;
|
||||||
KnownZero |= ~((1ULL << SrcBits)-1);
|
ComputeMaskedBits(Op.getOperand(0), Mask & InMask, KnownZero,
|
||||||
|
KnownOne, Depth+1);
|
||||||
|
KnownZero |= NewBits & Mask;
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case ISD::SIGN_EXTEND: {
|
||||||
|
MVT::ValueType InVT = Op.getOperand(0).getValueType();
|
||||||
|
unsigned InBits = MVT::getSizeInBits(InVT);
|
||||||
|
uint64_t InMask = MVT::getIntVTBitMask(InVT);
|
||||||
|
uint64_t InSignBit = 1ULL << (InBits-1);
|
||||||
|
uint64_t NewBits = (~InMask) & Mask;
|
||||||
|
uint64_t InDemandedBits = Mask & InMask;
|
||||||
|
|
||||||
|
// If any of the sign extended bits are demanded, we know that the sign
|
||||||
|
// bit is demanded.
|
||||||
|
if (NewBits & Mask)
|
||||||
|
InDemandedBits |= InSignBit;
|
||||||
|
|
||||||
|
ComputeMaskedBits(Op.getOperand(0), InDemandedBits, KnownZero,
|
||||||
|
KnownOne, Depth+1);
|
||||||
|
// If the sign bit is known zero or one, the top bits match.
|
||||||
|
if (KnownZero & InSignBit) {
|
||||||
|
KnownZero |= NewBits;
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
} else if (KnownOne & InSignBit) {
|
||||||
|
KnownOne |= NewBits;
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
} else { // Otherwise, top bits aren't known.
|
||||||
|
KnownOne &= ~NewBits;
|
||||||
|
KnownZero &= ~NewBits;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::ANY_EXTEND: {
|
case ISD::ANY_EXTEND: {
|
||||||
unsigned SrcBits =
|
MVT::ValueType VT = Op.getOperand(0).getValueType();
|
||||||
MVT::getSizeInBits(Op.getOperand(0).getValueType());
|
ComputeMaskedBits(Op.getOperand(0), Mask & MVT::getIntVTBitMask(VT),
|
||||||
KnownZero &= ((1ULL << SrcBits)-1);
|
KnownZero, KnownOne, Depth+1);
|
||||||
KnownOne &= ((1ULL << SrcBits)-1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::AssertZext: {
|
case ISD::AssertZext: {
|
||||||
unsigned SrcBits =
|
MVT::ValueType VT = cast<VTSDNode>(Op.getOperand(1))->getVT();
|
||||||
MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
|
uint64_t InMask = MVT::getIntVTBitMask(VT);
|
||||||
KnownZero |= ~((1ULL << SrcBits)-1);
|
ComputeMaskedBits(Op.getOperand(0), Mask & InMask, KnownZero,
|
||||||
|
KnownOne, Depth+1);
|
||||||
|
KnownZero |= (~InMask) & Mask;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ISD::ADD: {
|
case ISD::ADD: {
|
||||||
@ -683,7 +848,8 @@ void TargetLowering::ComputeMaskedBits(SDOperand Op, uint64_t Mask,
|
|||||||
case ISD::SUB:
|
case ISD::SUB:
|
||||||
// We know that the top bits of C-X are clear if X contains less bits
|
// We know that the top bits of C-X are clear if X contains less bits
|
||||||
// than C (i.e. no wrap-around can happen). For example, 20-X is
|
// than C (i.e. no wrap-around can happen). For example, 20-X is
|
||||||
// positive if we can prove that X is >= 0 and < 16.
|
// positive if we can prove that X is >= 0 and < 16. Remember to update
|
||||||
|
// SimplifyDemandedBits if/when this is implemented.
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
// Allow the target to implement this method for its nodes.
|
// Allow the target to implement this method for its nodes.
|
||||||
|
Reference in New Issue
Block a user