Index: include/llvm/CodeGen/FunctionLoweringInfo.h =================================================================== --- include/llvm/CodeGen/FunctionLoweringInfo.h +++ include/llvm/CodeGen/FunctionLoweringInfo.h @@ -249,7 +249,7 @@ void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits, const KnownBits &Known) { // Only install this information if it tells us something. - if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0) + if (NumSignBits == 1 && Known.isUnknown()) return; LiveOutRegInfo.grow(Reg); Index: include/llvm/Support/KnownBits.h =================================================================== --- include/llvm/Support/KnownBits.h +++ include/llvm/Support/KnownBits.h @@ -59,6 +59,51 @@ return One; } + /// Returns true if we don't know any bits. + bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); } + + /// Resets the known state of all bits. + void resetAll() { + Zero.clearAllBits(); + One.clearAllBits(); + } + + /// Returns true if value is all zero. + bool isZero() const { + assert(!hasConflict() && "KnownBits conflict!"); + return Zero.isAllOnesValue(); + } + + /// Returns true if value is all one bits. + bool isAllOnes() const { + assert(!hasConflict() && "KnownBits conflict!"); + return One.isAllOnesValue(); + } + + /// Make all bits known to be zero. Asserts if this creates a conflict. + void setAllZero() { + assert(One.isNullValue() && "Bits already known to be one!"); + Zero.setAllBits(); + } + + /// Make all bits known to be one. Asserts if this creats a conflict. + void setAllOnes() { + assert(Zero.isNullValue() && "Bits already known to be one!"); + One.setAllBits(); + } + + /// Make all bits known to be zero and discard any previous information. + void forceAllZero() { + Zero.setAllBits(); + One.clearAllBits(); + } + + /// Make all bits known to be one and discard any previous information. + void forceAllOnes() { + Zero.clearAllBits(); + One.setAllBits(); + } + /// Returns true if this value is known to be negative. bool isNegative() const { return One.isSignBitSet(); } Index: lib/Analysis/Lint.cpp =================================================================== --- lib/Analysis/Lint.cpp +++ lib/Analysis/Lint.cpp @@ -537,7 +537,7 @@ unsigned BitWidth = V->getType()->getIntegerBitWidth(); KnownBits Known(BitWidth); computeKnownBits(V, Known, DL, 0, AC, dyn_cast(V), DT); - return Known.Zero.isAllOnesValue(); + return Known.isZero(); } // Per-component check doesn't work with zeroinitializer @@ -558,7 +558,7 @@ KnownBits Known(BitWidth); computeKnownBits(Elem, Known, DL); - if (Known.Zero.isAllOnesValue()) + if (Known.isZero()) return true; } Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -342,7 +342,6 @@ // Also compute a conservative estimate for high known-0 bits. // More trickiness is possible, but this is sufficient for the // interesting case of alignment computation. - Known.One.clearAllBits(); unsigned TrailZ = Known.Zero.countTrailingOnes() + Known2.Zero.countTrailingOnes(); unsigned LeadZ = std::max(Known.Zero.countLeadingOnes() + @@ -351,7 +350,7 @@ TrailZ = std::min(TrailZ, BitWidth); LeadZ = std::min(LeadZ, BitWidth); - Known.Zero.clearAllBits(); + Known.resetAll(); Known.Zero.setLowBits(TrailZ); Known.Zero.setHighBits(LeadZ); @@ -529,15 +528,13 @@ if (Arg == V && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { assert(BitWidth == 1 && "assume operand is not i1?"); - Known.Zero.clearAllBits(); - Known.One.setAllBits(); + Known.forceAllOnes(); return; } if (match(Arg, m_Not(m_Specific(V))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { assert(BitWidth == 1 && "assume operand is not i1?"); - Known.Zero.setAllBits(); - Known.One.clearAllBits(); + Known.forceAllZero(); return; } @@ -719,7 +716,7 @@ KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - if (RHSKnown.One.isAllOnesValue() || RHSKnown.isNonNegative()) { + if (RHSKnown.isAllOnes() || RHSKnown.isNonNegative()) { // We know that the sign bit is zero. Known.makeNonNegative(); } @@ -741,7 +738,7 @@ KnownBits RHSKnown(BitWidth); computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - if (RHSKnown.Zero.isAllOnesValue() || RHSKnown.isNegative()) { + if (RHSKnown.isZero() || RHSKnown.isNegative()) { // We know that the sign bit is one. Known.makeNegative(); } @@ -776,8 +773,7 @@ // behavior, or we might have a bug in the compiler. We can't assert/crash, so // clear out the known bits, try to warn the user, and hope for the best. if (Known.Zero.intersects(Known.One)) { - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); + Known.resetAll(); if (Q.ORE) { auto *CxtI = const_cast(Q.CxtI); @@ -813,10 +809,8 @@ // If there is conflict between Known.Zero and Known.One, this must be an // overflowing left shift, so the shift result is undefined. Clear Known // bits so that other code could propagate this undef. - if ((Known.Zero & Known.One) != 0) { - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); - } + if ((Known.Zero & Known.One) != 0) + Known.resetAll(); return; } @@ -826,8 +820,7 @@ // If the shift amount could be greater than or equal to the bit-width of the LHS, the // value could be undef, so we don't know anything about it. if ((~Known.Zero).uge(BitWidth)) { - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); + Known.resetAll(); return; } @@ -839,8 +832,7 @@ // It would be more-clearly correct to use the two temporaries for this // calculation. Reusing the APInts here to prevent unnecessary allocations. - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); + Known.resetAll(); // If we know the shifter operand is nonzero, we can sometimes infer more // known bits. However this is expensive to compute, so be lazy about it and @@ -886,10 +878,8 @@ // return anything we'd like, but we need to make sure the sets of known bits // stay disjoint (it should be better for some other code to actually // propagate the undef than to pick a value here using known bits). - if (Known.Zero.intersects(Known.One)) { - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); - } + if (Known.Zero.intersects(Known.One)) + Known.resetAll(); } static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known, @@ -924,7 +914,7 @@ m_Value(Y))) || match(I->getOperand(1), m_Add(m_Specific(I->getOperand(0)), m_Value(Y))))) { - Known2.Zero.clearAllBits(); Known2.One.clearAllBits(); + Known2.resetAll(); computeKnownBits(Y, Known2, Depth + 1, Q); if (Known2.One.countTrailingOnes() > 0) Known.Zero.setBit(0); @@ -965,8 +955,7 @@ computeKnownBits(I->getOperand(0), Known2, Depth + 1, Q); unsigned LeadZ = Known2.Zero.countLeadingOnes(); - Known2.One.clearAllBits(); - Known2.Zero.clearAllBits(); + Known2.resetAll(); computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q); unsigned RHSUnknownLeadingOnes = Known2.One.countLeadingZeros(); if (RHSUnknownLeadingOnes != BitWidth) @@ -1198,8 +1187,7 @@ unsigned Leaders = std::max(Known.Zero.countLeadingOnes(), Known2.Zero.countLeadingOnes()); - Known.One.clearAllBits(); - Known.Zero.clearAllBits(); + Known.resetAll(); Known.Zero.setHighBits(Leaders); break; } @@ -1500,8 +1488,7 @@ } // Null and aggregate-zero are all-zeros. if (isa(V) || isa(V)) { - Known.One.clearAllBits(); - Known.Zero.setAllBits(); + Known.forceAllZero(); return; } // Handle a constant vector by taking the intersection of the known bits of @@ -1528,8 +1515,7 @@ Constant *Element = CV->getAggregateElement(i); auto *ElementCI = dyn_cast_or_null(Element); if (!ElementCI) { - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); + Known.resetAll(); return; } Elt = ElementCI->getValue(); @@ -1540,7 +1526,7 @@ } // Start out not knowing anything. - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); // We can't imply anything about undefs. if (isa(V)) Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2044,8 +2044,7 @@ if (M < 0) { // For UNDEF elements, we don't know anything about the common state of // the shuffle result. - Known.One.clearAllBits(); - Known.Zero.clearAllBits(); + Known.resetAll(); DemandedLHS.clearAllBits(); DemandedRHS.clearAllBits(); break; @@ -2218,14 +2217,13 @@ // Also compute a conservative estimate for high known-0 bits. // More trickiness is possible, but this is sufficient for the // interesting case of alignment computation. - Known.One.clearAllBits(); unsigned TrailZ = Known.Zero.countTrailingOnes() + Known2.Zero.countTrailingOnes(); unsigned LeadZ = std::max(Known.Zero.countLeadingOnes() + Known2.Zero.countLeadingOnes(), BitWidth) - BitWidth; - Known.Zero.clearAllBits(); + Known.resetAll(); Known.Zero.setLowBits(std::min(TrailZ, BitWidth)); Known.Zero.setHighBits(std::min(LeadZ, BitWidth)); break; @@ -2598,8 +2596,7 @@ uint32_t Leaders = std::max(Known.Zero.countLeadingOnes(), Known2.Zero.countLeadingOnes()); - Known.One.clearAllBits(); - Known.Zero.clearAllBits(); + Known.resetAll(); Known.Zero.setHighBits(Leaders); break; } Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1303,7 +1303,7 @@ Op.getOpcode() == ISD::INTRINSIC_VOID) && "Should use MaskedValueIsZero if you don't know whether Op" " is a target node!"); - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); } /// This method can be implemented by targets that want to expose additional Index: lib/Target/AMDGPU/AMDGPUISelLowering.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -3580,7 +3580,7 @@ const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const { - Known.Zero.clearAllBits(); Known.One.clearAllBits(); // Don't know anything. + Known.resetAll(); // Don't know anything. KnownBits Known2; unsigned Opc = Op.getOpcode(); Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -12640,7 +12640,7 @@ const SelectionDAG &DAG, unsigned Depth) const { unsigned BitWidth = Known.getBitWidth(); - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); switch (Op.getOpcode()) { default: break; case ARMISD::ADDC: @@ -12655,7 +12655,8 @@ case ARMISD::CMOV: { // Bits are known zero/one if known on the LHS and RHS. DAG.computeKnownBits(Op.getOperand(0), Known, Depth+1); - if (Known.Zero == 0 && Known.One == 0) return; + if (Known.isUnknown()) + return; KnownBits KnownRHS; DAG.computeKnownBits(Op.getOperand(1), KnownRHS, Depth+1); Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -12031,7 +12031,7 @@ const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const { - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); switch (Op.getOpcode()) { default: break; case PPCISD::LBRX: { Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -1881,7 +1881,7 @@ const SelectionDAG &DAG, unsigned Depth) const { KnownBits Known2; - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); switch (Op.getOpcode()) { default: break; Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -26667,7 +26667,7 @@ "Should use MaskedValueIsZero if you don't know whether Op" " is a target node!"); - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); switch (Opc) { default: break; case X86ISD::ADD: @@ -26697,7 +26697,7 @@ case X86ISD::VSRLI: { if (auto *ShiftImm = dyn_cast(Op.getOperand(1))) { if (ShiftImm->getAPIntValue().uge(VT.getScalarSizeInBits())) { - Known.Zero.setAllBits(); + Known.setAllZero(); break; } Index: lib/Target/XCore/XCoreISelLowering.cpp =================================================================== --- lib/Target/XCore/XCoreISelLowering.cpp +++ lib/Target/XCore/XCoreISelLowering.cpp @@ -1825,7 +1825,7 @@ const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const { - Known.Zero.clearAllBits(); Known.One.clearAllBits(); + Known.resetAll(); switch (Op.getOpcode()) { default: break; case XCoreISD::LADD: Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3619,7 +3619,7 @@ // then this one is redundant, and should be removed. KnownBits Known(1); computeKnownBits(IIOperand, Known, 0, II); - if (Known.One.isAllOnesValue()) + if (Known.isAllOnes()) return eraseInstFromFunction(*II); // Update the cache of affected values for this assumption (we might be Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4050,7 +4050,7 @@ // is set. If the comparison is against zero, then this is a check to see if // *that* bit is set. APInt Op0KnownZeroInverted = ~Op0Known.Zero; - if (~Op1Known.Zero == 0) { + if (Op1Known.isZero()) { // If the LHS is an AND with the same constant, look through it. Value *LHS = nullptr; const APInt *LHSC; Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -120,8 +120,7 @@ return nullptr; } - Known.Zero.clearAllBits(); - Known.One.clearAllBits(); + Known.resetAll(); if (DemandedMask == 0) // Not demanding any bits from V. return UndefValue::get(VTy);