From 977a76fbb6ea1b87dfd7fbbe2ae2afb63e982ff3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 13 Feb 2008 22:28:48 +0000 Subject: [PATCH] Simplify some logic in ComputeMaskedBits. And change ComputeMaskedBits to pass the mask APInt by value, not by reference. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47096 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 2 +- include/llvm/Target/TargetLowering.h | 2 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 91 +++++++++++---------- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 5 +- lib/Target/ARM/ARMISelLowering.cpp | 2 +- lib/Target/ARM/ARMISelLowering.h | 2 +- lib/Target/CellSPU/SPUISelLowering.cpp | 2 +- lib/Target/CellSPU/SPUISelLowering.h | 2 +- lib/Target/PowerPC/PPCISelLowering.cpp | 2 +- lib/Target/PowerPC/PPCISelLowering.h | 2 +- lib/Target/Sparc/SparcISelDAGToDAG.cpp | 4 +- lib/Target/X86/X86ISelLowering.cpp | 2 +- lib/Target/X86/X86ISelLowering.h | 2 +- 13 files changed, 64 insertions(+), 56 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 560e0fca132..22487dd5c37 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -556,7 +556,7 @@ public: /// bitsets. This code only analyzes bits in Mask, in order to short-circuit /// processing. Targets can implement the computeMaskedBitsForTargetNode /// method in the TargetLowering class to allow target nodes to be understood. - void ComputeMaskedBits(SDOperand Op, APInt Mask, APInt &KnownZero, + void ComputeMaskedBits(SDOperand Op, const APInt &Mask, APInt &KnownZero, APInt &KnownOne, unsigned Depth = 0) const; /// ComputeMaskedBits - This is a wrapper around the APInt-using diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index d81dacf41f7..ef8a4474097 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -627,7 +627,7 @@ public: /// Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index de5c4112c7e..3ec60cde9d7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1130,7 +1130,7 @@ bool SelectionDAG::MaskedValueIsZero(SDOperand Op, uint64_t Mask, /// known to be either zero or one and return them in the KnownZero/KnownOne /// bitsets. This code only analyzes bits in Mask, in order to short-circuit /// processing. -void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, +void SelectionDAG::ComputeMaskedBits(SDOperand Op, const APInt &Mask, APInt &KnownZero, APInt &KnownOne, unsigned Depth) const { unsigned BitWidth = Mask.getBitWidth(); @@ -1153,8 +1153,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, case ISD::AND: // If either the LHS or the RHS are Zero, the result is zero. ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1); - Mask &= ~KnownZero; - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1); + ComputeMaskedBits(Op.getOperand(0), Mask & ~KnownZero, + KnownZero2, KnownOne2, Depth+1); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); @@ -1165,8 +1165,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, return; case ISD::OR: ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1); - Mask &= ~KnownOne; - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1); + ComputeMaskedBits(Op.getOperand(0), Mask & ~KnownOne, + KnownZero2, KnownOne2, Depth+1); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); @@ -1271,21 +1271,19 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, return; case ISD::SIGN_EXTEND_INREG: { MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); + unsigned EBits = MVT::getSizeInBits(EVT); // Sign extension. Compute the demanded bits in the result that are not // present in the input. - APInt NewBits = ~APInt::getLowBitsSet(BitWidth, - MVT::getSizeInBits(EVT)) & Mask; + APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - EBits) & Mask; - APInt InSignBit = APInt::getSignBit(MVT::getSizeInBits(EVT)); - APInt InputDemandedBits = - Mask & APInt::getLowBitsSet(BitWidth, - MVT::getSizeInBits(EVT)); + APInt InSignBit = APInt::getSignBit(EBits); + APInt InputDemandedBits = Mask & APInt::getLowBitsSet(BitWidth, EBits); // If the sign extended bits are demanded, we know that the sign // bit is demanded. InSignBit.zext(BitWidth); - if (!!NewBits) + if (NewBits.getBoolValue()) InputDemandedBits |= InSignBit; ComputeMaskedBits(Op.getOperand(0), InputDemandedBits, @@ -1318,19 +1316,20 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, if (ISD::isZEXTLoad(Op.Val)) { LoadSDNode *LD = cast(Op); MVT::ValueType VT = LD->getMemoryVT(); - KnownZero |= ~APInt::getLowBitsSet(BitWidth, MVT::getSizeInBits(VT)) & Mask; + unsigned MemBits = MVT::getSizeInBits(VT); + KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits) & Mask; } return; } case ISD::ZERO_EXTEND: { MVT::ValueType InVT = Op.getOperand(0).getValueType(); unsigned InBits = MVT::getSizeInBits(InVT); - APInt InMask = APInt::getLowBitsSet(BitWidth, InBits); - APInt NewBits = (~InMask) & Mask; - Mask.trunc(InBits); + APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask; + APInt InMask = Mask; + InMask.trunc(InBits); KnownZero.trunc(InBits); KnownOne.trunc(InBits); - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1); KnownZero.zext(BitWidth); KnownOne.zext(BitWidth); KnownZero |= NewBits; @@ -1339,43 +1338,52 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, case ISD::SIGN_EXTEND: { MVT::ValueType InVT = Op.getOperand(0).getValueType(); unsigned InBits = MVT::getSizeInBits(InVT); - APInt InMask = APInt::getLowBitsSet(BitWidth, InBits); APInt InSignBit = APInt::getSignBit(InBits); - APInt NewBits = (~InMask) & Mask; + APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - InBits) & Mask; + APInt InMask = Mask; + InMask.trunc(InBits); // If any of the sign extended bits are demanded, we know that the sign - // bit is demanded. - InSignBit.zext(BitWidth); - if (!!(NewBits & Mask)) - Mask |= InSignBit; + // bit is demanded. Temporarily set this bit in the mask for our callee. + if (NewBits.getBoolValue()) + InMask |= InSignBit; - Mask.trunc(InBits); KnownZero.trunc(InBits); KnownOne.trunc(InBits); - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1); + + // Note if the sign bit is known to be zero or one. + bool SignBitKnownZero = KnownZero.isNegative(); + bool SignBitKnownOne = KnownOne.isNegative(); + assert(!(SignBitKnownZero && SignBitKnownOne) && + "Sign bit can't be known to be both zero and one!"); + + // If the sign bit wasn't actually demanded by our caller, we don't + // want it set in the KnownZero and KnownOne result values. Reset the + // mask and reapply it to the result values. + InMask = Mask; + InMask.trunc(InBits); + KnownZero &= InMask; + KnownOne &= InMask; + KnownZero.zext(BitWidth); KnownOne.zext(BitWidth); - // If the sign bit is known zero or one, the top bits match. - if (!!(KnownZero & InSignBit)) { + // If the sign bit is known zero or one, the top bits match. + if (SignBitKnownZero) KnownZero |= NewBits; - KnownOne &= ~NewBits; - } else if (!!(KnownOne & InSignBit)) { + else if (SignBitKnownOne) KnownOne |= NewBits; - KnownZero &= ~NewBits; - } else { // Otherwise, top bits aren't known. - KnownOne &= ~NewBits; - KnownZero &= ~NewBits; - } return; } case ISD::ANY_EXTEND: { MVT::ValueType InVT = Op.getOperand(0).getValueType(); unsigned InBits = MVT::getSizeInBits(InVT); - Mask.trunc(InBits); + APInt InMask = Mask; + InMask.trunc(InBits); KnownZero.trunc(InBits); KnownOne.trunc(InBits); - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1); KnownZero.zext(BitWidth); KnownOne.zext(BitWidth); return; @@ -1383,10 +1391,11 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, case ISD::TRUNCATE: { MVT::ValueType InVT = Op.getOperand(0).getValueType(); unsigned InBits = MVT::getSizeInBits(InVT); - Mask.zext(InBits); + APInt InMask = Mask; + InMask.zext(InBits); KnownZero.zext(InBits); KnownOne.zext(InBits); - ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1); + ComputeMaskedBits(Op.getOperand(0), InMask, KnownZero, KnownOne, Depth+1); assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); KnownZero.trunc(BitWidth); KnownOne.trunc(BitWidth); @@ -1415,8 +1424,8 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, // Output known-0 bits are known if clear or set in both the low clear bits // common to both LHS & RHS. For example, 8+(X<<3) is known to have the // low 3 bits clear. - unsigned KnownZeroOut = std::min((~KnownZero).countTrailingZeros(), - (~KnownZero2).countTrailingZeros()); + unsigned KnownZeroOut = std::min(KnownZero.countTrailingOnes(), + KnownZero2.countTrailingOnes()); KnownZero = APInt::getLowBitsSet(BitWidth, KnownZeroOut); KnownOne = APInt(BitWidth, 0); @@ -1431,7 +1440,7 @@ void SelectionDAG::ComputeMaskedBits(SDOperand Op, APInt Mask, // positive if we can prove that X is >= 0 and < 16. // sign bit clear - if (!(CLHS->getAPIntValue() & APInt::getSignBit(BitWidth))) { + if (CLHS->getAPIntValue().isNonNegative()) { unsigned NLZ = (CLHS->getAPIntValue()+1).countLeadingZeros(); // NLZ can't be BitWidth with no sign bit APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index c84b6972aa7..f74ea5c29b2 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1008,7 +1008,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask, /// in Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, @@ -1019,8 +1019,7 @@ void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, Op.getOpcode() == ISD::INTRINSIC_VOID) && "Should use MaskedValueIsZero if you don't know whether Op" " is a target node!"); - KnownZero = 0; - KnownOne = 0; + KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); } /// ComputeNumSignBitsForTargetNode - This method can be implemented by diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index a6c669dc88a..a4ab3938121 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1762,7 +1762,7 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, } void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 80ee51a1649..285a20d23f8 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -106,7 +106,7 @@ namespace llvm { SelectionDAG &DAG); virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 6fe6e48bc84..f6e33599c69 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -2668,7 +2668,7 @@ SPUTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, void SPUTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/CellSPU/SPUISelLowering.h b/lib/Target/CellSPU/SPUISelLowering.h index 3abb9d17fac..29242df71b3 100644 --- a/lib/Target/CellSPU/SPUISelLowering.h +++ b/lib/Target/CellSPU/SPUISelLowering.h @@ -108,7 +108,7 @@ namespace llvm { virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 6c4468c359f..53be370f0a1 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3451,7 +3451,7 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N, //===----------------------------------------------------------------------===// void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 2b20e26c16a..3843998b508 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -254,7 +254,7 @@ namespace llvm { virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index 81e15397c7f..29fe6a41602 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -110,7 +110,7 @@ namespace { /// in Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, @@ -270,7 +270,7 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const { /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index c7e055dbbd7..556aaac9eae 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5640,7 +5640,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, //===----------------------------------------------------------------------===// void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG, diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index e4ca85068aa..b191dfac33f 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -379,7 +379,7 @@ namespace llvm { /// in Mask are known to be either zero or one and return them in the /// KnownZero/KnownOne bitsets. virtual void computeMaskedBitsForTargetNode(const SDOperand Op, - APInt Mask, + const APInt &Mask, APInt &KnownZero, APInt &KnownOne, const SelectionDAG &DAG,