diff options
author | James Molloy <james.molloy@arm.com> | 2015-09-24 16:06:32 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2015-09-24 16:06:32 +0000 |
commit | b6be1ebb7d53475c4edd88131efd52a84e1b6b23 (patch) | |
tree | 768162cdb68ab434730a0473eff68f25e23930c2 /llvm/lib/Analysis | |
parent | bd432b2d04b2aa0a42ec6c222e898baed339980e (diff) | |
download | bcm5719-llvm-b6be1ebb7d53475c4edd88131efd52a84e1b6b23.tar.gz bcm5719-llvm-b6be1ebb7d53475c4edd88131efd52a84e1b6b23.zip |
[ValueTracking] Teach isKnownNonZero a new trick
If the shifter operand is a constant, and all of the bits shifted out
are known to be zero, then if X is known non-zero at least one
non-zero bit must remain.
llvm-svn: 248508
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 10776a03cae..417122be0d8 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1827,6 +1827,23 @@ bool isKnownNonZero(Value *V, const DataLayout &DL, unsigned Depth, ComputeSignBit(X, XKnownNonNegative, XKnownNegative, DL, Depth, Q); if (XKnownNegative) return true; + + // If the shifter operand is a constant, and all of the bits shifted + // out are known to be zero, and X is known non-zero then at least one + // non-zero bit must remain. + if (ConstantInt *Shift = dyn_cast<ConstantInt>(Y)) { + APInt KnownZero(BitWidth, 0); + APInt KnownOne(BitWidth, 0); + computeKnownBits(X, KnownZero, KnownOne, DL, Depth, Q); + + auto ShiftVal = Shift->getLimitedValue(BitWidth - 1); + // Is there a known one in the portion not shifted out? + if (KnownOne.countLeadingZeros() < BitWidth - ShiftVal) + return true; + // Are all the bits to be shifted out known zero? + if (KnownZero.countTrailingOnes() >= ShiftVal) + return isKnownNonZero(X, DL, 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())))) { |