diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2020-03-20 13:29:00 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2020-03-20 13:29:00 +0000 |
commit | 7f764fa18f640bf4748ef53c39d55e52132bf95d (patch) | |
tree | 65c303cabd8a74bd51ef7b6dcbbc287b4c620fd8 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | fcba7c3534f98851531095f8457eb3142e237f0b (diff) | |
download | llvm-7f764fa18f640bf4748ef53c39d55e52132bf95d.zip llvm-7f764fa18f640bf4748ef53c39d55e52132bf95d.tar.gz llvm-7f764fa18f640bf4748ef53c39d55e52132bf95d.tar.bz2 |
[ValueTracking] Add some initial isKnownNonZero DemandedElts support (PR36319)
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index ea6391d..b7af0d2 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -215,6 +215,9 @@ void llvm::computeKnownBits(const Value *V, KnownBits &Known, Query(DL, AC, safeCxtI(V, CxtI), DT, UseInstrInfo, ORE)); } +static KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts, + unsigned Depth, const Query &Q); + static KnownBits computeKnownBits(const Value *V, unsigned Depth, const Query &Q); @@ -275,6 +278,9 @@ bool llvm::isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, V, OrZero, Depth, Query(DL, AC, safeCxtI(V, CxtI), DT, UseInstrInfo)); } +static bool isKnownNonZero(const Value *V, const APInt &DemandedElts, + unsigned Depth, const Query &Q); + static bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q); bool llvm::isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth, @@ -1052,7 +1058,8 @@ static void computeKnownBitsFromShiftOperator( // Early exit if we can't constrain any well-defined shift amount. if (!(ShiftAmtKZ & (PowerOf2Ceil(BitWidth) - 1)) && !(ShiftAmtKO & (PowerOf2Ceil(BitWidth) - 1))) { - ShifterOperandIsNonZero = isKnownNonZero(I->getOperand(1), Depth + 1, Q); + ShifterOperandIsNonZero = + isKnownNonZero(I->getOperand(1), DemandedElts, Depth + 1, Q); if (!*ShifterOperandIsNonZero) return; } @@ -1074,7 +1081,7 @@ static void computeKnownBitsFromShiftOperator( if (ShiftAmt == 0) { if (!ShifterOperandIsNonZero.hasValue()) ShifterOperandIsNonZero = - isKnownNonZero(I->getOperand(1), Depth + 1, Q); + isKnownNonZero(I->getOperand(1), DemandedElts, Depth + 1, Q); if (*ShifterOperandIsNonZero) continue; } @@ -1813,6 +1820,15 @@ static void computeKnownBitsFromOperator(const Operator *I, /// Determine which bits of V are known to be either zero or one and return /// them. +KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts, + unsigned Depth, const Query &Q) { + KnownBits Known(getBitWidth(V->getType(), Q.DL)); + computeKnownBits(V, DemandedElts, Known, Depth, Q); + return Known; +} + +/// Determine which bits of V are known to be either zero or one and return +/// them. KnownBits computeKnownBits(const Value *V, unsigned Depth, const Query &Q) { KnownBits Known(getBitWidth(V->getType(), Q.DL)); computeKnownBits(V, Known, Depth, Q); @@ -2223,12 +2239,13 @@ static bool rangeMetadataExcludesValue(const MDNode* Ranges, const APInt& Value) } /// Return true if the given value is known to be non-zero when defined. For -/// vectors, return true if every element is known to be non-zero when +/// vectors, return true if every demanded element is known to be non-zero when /// defined. For pointers, if the context instruction and dominator tree are /// specified, perform context-sensitive analysis and return true if the /// pointer couldn't possibly be null at the specified instruction. /// Supports values with integer or pointer type and vectors of integers. -bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { +bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth, + const Query &Q) { if (auto *C = dyn_cast<Constant>(V)) { if (C->isNullValue()) return false; @@ -2249,6 +2266,8 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { // non-zero to determine that the whole vector is known non-zero. if (auto *VecTy = dyn_cast<VectorType>(C->getType())) { for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) { + if (!DemandedElts[i]) + continue; Constant *Elt = C->getAggregateElement(i); if (!Elt || Elt->isNullValue()) return false; @@ -2349,7 +2368,8 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { // X | Y != 0 if X != 0 or Y != 0. Value *X = nullptr, *Y = nullptr; if (match(V, m_Or(m_Value(X), m_Value(Y)))) - return isKnownNonZero(X, Depth, Q) || isKnownNonZero(Y, Depth, Q); + return isKnownNonZero(X, DemandedElts, Depth, Q) || + isKnownNonZero(Y, DemandedElts, Depth, Q); // ext X != 0 if X != 0. if (isa<SExtInst>(V) || isa<ZExtInst>(V)) @@ -2364,7 +2384,7 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { return isKnownNonZero(X, Depth, Q); KnownBits Known(BitWidth); - computeKnownBits(X, Known, Depth, Q); + computeKnownBits(X, DemandedElts, Known, Depth, Q); if (Known.One[0]) return true; } @@ -2376,7 +2396,7 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { if (BO->isExact()) return isKnownNonZero(X, Depth, Q); - KnownBits Known = computeKnownBits(X, Depth, Q); + KnownBits Known = computeKnownBits(X, DemandedElts, Depth, Q); if (Known.isNegative()) return true; @@ -2390,22 +2410,23 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { return true; // Are all the bits to be shifted out known zero? if (Known.countMinTrailingZeros() >= ShiftVal) - return isKnownNonZero(X, Depth, Q); + return isKnownNonZero(X, DemandedElts, Depth, Q); } } // div exact can only produce a zero if the dividend is zero. else if (match(V, m_Exact(m_IDiv(m_Value(X), m_Value())))) { - return isKnownNonZero(X, Depth, Q); + return isKnownNonZero(X, DemandedElts, Depth, Q); } // X + Y. else if (match(V, m_Add(m_Value(X), m_Value(Y)))) { - KnownBits XKnown = computeKnownBits(X, Depth, Q); - KnownBits YKnown = computeKnownBits(Y, Depth, Q); + KnownBits XKnown = computeKnownBits(X, DemandedElts, Depth, Q); + KnownBits YKnown = computeKnownBits(Y, DemandedElts, Depth, Q); // If X and Y are both non-negative (as signed values) then their sum is not // zero unless both X and Y are zero. if (XKnown.isNonNegative() && YKnown.isNonNegative()) - if (isKnownNonZero(X, Depth, Q) || isKnownNonZero(Y, Depth, Q)) + if (isKnownNonZero(X, DemandedElts, Depth, Q) || + isKnownNonZero(Y, DemandedElts, Depth, Q)) return true; // If X and Y are both negative (as signed values) then their sum is not @@ -2436,13 +2457,14 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { // If X and Y are non-zero then so is X * Y as long as the multiplication // does not overflow. if ((Q.IIQ.hasNoSignedWrap(BO) || Q.IIQ.hasNoUnsignedWrap(BO)) && - isKnownNonZero(X, Depth, Q) && isKnownNonZero(Y, Depth, Q)) + isKnownNonZero(X, DemandedElts, Depth, Q) && + isKnownNonZero(Y, DemandedElts, Depth, Q)) return true; } // (C ? X : Y) != 0 if X != 0 and Y != 0. else if (const SelectInst *SI = dyn_cast<SelectInst>(V)) { - if (isKnownNonZero(SI->getTrueValue(), Depth, Q) && - isKnownNonZero(SI->getFalseValue(), Depth, Q)) + if (isKnownNonZero(SI->getTrueValue(), DemandedElts, Depth, Q) && + isKnownNonZero(SI->getFalseValue(), DemandedElts, Depth, Q)) return true; } // PHI @@ -2472,12 +2494,31 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { if (AllNonZeroConstants) return true; } + // ExtractElement + else if (const auto *EEI = dyn_cast<ExtractElementInst>(V)) { + const Value *Vec = EEI->getVectorOperand(); + const Value *Idx = EEI->getIndexOperand(); + auto *CIdx = dyn_cast<ConstantInt>(Idx); + unsigned NumElts = Vec->getType()->getVectorNumElements(); + APInt DemandedVecElts = APInt::getAllOnesValue(NumElts); + if (CIdx && CIdx->getValue().ult(NumElts)) + DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue()); + return isKnownNonZero(Vec, DemandedVecElts, Depth, Q); + } KnownBits Known(BitWidth); - computeKnownBits(V, Known, Depth, Q); + computeKnownBits(V, DemandedElts, Known, Depth, Q); return Known.One != 0; } +bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) { + Type *Ty = V->getType(); + APInt DemandedElts = Ty->isVectorTy() + ? APInt::getAllOnesValue(Ty->getVectorNumElements()) + : APInt(1, 1); + return isKnownNonZero(V, DemandedElts, Depth, Q); +} + /// Return true if V2 == V1 + X, where X is known non-zero. static bool isAddOfNonZero(const Value *V1, const Value *V2, const Query &Q) { const BinaryOperator *BO = dyn_cast<BinaryOperator>(V1); |