[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