[PATCH] D35040: [IR] Implement Constant::isNegativeZeroValue/isZeroValue/isAllOnesValue/isOneValue/isMinSignedValue for ConstantDataVector without going through getElementAsConstant

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 14 15:59:31 PDT 2017


LGTM

Craig Topper via Phabricator <reviews at reviews.llvm.org> writes:
> craig.topper updated this revision to Diff 106038.
> craig.topper added a comment.
>
> Add getElementAsAPInt.
>
>
> https://reviews.llvm.org/D35040
>
> Files:
>   include/llvm/IR/Constants.h
>   lib/IR/Constants.cpp
>
> Index: lib/IR/Constants.cpp
> ===================================================================
> --- lib/IR/Constants.cpp
> +++ lib/IR/Constants.cpp
> @@ -44,8 +44,8 @@
>  
>    // Equivalent for a vector of -0.0's.
>    if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
> -      if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
> +    if (CV->getElementType()->isFloatingPointTy() && CV->isSplat())
> +      if (CV->getElementAsAPFloat(0).isNegZero())
>          return true;
>  
>    if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
> @@ -70,8 +70,8 @@
>  
>    // Equivalent for a vector of -0.0's.
>    if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
> -      if (SplatCFP && SplatCFP->isZero())
> +    if (CV->getElementType()->isFloatingPointTy() && CV->isSplat())
> +      if (CV->getElementAsAPFloat(0).isZero())
>          return true;
>  
>    if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
> @@ -113,9 +113,13 @@
>        return Splat->isAllOnesValue();
>  
>    // Check for constant vectors which are splats of -1 values.
> -  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (Constant *Splat = CV->getSplatValue())
> -      return Splat->isAllOnesValue();
> +  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
> +    if (CV->isSplat()) {
> +      if (CV->getElementType()->isFloatingPointTy())
> +        return CV->getElementAsAPFloat(0).bitcastToAPInt().isAllOnesValue();
> +      return CV->getElementAsAPInt(0).isAllOnesValue();
> +    }
> +  }
>  
>    return false;
>  }
> @@ -135,9 +139,13 @@
>        return Splat->isOneValue();
>  
>    // Check for constant vectors which are splats of 1 values.
> -  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (Constant *Splat = CV->getSplatValue())
> -      return Splat->isOneValue();
> +  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
> +    if (CV->isSplat()) {
> +      if (CV->getElementType()->isFloatingPointTy())
> +        return CV->getElementAsAPFloat(0).bitcastToAPInt().isOneValue();
> +      return CV->getElementAsAPInt(0).isOneValue();
> +    }
> +  }
>  
>    return false;
>  }
> @@ -157,9 +165,13 @@
>        return Splat->isMinSignedValue();
>  
>    // Check for constant vectors which are splats of INT_MIN values.
> -  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (Constant *Splat = CV->getSplatValue())
> -      return Splat->isMinSignedValue();
> +  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
> +    if (CV->isSplat()) {
> +      if (CV->getElementType()->isFloatingPointTy())
> +        return CV->getElementAsAPFloat(0).bitcastToAPInt().isMinSignedValue();
> +      return CV->getElementAsAPInt(0).isMinSignedValue();
> +    }
> +  }
>  
>    return false;
>  }
> @@ -179,9 +191,13 @@
>        return Splat->isNotMinSignedValue();
>  
>    // Check for constant vectors which are splats of INT_MIN values.
> -  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
> -    if (Constant *Splat = CV->getSplatValue())
> -      return Splat->isNotMinSignedValue();
> +  if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this)) {
> +    if (CV->isSplat()) {
> +      if (CV->getElementType()->isFloatingPointTy())
> +        return !CV->getElementAsAPFloat(0).bitcastToAPInt().isMinSignedValue();
> +      return !CV->getElementAsAPInt(0).isMinSignedValue();
> +    }
> +  }
>  
>    // It *may* contain INT_MIN, we can't tell.
>    return false;
> @@ -2565,6 +2581,34 @@
>    }
>  }
>  
> +APInt ConstantDataSequential::getElementAsAPInt(unsigned Elt) const {
> +  assert(isa<IntegerType>(getElementType()) &&
> +         "Accessor can only be used when element is an integer");
> +  const char *EltPtr = getElementPointer(Elt);
> +
> +  // The data is stored in host byte order, make sure to cast back to the right
> +  // type to load with the right endianness.
> +  switch (getElementType()->getIntegerBitWidth()) {
> +  default: llvm_unreachable("Invalid bitwidth for CDS");
> +  case 8: {
> +    auto EltVal = *reinterpret_cast<const uint8_t *>(EltPtr);
> +    return APInt(8, EltVal);
> +  }
> +  case 16: {
> +    auto EltVal = *reinterpret_cast<const uint16_t *>(EltPtr);
> +    return APInt(16, EltVal);
> +  }
> +  case 32: {
> +    auto EltVal = *reinterpret_cast<const uint32_t *>(EltPtr);
> +    return APInt(32, EltVal);
> +  }
> +  case 64: {
> +    auto EltVal = *reinterpret_cast<const uint64_t *>(EltPtr);
> +    return APInt(64, EltVal);
> +  }
> +  }
> +}
> +
>  APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
>    const char *EltPtr = getElementPointer(Elt);
>  
> @@ -2623,17 +2667,21 @@
>    return Str.drop_back().find(0) == StringRef::npos;
>  }
>  
> -Constant *ConstantDataVector::getSplatValue() const {
> +bool ConstantDataVector::isSplat() const {
>    const char *Base = getRawDataValues().data();
>  
>    // Compare elements 1+ to the 0'th element.
>    unsigned EltSize = getElementByteSize();
>    for (unsigned i = 1, e = getNumElements(); i != e; ++i)
>      if (memcmp(Base, Base+i*EltSize, EltSize))
> -      return nullptr;
> +      return false;
> +
> +  return true;
> +}
>  
> +Constant *ConstantDataVector::getSplatValue() const {
>    // If they're all the same, return the 0th one as a representative.
> -  return getElementAsConstant(0);
> +  return isSplat() ? getElementAsConstant(0) : nullptr;
>  }
>  
>  //===----------------------------------------------------------------------===//
> Index: include/llvm/IR/Constants.h
> ===================================================================
> --- include/llvm/IR/Constants.h
> +++ include/llvm/IR/Constants.h
> @@ -598,6 +598,10 @@
>    /// specified element in the low bits of a uint64_t.
>    uint64_t getElementAsInteger(unsigned i) const;
>  
> +  /// If this is a sequential container of integers (of any size), return the
> +  /// specified element as an APInt.
> +  APInt getElementAsAPInt(unsigned i) const;
> +
>    /// If this is a sequential container of floating point type, return the
>    /// specified element as an APFloat.
>    APFloat getElementAsAPFloat(unsigned i) const;
> @@ -761,6 +765,10 @@
>    /// i32/i64/float/double) and must be a ConstantFP or ConstantInt.
>    static Constant *getSplat(unsigned NumElts, Constant *Elt);
>  
> +  /// Returns true if this is a splat constant, meaning that all elements have
> +  /// the same value.
> +  bool isSplat() const;
> +
>    /// If this is a splat constant, meaning that all of the elements have the
>    /// same value, return that value. Otherwise return NULL.
>    Constant *getSplatValue() const;


More information about the llvm-commits mailing list