[ValueTracking] improve ComputeNumSignBits for vector constants

This is similar to the computeKnownBits improvement in rL268479. 
There's probably more we can do for vector logic instructions, but 
this should let us see non-splat constant masking ops that can
become vector selects instead of and/andn/or sequences.

Differential Revision: http://reviews.llvm.org/D21610



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273459 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel 2016-06-22 19:20:59 +00:00
parent 577fa41d50
commit efa1f7f367
3 changed files with 37 additions and 9 deletions

View File

@ -138,9 +138,9 @@ template <typename T> class ArrayRef;
/// the other bits. We know that at least 1 bit is always equal to the sign
/// bit (itself), but other cases can give us information. For example,
/// immediately after an "ashr X, 2", we know that the top 3 bits are all
/// equal to each other, so we return 3.
///
/// 'Op' must have a scalar integer type.
/// equal to each other, so we return 3. For vectors, return the number of
/// sign bits for the vector element with the mininum number of known sign
/// bits.
unsigned ComputeNumSignBits(Value *Op, const DataLayout &DL,
unsigned Depth = 0, AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,

View File

@ -1918,16 +1918,39 @@ bool MaskedValueIsZero(Value *V, const APInt &Mask, unsigned Depth,
return (KnownZero & Mask) == Mask;
}
/// For vector constants, loop over the elements and find the constant with the
/// minimum number of sign bits. Return 0 if the value is not a vector constant
/// or if any element was not analyzed; otherwise, return the count for the
/// element with the minimum number of sign bits.
static unsigned computeNumSignBitsVectorConstant(Value *V, unsigned TyBits) {
auto *CV = dyn_cast<Constant>(V);
if (!CV || !CV->getType()->isVectorTy())
return 0;
unsigned MinSignBits = TyBits;
unsigned NumElts = CV->getType()->getVectorNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
// If we find a non-ConstantInt, bail out.
auto *Elt = dyn_cast_or_null<ConstantInt>(CV->getAggregateElement(i));
if (!Elt)
return 0;
// If the sign bit is 1, flip the bits, so we always count leading zeros.
APInt EltVal = Elt->getValue();
if (EltVal.isNegative())
EltVal = ~EltVal;
MinSignBits = std::min(MinSignBits, EltVal.countLeadingZeros());
}
return MinSignBits;
}
/// Return the number of times the sign bit of the register is replicated into
/// the other bits. We know that at least 1 bit is always equal to the sign bit
/// (itself), but other cases can give us information. For example, immediately
/// after an "ashr X, 2", we know that the top 3 bits are all equal to each
/// other, so we return 3.
///
/// 'Op' must have a scalar integer type.
///
/// other, so we return 3. For vectors, return the number of sign bits for the
/// vector element with the mininum number of known sign bits.
unsigned ComputeNumSignBits(Value *V, unsigned Depth, const Query &Q) {
unsigned TyBits = Q.DL.getTypeSizeInBits(V->getType()->getScalarType());
unsigned Tmp, Tmp2;
@ -2123,6 +2146,12 @@ unsigned ComputeNumSignBits(Value *V, unsigned Depth, const Query &Q) {
// Finally, if we can prove that the top bits of the result are 0's or 1's,
// use this information.
// If we can examine all elements of a vector constant successfully, we're
// done (we can't do any better than that). If not, keep trying.
if (unsigned VecSignBits = computeNumSignBitsVectorConstant(V, TyBits))
return VecSignBits;
APInt KnownZero(TyBits, 0), KnownOne(TyBits, 0);
APInt Mask;
computeKnownBits(V, KnownZero, KnownOne, Depth, Q);

View File

@ -423,8 +423,7 @@ define <2 x i64> @ashr_minus1_vec(<2 x i64> %shiftval) {
define <2 x i4> @ashr_zero_minus1_vec(<2 x i4> %shiftval) {
; CHECK-LABEL: @ashr_zero_minus1_vec(
; CHECK-NEXT: [[SHR:%.*]] = ashr <2 x i4> <i4 0, i4 -1>, %shiftval
; CHECK-NEXT: ret <2 x i4> [[SHR]]
; CHECK-NEXT: ret <2 x i4> <i4 0, i4 -1>
;
%shr = ashr <2 x i4> <i4 0, i4 -1>, %shiftval
ret <2 x i4> %shr