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:
Chris Lattner
2006-02-26 23:36:02 +00:00
parent 02bd1b3e94
commit ec665151b8

View File

@ -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.