static void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth,
const Query &Q) {
- Type *Ty = V->getType();
+ // FIXME: We currently have no way to represent the DemandedElts of a scalable
+ // vector
+ if (isa<ScalableVectorType>(V->getType())) {
+ Known.resetAll();
+ return;
+ }
+
+ auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
- Ty->isVectorTy()
- ? APInt::getAllOnesValue(cast<VectorType>(Ty)->getNumElements())
- : APInt(1, 1);
+ FVTy ? APInt::getAllOnesValue(FVTy->getNumElements()) : APInt(1, 1);
computeKnownBits(V, DemandedElts, Known, Depth, Q);
}
static unsigned ComputeNumSignBits(const Value *V, unsigned Depth,
const Query &Q) {
- Type *Ty = V->getType();
+ // FIXME: We currently have no way to represent the DemandedElts of a scalable
+ // vector
+ if (isa<ScalableVectorType>(V->getType()))
+ return 1;
+
+ auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
- Ty->isVectorTy()
- ? APInt::getAllOnesValue(cast<VectorType>(Ty)->getNumElements())
- : APInt(1, 1);
+ FVTy ? APInt::getAllOnesValue(FVTy->getNumElements()) : APInt(1, 1);
return ComputeNumSignBits(V, DemandedElts, Depth, Q);
}
const Value *Vec = I->getOperand(0);
const Value *Idx = I->getOperand(1);
auto *CIdx = dyn_cast<ConstantInt>(Idx);
- unsigned NumElts = cast<VectorType>(Vec->getType())->getNumElements();
+ if (isa<ScalableVectorType>(Vec->getType())) {
+ // FIXME: there's probably *something* we can do with scalable vectors
+ Known.resetAll();
+ break;
+ }
+ unsigned NumElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
APInt DemandedVecElts = APInt::getAllOnesValue(NumElts);
if (CIdx && CIdx->getValue().ult(NumElts))
DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
/// for all of the demanded elements in the vector specified by DemandedElts.
void computeKnownBits(const Value *V, const APInt &DemandedElts,
KnownBits &Known, unsigned Depth, const Query &Q) {
+ if (!DemandedElts || isa<ScalableVectorType>(V->getType())) {
+ // No demanded elts or V is a scalable vector, better to assume we don't
+ // know anything.
+ Known.resetAll();
+ return;
+ }
+
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
- unsigned BitWidth = Known.getBitWidth();
+#ifndef NDEBUG
Type *Ty = V->getType();
+ unsigned BitWidth = Known.getBitWidth();
+
assert((Ty->isIntOrIntVectorTy(BitWidth) || Ty->isPtrOrPtrVectorTy()) &&
"Not integer or pointer type!");
- assert(((Ty->isVectorTy() && cast<VectorType>(Ty)->getNumElements() ==
- DemandedElts.getBitWidth()) ||
- (!Ty->isVectorTy() && DemandedElts == APInt(1, 1))) &&
- "Unexpected vector size");
+
+ if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
+ assert(
+ FVTy->getNumElements() == DemandedElts.getBitWidth() &&
+ "DemandedElt width should equal the fixed vector number of elements");
+ } else {
+ assert(DemandedElts == APInt(1, 1) &&
+ "DemandedElt width should be 1 for scalars");
+ }
Type *ScalarTy = Ty->getScalarType();
- unsigned ExpectedWidth = ScalarTy->isPointerTy() ?
- Q.DL.getPointerTypeSizeInBits(ScalarTy) : Q.DL.getTypeSizeInBits(ScalarTy);
- assert(ExpectedWidth == BitWidth && "V and Known should have same BitWidth");
- (void)BitWidth;
- (void)ExpectedWidth;
-
- if (!DemandedElts) {
- // No demanded elts, better to assume we don't know anything.
- Known.resetAll();
- return;
+ if (ScalarTy->isPointerTy()) {
+ assert(BitWidth == Q.DL.getPointerTypeSizeInBits(ScalarTy) &&
+ "V and Known should have same BitWidth");
+ } else {
+ assert(BitWidth == Q.DL.getTypeSizeInBits(ScalarTy) &&
+ "V and Known should have same BitWidth");
}
+#endif
const APInt *C;
if (match(V, m_APInt(C))) {
}
// Handle a constant vector by taking the intersection of the known bits of
// each element.
- if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) {
- assert((!Ty->isVectorTy() ||
- CDS->getNumElements() == DemandedElts.getBitWidth()) &&
- "Unexpected vector size");
- // We know that CDS must be a vector of integers. Take the intersection of
+ if (const ConstantDataVector *CDV = dyn_cast<ConstantDataVector>(V)) {
+ // We know that CDV must be a vector of integers. Take the intersection of
// each element.
Known.Zero.setAllBits(); Known.One.setAllBits();
- for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
- if (Ty->isVectorTy() && !DemandedElts[i])
+ for (unsigned i = 0, e = CDV->getNumElements(); i != e; ++i) {
+ if (!DemandedElts[i])
continue;
- APInt Elt = CDS->getElementAsAPInt(i);
+ APInt Elt = CDV->getElementAsAPInt(i);
Known.Zero &= ~Elt;
Known.One &= Elt;
}
}
if (const auto *CV = dyn_cast<ConstantVector>(V)) {
- assert(CV->getNumOperands() == DemandedElts.getBitWidth() &&
- "Unexpected vector size");
// We know that CV must be a vector of integers. Take the intersection of
// each element.
Known.Zero.setAllBits(); Known.One.setAllBits();
computeKnownBitsFromOperator(I, DemandedElts, Known, Depth, Q);
// Aligned pointers have trailing zeros - refine Known.Zero set
- if (Ty->isPointerTy()) {
+ if (isa<PointerType>(V->getType())) {
const MaybeAlign Align = V->getPointerAlignment(Q.DL);
if (Align)
Known.Zero.setLowBits(countTrailingZeros(Align->value()));
/// Supports values with integer or pointer type and vectors of integers.
bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
const Query &Q) {
+ // FIXME: We currently have no way to represent the DemandedElts of a scalable
+ // vector
+ if (isa<ScalableVectorType>(V->getType()))
+ return false;
+
if (auto *C = dyn_cast<Constant>(V)) {
if (C->isNullValue())
return false;
// For constant vectors, check that all elements are undefined or known
// non-zero to determine that the whole vector is known non-zero.
- if (auto *VecTy = dyn_cast<VectorType>(C->getType())) {
+ if (auto *VecTy = dyn_cast<FixedVectorType>(C->getType())) {
for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) {
if (!DemandedElts[i])
continue;
const Value *Vec = EEI->getVectorOperand();
const Value *Idx = EEI->getIndexOperand();
auto *CIdx = dyn_cast<ConstantInt>(Idx);
- unsigned NumElts = cast<VectorType>(Vec->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(Vec->getType())->getNumElements();
APInt DemandedVecElts = APInt::getAllOnesValue(NumElts);
if (CIdx && CIdx->getValue().ult(NumElts))
DemandedVecElts = APInt::getOneBitSet(NumElts, CIdx->getZExtValue());
}
bool isKnownNonZero(const Value* V, unsigned Depth, const Query& Q) {
- Type *Ty = V->getType();
+ // FIXME: We currently have no way to represent the DemandedElts of a scalable
+ // vector
+ if (isa<ScalableVectorType>(V->getType()))
+ return false;
+
+ auto *FVTy = dyn_cast<FixedVectorType>(V->getType());
APInt DemandedElts =
- Ty->isVectorTy()
- ? APInt::getAllOnesValue(cast<VectorType>(Ty)->getNumElements())
- : APInt(1, 1);
+ FVTy ? APInt::getAllOnesValue(FVTy->getNumElements()) : APInt(1, 1);
return isKnownNonZero(V, DemandedElts, Depth, Q);
}
const APInt &DemandedElts,
unsigned TyBits) {
const auto *CV = dyn_cast<Constant>(V);
- if (!CV || !CV->getType()->isVectorTy())
+ if (!CV || !isa<FixedVectorType>(CV->getType()))
return 0;
unsigned MinSignBits = TyBits;
- unsigned NumElts = cast<VectorType>(CV->getType())->getNumElements();
+ unsigned NumElts = cast<FixedVectorType>(CV->getType())->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
if (!DemandedElts[i])
continue;
static unsigned ComputeNumSignBitsImpl(const Value *V,
const APInt &DemandedElts,
unsigned Depth, const Query &Q) {
+ Type *Ty = V->getType();
+
+ // FIXME: We currently have no way to represent the DemandedElts of a scalable
+ // vector
+ if (isa<ScalableVectorType>(Ty))
+ return 1;
+
+#ifndef NDEBUG
assert(Depth <= MaxDepth && "Limit Search Depth");
+ if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
+ assert(
+ FVTy->getNumElements() == DemandedElts.getBitWidth() &&
+ "DemandedElt width should equal the fixed vector number of elements");
+ } else {
+ assert(DemandedElts == APInt(1, 1) &&
+ "DemandedElt width should be 1 for scalars");
+ }
+#endif
+
// We return the minimum number of sign bits that are guaranteed to be present
// in V, so for undef we have to conservatively return 1. We don't have the
// same behavior for poison though -- that's a FIXME today.
- Type *Ty = V->getType();
- assert(((Ty->isVectorTy() && cast<VectorType>(Ty)->getNumElements() ==
- DemandedElts.getBitWidth()) ||
- (!Ty->isVectorTy() && DemandedElts == APInt(1, 1))) &&
- "Unexpected vector size");
-
Type *ScalarTy = Ty->getScalarType();
unsigned TyBits = ScalarTy->isPointerTy() ?
Q.DL.getPointerTypeSizeInBits(ScalarTy) :
// Handle vector of constants.
if (auto *CV = dyn_cast<Constant>(V)) {
- if (auto *CVVTy = dyn_cast<VectorType>(CV->getType())) {
- unsigned NumElts = CVVTy->getNumElements();
+ if (auto *CVFVTy = dyn_cast<FixedVectorType>(CV->getType())) {
+ unsigned NumElts = CVFVTy->getNumElements();
for (unsigned i = 0; i != NumElts; ++i) {
auto *CFP = dyn_cast_or_null<ConstantFP>(CV->getAggregateElement(i));
if (!CFP)
}
}
- // Bail out for constant expressions, but try to handle vector constants.
- if (!V->getType()->isVectorTy() || !isa<Constant>(V))
- return false;
-
- // For vectors, verify that each element is not infinity.
- unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
- if (!Elt)
- return false;
- if (isa<UndefValue>(Elt))
- continue;
- auto *CElt = dyn_cast<ConstantFP>(Elt);
- if (!CElt || CElt->isInfinity())
- return false;
+ // try to handle fixed width vector constants
+ if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V)) {
+ // For vectors, verify that each element is not infinity.
+ unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
+ if (!Elt)
+ return false;
+ if (isa<UndefValue>(Elt))
+ continue;
+ auto *CElt = dyn_cast<ConstantFP>(Elt);
+ if (!CElt || CElt->isInfinity())
+ return false;
+ }
+ // All elements were confirmed non-infinity or undefined.
+ return true;
}
- // All elements were confirmed non-infinity or undefined.
- return true;
+
+ // was not able to prove that V never contains infinity
+ return false;
}
bool llvm::isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI,
}
}
- // Bail out for constant expressions, but try to handle vector constants.
- if (!V->getType()->isVectorTy() || !isa<Constant>(V))
- return false;
-
- // For vectors, verify that each element is not NaN.
- unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
- if (!Elt)
- return false;
- if (isa<UndefValue>(Elt))
- continue;
- auto *CElt = dyn_cast<ConstantFP>(Elt);
- if (!CElt || CElt->isNaN())
- return false;
+ // Try to handle fixed width vector constants
+ if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V)) {
+ // For vectors, verify that each element is not NaN.
+ unsigned NumElts = cast<VectorType>(V->getType())->getNumElements();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
+ if (!Elt)
+ return false;
+ if (isa<UndefValue>(Elt))
+ continue;
+ auto *CElt = dyn_cast<ConstantFP>(Elt);
+ if (!CElt || CElt->isNaN())
+ return false;
+ }
+ // All elements were confirmed not-NaN or undefined.
+ return true;
}
- // All elements were confirmed not-NaN or undefined.
- return true;
+
+ // Was not able to prove that V never contains NaN
+ return false;
}
Value *llvm::isBytewiseValue(Value *V, const DataLayout &DL) {
// Shifts return poison if shiftwidth is larger than the bitwidth.
if (auto *C = dyn_cast<Constant>(I->getOperand(1))) {
SmallVector<Constant *, 4> ShiftAmounts;
- if (C->getType()->isVectorTy()) {
- unsigned NumElts = cast<VectorType>(C->getType())->getNumElements();
+ if (auto *FVTy = dyn_cast<FixedVectorType>(C->getType())) {
+ unsigned NumElts = FVTy->getNumElements();
for (unsigned i = 0; i < NumElts; ++i)
ShiftAmounts.push_back(C->getAggregateElement(i));
- } else
+ } else if (isa<ScalableVectorType>(C->getType()))
+ return true; // Can't tell, just return true to be safe
+ else
ShiftAmounts.push_back(C);
bool Safe = llvm::all_of(ShiftAmounts, [](Constant *C) {