diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -417,7 +417,7 @@ bool isIntN(unsigned N) const { return getActiveBits() <= N; } /// Check if this APInt has an N-bits signed integer value. - bool isSignedIntN(unsigned N) const { return getMinSignedBits() <= N; } + bool isSignedIntN(unsigned N) const { return getSignificantBits() <= N; } /// Check if this APInt's value is a power of two greater than zero. /// @@ -1069,8 +1069,9 @@ /// /// \returns true if *this < RHS when considered signed. bool slt(int64_t RHS) const { - return (!isSingleWord() && getMinSignedBits() > 64) ? isNegative() - : getSExtValue() < RHS; + return (!isSingleWord() && getSignificantBits() > 64) + ? isNegative() + : getSExtValue() < RHS; } /// Unsigned less or equal comparison @@ -1139,8 +1140,9 @@ /// /// \returns true if *this > RHS when considered signed. bool sgt(int64_t RHS) const { - return (!isSingleWord() && getMinSignedBits() > 64) ? !isNegative() - : getSExtValue() > RHS; + return (!isSingleWord() && getSignificantBits() > 64) + ? !isNegative() + : getSExtValue() > RHS; } /// Unsigned greater or equal comparison @@ -1450,7 +1452,12 @@ /// returns the smallest bit width that will retain the negative value. For /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so /// for -1, this function will always return 1. - unsigned getMinSignedBits() const { return BitWidth - getNumSignBits() + 1; } + unsigned getSignificantBits() const { + return BitWidth - getNumSignBits() + 1; + } + + /// NOTE: This is soft-deprecated. Please use `getSignificantBits()` instead. + unsigned getMinSignedBits() const { return getSignificantBits(); } /// Get zero extended value /// @@ -1472,7 +1479,7 @@ int64_t getSExtValue() const { if (isSingleWord()) return SignExtend64(U.VAL, BitWidth); - assert(getMinSignedBits() <= 64 && "Too many bits for int64_t"); + assert(getSignificantBits() <= 64 && "Too many bits for int64_t"); return int64_t(U.pVal[0]); } diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -202,14 +202,14 @@ const DominatorTree *DT = nullptr, bool UseInstrInfo = true); - /// Get the minimum bit size for this Value \p Op as a signed integer. - /// i.e. x == sext(trunc(x to MinSignedBits) to bitwidth(x)). - /// Similar to the APInt::getMinSignedBits function. - unsigned ComputeMinSignedBits(const Value *Op, const DataLayout &DL, - unsigned Depth = 0, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr, - const DominatorTree *DT = nullptr); + /// Get the upper bound on bit size for this Value \p Op as a signed integer. + /// i.e. x == sext(trunc(x to MaxSignificantBits) to bitwidth(x)). + /// Similar to the APInt::getSignificantBits function. + unsigned ComputeMaxSignificantBits(const Value *Op, const DataLayout &DL, + unsigned Depth = 0, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); /// This function computes the integer multiple of Base that equals V. If /// successful, it returns true and returns the multiple in Multiple. If diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1833,18 +1833,18 @@ unsigned ComputeNumSignBits(SDValue Op, const APInt &DemandedElts, unsigned Depth = 0) const; - /// Get the minimum bit size for this Value \p Op as a signed integer. - /// i.e. x == sext(trunc(x to MinSignedBits) to bitwidth(x)). - /// Similar to the APInt::getMinSignedBits function. + /// Get the upper bound on bit size for this Value \p Op as a signed integer. + /// i.e. x == sext(trunc(x to MaxSignedBits) to bitwidth(x)). + /// Similar to the APInt::getSignificantBits function. /// Helper wrapper to ComputeNumSignBits. - unsigned ComputeMinSignedBits(SDValue Op, unsigned Depth = 0) const; + unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth = 0) const; - /// Get the minimum bit size for this Value \p Op as a signed integer. - /// i.e. x == sext(trunc(x to MinSignedBits) to bitwidth(x)). - /// Similar to the APInt::getMinSignedBits function. + /// Get the upper bound on bit size for this Value \p Op as a signed integer. + /// i.e. x == sext(trunc(x to MaxSignedBits) to bitwidth(x)). + /// Similar to the APInt::getSignificantBits function. /// Helper wrapper to ComputeNumSignBits. - unsigned ComputeMinSignedBits(SDValue Op, const APInt &DemandedElts, - unsigned Depth = 0) const; + unsigned ComputeMaxSignificantBits(SDValue Op, const APInt &DemandedElts, + unsigned Depth = 0) const; /// Return true if this function can prove that \p Op is never poison /// and, if \p PoisonOnly is false, does not have undef bits. diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -254,8 +254,11 @@ } /// Returns the maximum number of bits needed to represent all possible - /// signed values with these known bits. - unsigned countMaxSignedBits() const { + /// signed values with these known bits. This is the inverse of the minimum + /// number of known sign bits. Examples for bitwidth 5: + /// 110?? --> 4 + /// 0000? --> 2 + unsigned countMaxSignificantBits() const { return getBitWidth() - countMinSignBits() + 1; } @@ -289,6 +292,9 @@ return getBitWidth() - Zero.countPopulation(); } + /// Returns the maximum number of bits needed to represent all possible + /// unsigned values with these known bits. This is the inverse of the + /// minimum number of leading zeros. unsigned countMaxActiveBits() const { return getBitWidth() - countMinLeadingZeros(); } diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h --- a/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h +++ b/llvm/include/llvm/Transforms/InstCombine/InstCombiner.h @@ -480,9 +480,9 @@ return llvm::ComputeNumSignBits(Op, DL, Depth, &AC, CxtI, &DT); } - unsigned ComputeMinSignedBits(const Value *Op, unsigned Depth = 0, - const Instruction *CxtI = nullptr) const { - return llvm::ComputeMinSignedBits(Op, DL, Depth, &AC, CxtI, &DT); + unsigned ComputeMaxSignificantBits(const Value *Op, unsigned Depth = 0, + const Instruction *CxtI = nullptr) const { + return llvm::ComputeMaxSignificantBits(Op, DL, Depth, &AC, CxtI, &DT); } OverflowResult computeOverflowForUnsignedMul(const Value *LHS, diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -396,10 +396,10 @@ V, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT, UseInstrInfo)); } -unsigned llvm::ComputeMinSignedBits(const Value *V, const DataLayout &DL, - unsigned Depth, AssumptionCache *AC, - const Instruction *CxtI, - const DominatorTree *DT) { +unsigned llvm::ComputeMaxSignificantBits(const Value *V, const DataLayout &DL, + unsigned Depth, AssumptionCache *AC, + const Instruction *CxtI, + const DominatorTree *DT) { unsigned SignBits = ComputeNumSignBits(V, DL, Depth, AC, CxtI, DT); return V->getType()->getScalarSizeInBits() - SignBits + 1; } diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12320,7 +12320,7 @@ return DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), VT, N0, N1); // If the input is already sign extended, just drop the extension. - if (ExtVTBits >= DAG.ComputeMinSignedBits(N0)) + if (ExtVTBits >= DAG.ComputeMaxSignificantBits(N0)) return N0; // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 @@ -12336,7 +12336,8 @@ if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) { SDValue N00 = N0.getOperand(0); unsigned N00Bits = N00.getScalarValueSizeInBits(); - if ((N00Bits <= ExtVTBits || DAG.ComputeMinSignedBits(N00) <= ExtVTBits) && + if ((N00Bits <= ExtVTBits || + DAG.ComputeMaxSignificantBits(N00) <= ExtVTBits) && (!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND, VT))) return DAG.getNode(ISD::SIGN_EXTEND, SDLoc(N), VT, N00); } @@ -12355,7 +12356,7 @@ APInt DemandedSrcElts = APInt::getLowBitsSet(SrcElts, DstElts); if ((N00Bits == ExtVTBits || (!IsZext && (N00Bits < ExtVTBits || - DAG.ComputeMinSignedBits(N00) <= ExtVTBits))) && + DAG.ComputeMaxSignificantBits(N00) <= ExtVTBits))) && (!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_VECTOR_INREG, VT))) return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, SDLoc(N), VT, N00); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1751,8 +1751,8 @@ // duplicated sign bits is no greater than the width of LHS/RHS, we can avoid // inserting a zext_inreg operation that we might not be able to remove. if (ISD::isIntEqualitySetCC(CCCode)) { - unsigned OpLEffectiveBits = DAG.ComputeMinSignedBits(OpL); - unsigned OpREffectiveBits = DAG.ComputeMinSignedBits(OpR); + unsigned OpLEffectiveBits = DAG.ComputeMaxSignificantBits(OpL); + unsigned OpREffectiveBits = DAG.ComputeMaxSignificantBits(OpR); if (OpLEffectiveBits <= LHS.getScalarValueSizeInBits() && OpREffectiveBits <= RHS.getScalarValueSizeInBits()) { LHS = OpL; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4297,14 +4297,15 @@ return std::max(FirstAnswer, Known.countMinSignBits()); } -unsigned SelectionDAG::ComputeMinSignedBits(SDValue Op, unsigned Depth) const { +unsigned SelectionDAG::ComputeMaxSignificantBits(SDValue Op, + unsigned Depth) const { unsigned SignBits = ComputeNumSignBits(Op, Depth); return Op.getScalarValueSizeInBits() - SignBits + 1; } -unsigned SelectionDAG::ComputeMinSignedBits(SDValue Op, - const APInt &DemandedElts, - unsigned Depth) const { +unsigned SelectionDAG::ComputeMaxSignificantBits(SDValue Op, + const APInt &DemandedElts, + unsigned Depth) const { unsigned SignBits = ComputeNumSignBits(Op, DemandedElts, Depth); return Op.getScalarValueSizeInBits() - SignBits + 1; } diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1833,7 +1833,7 @@ // If we only care about the highest bit, don't bother shifting right. if (DemandedBits.isSignMask()) { unsigned MinSignedBits = - TLO.DAG.ComputeMinSignedBits(Op0, DemandedElts, Depth + 1); + TLO.DAG.ComputeMaxSignificantBits(Op0, DemandedElts, Depth + 1); bool AlreadySignExtended = ExVTBits >= MinSignedBits; // However if the input is already sign extended we expect the sign // extension to be dropped altogether later and do not simplify. diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp @@ -450,7 +450,7 @@ } unsigned AMDGPUCodeGenPrepare::numBitsSigned(Value *Op) const { - return ComputeMinSignedBits(Op, *DL, 0, AC); + return ComputeMaxSignificantBits(Op, *DL, 0, AC); } static void extractValues(IRBuilder<> &Builder, diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -51,7 +51,7 @@ unsigned AMDGPUTargetLowering::numBitsSigned(SDValue Op, SelectionDAG &DAG) { // In order for this to be a signed 24-bit value, bit 23, must // be a sign bit. - return DAG.ComputeMinSignedBits(Op); + return DAG.ComputeMaxSignificantBits(Op); } AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM, diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -6850,8 +6850,8 @@ DAG.computeKnownBits(RHS).countMaxActiveBits() <= EltSizeInBits) return DAG.getNode(X86ISD::PACKUS, dl, VT, LHS, RHS); - if (DAG.ComputeMinSignedBits(LHS) <= EltSizeInBits && - DAG.ComputeMinSignedBits(RHS) <= EltSizeInBits) + if (DAG.ComputeMaxSignificantBits(LHS) <= EltSizeInBits && + DAG.ComputeMaxSignificantBits(RHS) <= EltSizeInBits) return DAG.getNode(X86ISD::PACKSS, dl, VT, LHS, RHS); } @@ -23157,10 +23157,10 @@ // For equality comparisons try to use SIGN_EXTEND if the input was // truncate from something with enough sign bits. if (Op0.getOpcode() == ISD::TRUNCATE) { - if (DAG.ComputeMinSignedBits(Op0.getOperand(0)) <= 16) + if (DAG.ComputeMaxSignificantBits(Op0.getOperand(0)) <= 16) ExtendOp = ISD::SIGN_EXTEND; } else if (Op1.getOpcode() == ISD::TRUNCATE) { - if (DAG.ComputeMinSignedBits(Op1.getOperand(0)) <= 16) + if (DAG.ComputeMaxSignificantBits(Op1.getOperand(0)) <= 16) ExtendOp = ISD::SIGN_EXTEND; } } @@ -44732,7 +44732,8 @@ return SDValue(); // Sign bits must extend down to the lowest i16. - if (DAG.ComputeMinSignedBits(N1) > 16 || DAG.ComputeMinSignedBits(N0) > 16) + if (DAG.ComputeMaxSignificantBits(N1) > 16 || + DAG.ComputeMaxSignificantBits(N0) > 16) return SDValue(); // At least one of the elements must be zero in the upper 17 bits, or can be @@ -48714,7 +48715,7 @@ // sequence or using AVX512 truncations. If the inputs are sext/zext then the // truncations may actually be free by peeking through to the ext source. auto IsSext = [&DAG](SDValue V) { - return DAG.ComputeMinSignedBits(V) <= 16; + return DAG.ComputeMaxSignificantBits(V) <= 16; }; auto IsZext = [&DAG](SDValue V) { return DAG.computeKnownBits(V).countMaxActiveBits() <= 16; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1263,8 +1263,8 @@ // This is only really a signed overflow check if the inputs have been // sign-extended; check for that condition. For example, if CI2 is 2^31 and // the operands of the add are 64 bits wide, we need at least 33 sign bits. - if (IC.ComputeMinSignedBits(A, 0, &I) > NewWidth || - IC.ComputeMinSignedBits(B, 0, &I) > NewWidth) + if (IC.ComputeMaxSignificantBits(A, 0, &I) > NewWidth || + IC.ComputeMaxSignificantBits(B, 0, &I) > NewWidth) return nullptr; // In order to replace the original add with a narrower diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2325,8 +2325,9 @@ // The two operands of the add/sub must be nsw-truncatable to the NewTy. This // is usually achieved via a sext from a smaller type. - if (ComputeMinSignedBits(AddSub->getOperand(0), 0, AddSub) > NewBitWidth || - ComputeMinSignedBits(AddSub->getOperand(1), 0, AddSub) > NewBitWidth) + if (ComputeMaxSignificantBits(AddSub->getOperand(0), 0, AddSub) > + NewBitWidth || + ComputeMaxSignificantBits(AddSub->getOperand(1), 0, AddSub) > NewBitWidth) return nullptr; // Finally create and return the sat intrinsic, truncated to the new type diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4940,7 +4940,8 @@ // We can also eliminate cases by determining that their values are outside of // the limited range of the condition based on how many significant (non-sign) // bits are in the condition value. - unsigned MaxSignificantBitsInCond = ComputeMinSignedBits(Cond, DL, 0, AC, SI); + unsigned MaxSignificantBitsInCond = + ComputeMaxSignificantBits(Cond, DL, 0, AC, SI); // Gather dead cases. SmallVector DeadCases; diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -442,14 +442,14 @@ }); } -TEST(KnownBitsTest, CountMaxSignedBits) { +TEST(KnownBitsTest, CountMaxSignificantBits) { unsigned Bits = 4; ForeachKnownBits(Bits, [&](const KnownBits &Known) { unsigned Expected = 0; ForeachNumInKnownBits(Known, [&](const APInt &N) { - Expected = std::max(Expected, N.getMinSignedBits()); + Expected = std::max(Expected, N.getSignificantBits()); }); - EXPECT_EQ(Expected, Known.countMaxSignedBits()); + EXPECT_EQ(Expected, Known.countMaxSignificantBits()); }); }