diff --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h index ae871cf478733d..53c888e0a2e9b4 100644 --- a/llvm/include/llvm/Support/TypeSize.h +++ b/llvm/include/llvm/Support/TypeSize.h @@ -31,176 +31,97 @@ namespace llvm { /// done on a scalable vector. This function may not return. void reportInvalidSizeRequest(const char *Msg); -template struct LinearPolyBaseTypeTraits {}; +/// StackOffset holds a fixed and a scalable offset in bytes. +class StackOffset { + int64_t Fixed = 0; + int64_t Scalable = 0; -//===----------------------------------------------------------------------===// -// LinearPolyBase - a base class for linear polynomials with multiple -// dimensions. This can e.g. be used to describe offsets that are have both a -// fixed and scalable component. -//===----------------------------------------------------------------------===// - -/// LinearPolyBase describes a linear polynomial: -/// c0 * scale0 + c1 * scale1 + ... + cK * scaleK -/// where the scale is implicit, so only the coefficients are encoded. -template -class LinearPolyBase { -public: - using ScalarTy = typename LinearPolyBaseTypeTraits::ScalarTy; - static constexpr auto Dimensions = LinearPolyBaseTypeTraits::Dimensions; - static_assert(Dimensions != std::numeric_limits::max(), - "Dimensions out of range"); - -private: - std::array Coefficients; - -protected: - constexpr LinearPolyBase(ArrayRef Values) { - std::copy(Values.begin(), Values.end(), Coefficients.begin()); - } + StackOffset(int64_t Fixed, int64_t Scalable) + : Fixed(Fixed), Scalable(Scalable) {} public: - friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) { - for (unsigned I=0; I - friend std::enable_if_t::value, LeafTy> - operator-(const LeafTy &LHS) { - LeafTy Copy = LHS; - return Copy *= -1; + StackOffset &operator+=(const StackOffset &RHS) { + Fixed += RHS.Fixed; + Scalable += RHS.Scalable; + return *this; } - - constexpr bool operator==(const LinearPolyBase &RHS) const { - return std::equal(Coefficients.begin(), Coefficients.end(), - RHS.Coefficients.begin()); + StackOffset &operator-=(const StackOffset &RHS) { + Fixed -= RHS.Fixed; + Scalable -= RHS.Scalable; + return *this; } + StackOffset operator-() const { return {-Fixed, -Scalable}; } - constexpr bool operator!=(const LinearPolyBase &RHS) const { - return !(*this == RHS); + // Equality comparisons. + bool operator==(const StackOffset &RHS) const { + return Fixed == RHS.Fixed && Scalable == RHS.Scalable; } - - constexpr bool isZero() const { - return all_of(Coefficients, [](const ScalarTy &C) { return C == 0; }); + bool operator!=(const StackOffset &RHS) const { + return Fixed != RHS.Fixed || Scalable != RHS.Scalable; } - constexpr bool isNonZero() const { return !isZero(); } - constexpr explicit operator bool() const { return isNonZero(); } - constexpr ScalarTy getValue(unsigned Dim) const { return Coefficients[Dim]; } + // The bool operator returns true iff any of the components is non zero. + explicit operator bool() const { return Fixed != 0 || Scalable != 0; } }; -//===----------------------------------------------------------------------===// -// StackOffset - Represent an offset with named fixed and scalable components. -//===----------------------------------------------------------------------===// - -class StackOffset; -template <> struct LinearPolyBaseTypeTraits { - using ScalarTy = int64_t; - static constexpr unsigned Dimensions = 2; -}; - -/// StackOffset is a class to represent an offset with 2 dimensions, -/// named fixed and scalable, respectively. This class allows a value for both -/// dimensions to depict e.g. "8 bytes and 16 scalable bytes", which is needed -/// to represent stack offsets. -class StackOffset : public LinearPolyBase { -protected: - StackOffset(ScalarTy Fixed, ScalarTy Scalable) - : LinearPolyBase({Fixed, Scalable}) {} +namespace details { +// Base class for ElementCount and TypeSize below. +template class FixedOrScalableQuantity { public: - StackOffset() : StackOffset({0, 0}) {} - StackOffset(const LinearPolyBase &Other) - : LinearPolyBase(Other) {} - static StackOffset getFixed(ScalarTy Fixed) { return {Fixed, 0}; } - static StackOffset getScalable(ScalarTy Scalable) { return {0, Scalable}; } - static StackOffset get(ScalarTy Fixed, ScalarTy Scalable) { - return {Fixed, Scalable}; - } - - ScalarTy getFixed() const { return this->getValue(0); } - ScalarTy getScalable() const { return this->getValue(1); } -}; - -//===----------------------------------------------------------------------===// -// UnivariateLinearPolyBase - a base class for linear polynomials with multiple -// dimensions, but where only one dimension can be set at any time. -// This can e.g. be used to describe sizes that are either fixed or scalable. -//===----------------------------------------------------------------------===// - -/// UnivariateLinearPolyBase is a base class for ElementCount and TypeSize. -/// Like LinearPolyBase it tries to represent a linear polynomial -/// where only one dimension can be set at any time, e.g. -/// 0 * scale0 + 0 * scale1 + ... + cJ * scaleJ + ... + 0 * scaleK -/// The dimension that is set is the univariate dimension. -template -class UnivariateLinearPolyBase { -public: - using ScalarTy = typename LinearPolyBaseTypeTraits::ScalarTy; - static constexpr auto Dimensions = LinearPolyBaseTypeTraits::Dimensions; - static_assert(Dimensions != std::numeric_limits::max(), - "Dimensions out of range"); + using ScalarTy = ValueTy; protected: - ScalarTy Value; // The value at the univeriate dimension. - unsigned UnivariateDim; // The univeriate dimension. + ScalarTy Quantity = 0; + bool Scalable = false; - constexpr UnivariateLinearPolyBase(ScalarTy Val, unsigned UnivariateDim) - : Value(Val), UnivariateDim(UnivariateDim) { - assert(UnivariateDim < Dimensions && "Dimension out of range"); - } + constexpr FixedOrScalableQuantity() = default; + constexpr FixedOrScalableQuantity(ScalarTy Quantity, bool Scalable) + : Quantity(Quantity), Scalable(Scalable) {} - friend LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) { - assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions"); - LHS.Value += RHS.Value; + friend constexpr LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) { + assert(LHS.Scalable == RHS.Scalable && "Incompatible types"); + LHS.Quantity += RHS.Quantity; return LHS; } - friend LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) { - assert(LHS.UnivariateDim == RHS.UnivariateDim && "Invalid dimensions"); - LHS.Value -= RHS.Value; + friend constexpr LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) { + assert(LHS.Scalable == RHS.Scalable && "Incompatible types"); + LHS.Quantity -= RHS.Quantity; return LHS; } friend constexpr LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) { - LHS.Value *= RHS; + LHS.Quantity *= RHS; return LHS; } - friend LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) { + friend constexpr LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) { LeafTy Copy = LHS; return Copy += RHS; } - friend LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) { + friend constexpr LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) { LeafTy Copy = LHS; return Copy -= RHS; } @@ -211,96 +132,43 @@ class UnivariateLinearPolyBase { } template - friend std::enable_if_t::value, LeafTy> + friend constexpr std::enable_if_t::value, LeafTy> operator-(const LeafTy &LHS) { LeafTy Copy = LHS; return Copy *= -1; } public: - constexpr bool operator==(const UnivariateLinearPolyBase &RHS) const { - return Value == RHS.Value && UnivariateDim == RHS.UnivariateDim; - } - - constexpr bool operator!=(const UnivariateLinearPolyBase &RHS) const { - return !(*this == RHS); - } - - constexpr bool isZero() const { return !Value; } - constexpr bool isNonZero() const { return !isZero(); } - explicit constexpr operator bool() const { return isNonZero(); } - constexpr ScalarTy getValue(unsigned Dim) const { - return Dim == UnivariateDim ? Value : 0; + constexpr bool operator==(const FixedOrScalableQuantity &RHS) const { + return Quantity == RHS.Quantity && Scalable == RHS.Scalable; } - /// Add \p RHS to the value at the univariate dimension. - constexpr LeafTy getWithIncrement(ScalarTy RHS) const { - return static_cast( - UnivariateLinearPolyBase(Value + RHS, UnivariateDim)); - } - - /// Subtract \p RHS from the value at the univariate dimension. - constexpr LeafTy getWithDecrement(ScalarTy RHS) const { - return static_cast( - UnivariateLinearPolyBase(Value - RHS, UnivariateDim)); + constexpr bool operator!=(const FixedOrScalableQuantity &RHS) const { + return Quantity != RHS.Quantity || Scalable != RHS.Scalable; } -}; - -//===----------------------------------------------------------------------===// -// LinearPolySize - base class for fixed- or scalable sizes. -// ^ ^ -// | | -// | +----- ElementCount - Leaf class to represent an element count -// | (vscale x unsigned) -// | -// +-------- TypeSize - Leaf class to represent a type size -// (vscale x uint64_t) -//===----------------------------------------------------------------------===// + constexpr bool isZero() const { return Quantity == 0; } -/// LinearPolySize is a base class to represent sizes. It is either -/// fixed-sized or it is scalable-sized, but it cannot be both. -template -class LinearPolySize : public UnivariateLinearPolyBase { - // Make the parent class a friend, so that it can access the protected - // conversion/copy-constructor for UnivariatePolyBase -> - // LinearPolySize. - friend class UnivariateLinearPolyBase; + constexpr bool isNonZero() const { return Quantity != 0; } -public: - using ScalarTy = typename UnivariateLinearPolyBase::ScalarTy; - enum Dims : unsigned { FixedDim = 0, ScalableDim = 1 }; + explicit operator bool() const { return isNonZero(); } -protected: - constexpr LinearPolySize(ScalarTy MinVal, Dims D) - : UnivariateLinearPolyBase(MinVal, D) {} + /// Add \p RHS to the underlying quantity. + constexpr LeafTy getWithIncrement(ScalarTy RHS) const { + return LeafTy::get(Quantity + RHS, Scalable); + } - constexpr LinearPolySize(const UnivariateLinearPolyBase &V) - : UnivariateLinearPolyBase(V) {} + /// Returns the minimum value this quantity can represent. + constexpr ScalarTy getKnownMinValue() const { return Quantity; } -public: - static constexpr LeafTy getFixed(ScalarTy MinVal) { - return static_cast(LinearPolySize(MinVal, FixedDim)); - } - static constexpr LeafTy getScalable(ScalarTy MinVal) { - return static_cast(LinearPolySize(MinVal, ScalableDim)); - } - static constexpr LeafTy get(ScalarTy MinVal, bool Scalable) { - return static_cast( - LinearPolySize(MinVal, Scalable ? ScalableDim : FixedDim)); - } - static constexpr LeafTy getNull() { return get(0, false); } + /// Returns whether the quantity is scaled by a runtime quantity (vscale). + constexpr bool isScalable() const { return Scalable; } - /// Returns the minimum value this size can represent. - constexpr ScalarTy getKnownMinValue() const { return this->Value; } - /// Returns whether the size is scaled by a runtime quantity (vscale). - constexpr bool isScalable() const { - return this->UnivariateDim == ScalableDim; - } /// A return value of true indicates we know at compile time that the number /// of elements (vscale * Min) is definitely even. However, returning false /// does not guarantee that the total number of elements is odd. constexpr bool isKnownEven() const { return (getKnownMinValue() & 0x1) == 0; } + /// This function tells the caller whether the element count is known at /// compile time to be a multiple of the scalar value RHS. constexpr bool isKnownMultipleOf(ScalarTy RHS) const { @@ -316,8 +184,8 @@ class LinearPolySize : public UnivariateLinearPolyBase { return getKnownMinValue(); } - // For some cases, size ordering between scalable and fixed size types cannot - // be determined at compile time, so such comparisons aren't allowed. + // For some cases, quantity ordering between scalable and fixed quantity types + // cannot be determined at compile time, so such comparisons aren't allowed. // // e.g. could be bigger than <4 x i32> with a runtime // vscale >= 5, equal sized with a vscale of 4, and smaller with @@ -326,29 +194,29 @@ class LinearPolySize : public UnivariateLinearPolyBase { // All the functions below make use of the fact vscale is always >= 1, which // means that is guaranteed to be >= <4 x i32>, etc. - static constexpr bool isKnownLT(const LinearPolySize &LHS, - const LinearPolySize &RHS) { + static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, + const FixedOrScalableQuantity &RHS) { if (!LHS.isScalable() || RHS.isScalable()) return LHS.getKnownMinValue() < RHS.getKnownMinValue(); return false; } - static constexpr bool isKnownGT(const LinearPolySize &LHS, - const LinearPolySize &RHS) { + static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, + const FixedOrScalableQuantity &RHS) { if (LHS.isScalable() || !RHS.isScalable()) return LHS.getKnownMinValue() > RHS.getKnownMinValue(); return false; } - static constexpr bool isKnownLE(const LinearPolySize &LHS, - const LinearPolySize &RHS) { + static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, + const FixedOrScalableQuantity &RHS) { if (!LHS.isScalable() || RHS.isScalable()) return LHS.getKnownMinValue() <= RHS.getKnownMinValue(); return false; } - static constexpr bool isKnownGE(const LinearPolySize &LHS, - const LinearPolySize &RHS) { + static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, + const FixedOrScalableQuantity &RHS) { if (LHS.isScalable() || !RHS.isScalable()) return LHS.getKnownMinValue() >= RHS.getKnownMinValue(); return false; @@ -363,31 +231,31 @@ class LinearPolySize : public UnivariateLinearPolyBase { /// isKnownMultipleOf(RHS), which lets the caller know if it's possible to /// perform a lossless divide by RHS. constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const { - return static_cast( - LinearPolySize::get(getKnownMinValue() / RHS, isScalable())); + return LeafTy::get(getKnownMinValue() / RHS, isScalable()); } constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const { - return static_cast( - LinearPolySize::get(getKnownMinValue() * RHS, isScalable())); + return LeafTy::get(getKnownMinValue() * RHS, isScalable()); } constexpr LeafTy coefficientNextPowerOf2() const { - return static_cast(LinearPolySize::get( + return LeafTy::get( static_cast(llvm::NextPowerOf2(getKnownMinValue())), - isScalable())); + isScalable()); } /// Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) - /// will result in a value whose size matches our own. - constexpr bool hasKnownScalarFactor(const LinearPolySize &RHS) const { + /// will result in a value whose quantity matches our own. + constexpr bool + hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const { return isScalable() == RHS.isScalable() && getKnownMinValue() % RHS.getKnownMinValue() == 0; } /// Returns a value X where RHS.multiplyCoefficientBy(X) will result in a - /// value whose size matches our own. - constexpr ScalarTy getKnownScalarFactor(const LinearPolySize &RHS) const { + /// value whose quantity matches our own. + constexpr ScalarTy + getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const { assert(hasKnownScalarFactor(RHS) && "Expected RHS to be a known factor!"); return getKnownMinValue() / RHS.getKnownMinValue(); } @@ -400,22 +268,35 @@ class LinearPolySize : public UnivariateLinearPolyBase { } }; -class ElementCount; -template <> struct LinearPolyBaseTypeTraits { - using ScalarTy = unsigned; - static constexpr unsigned Dimensions = 2; -}; +} // namespace details + +// Stores the number of elements for a type and whether this type is fixed +// (N-Elements) or scalable (e.g., SVE). +// - ElementCount::getFixed(1) : A scalar value. +// - ElementCount::getFixed(2) : A vector type holding 2 values. +// - ElementCount::getScalable(4) : A scalable vector type holding 4 values. +class ElementCount + : public details::FixedOrScalableQuantity { + constexpr ElementCount(ScalarTy MinVal, bool Scalable) + : FixedOrScalableQuantity(MinVal, Scalable) {} + + constexpr ElementCount( + const FixedOrScalableQuantity &V) + : FixedOrScalableQuantity(V) {} -class ElementCount : public LinearPolySize { public: - constexpr ElementCount() : LinearPolySize(LinearPolySize::getNull()) {} + constexpr ElementCount() : FixedOrScalableQuantity() {} - constexpr ElementCount(const LinearPolySize &V) - : LinearPolySize(V) {} + static constexpr ElementCount getFixed(ScalarTy MinVal) { + return ElementCount(MinVal, false); + } + static constexpr ElementCount getScalable(ScalarTy MinVal) { + return ElementCount(MinVal, true); + } + static constexpr ElementCount get(ScalarTy MinVal, bool Scalable) { + return ElementCount(MinVal, Scalable); + } - /// Counting predicates. - /// - ///@{ Number of elements.. /// Exactly one element. constexpr bool isScalar() const { return !isScalable() && getKnownMinValue() == 1; @@ -424,33 +305,33 @@ class ElementCount : public LinearPolySize { constexpr bool isVector() const { return (isScalable() && getKnownMinValue() != 0) || getKnownMinValue() > 1; } - ///@} }; -// This class is used to represent the size of types. If the type is of fixed -class TypeSize; -template <> struct LinearPolyBaseTypeTraits { - using ScalarTy = uint64_t; - static constexpr unsigned Dimensions = 2; -}; +// Stores the size of a type. If the type is of fixed size, it will represent +// the exact size. If the type is a scalable vector, it will represent the known +// minimum size. +class TypeSize : public details::FixedOrScalableQuantity { + TypeSize(const FixedOrScalableQuantity &V) + : FixedOrScalableQuantity(V) {} -// TODO: Most functionality in this class will gradually be phased out -// so it will resemble LinearPolySize as much as possible. -// -// TypeSize is used to represent the size of types. If the type is of fixed -// size, it will represent the exact size. If the type is a scalable vector, -// it will represent the known minimum size. -class TypeSize : public LinearPolySize { public: - constexpr TypeSize(const LinearPolySize &V) : LinearPolySize(V) {} - constexpr TypeSize(ScalarTy MinVal, bool IsScalable) - : LinearPolySize(LinearPolySize::get(MinVal, IsScalable)) {} + constexpr TypeSize(ScalarTy Quantity, bool Scalable) + : FixedOrScalableQuantity(Quantity, Scalable) {} - static constexpr TypeSize Fixed(ScalarTy MinVal) { - return TypeSize(MinVal, false); + static constexpr TypeSize getFixed(ScalarTy ExactSize) { + return TypeSize(ExactSize, false); } - static constexpr TypeSize Scalable(ScalarTy MinVal) { - return TypeSize(MinVal, true); + static constexpr TypeSize getScalable(ScalarTy MinimunSize) { + return TypeSize(MinimunSize, true); + } + static constexpr TypeSize get(ScalarTy Quantity, bool Scalable) { + return TypeSize(Quantity, Scalable); + } + static constexpr TypeSize Fixed(ScalarTy ExactSize) { + return TypeSize(ExactSize, false); + } + static constexpr TypeSize Scalable(ScalarTy MinimumSize) { + return TypeSize(MinimumSize, true); } constexpr ScalarTy getFixedSize() const { return getFixedValue(); } @@ -512,7 +393,7 @@ class TypeSize : public LinearPolySize { //===----------------------------------------------------------------------===// /// Returns a TypeSize with a known minimum size that is the next integer -/// (mod 2**64) that is greater than or equal to \p Value and is a multiple +/// (mod 2**64) that is greater than or equal to \p Quantity and is a multiple /// of \p Align. \p Align must be non-zero. /// /// Similar to the alignTo functions in MathExtras.h @@ -522,10 +403,11 @@ inline constexpr TypeSize alignTo(TypeSize Size, uint64_t Align) { Size.isScalable()}; } -/// Stream operator function for `LinearPolySize`. -template -inline raw_ostream &operator<<(raw_ostream &OS, - const LinearPolySize &PS) { +/// Stream operator function for `FixedOrScalableQuantity`. +template +inline raw_ostream & +operator<<(raw_ostream &OS, + const details::FixedOrScalableQuantity &PS) { PS.print(OS); return OS; } @@ -544,7 +426,6 @@ template <> struct DenseMapInfo { return HashVal; } - static bool isEqual(const ElementCount &LHS, const ElementCount &RHS) { return LHS == RHS; } diff --git a/llvm/lib/IR/StructuralHash.cpp b/llvm/lib/IR/StructuralHash.cpp index 5a6e0745132680..b6b9fe72cc355b 100644 --- a/llvm/lib/IR/StructuralHash.cpp +++ b/llvm/lib/IR/StructuralHash.cpp @@ -15,7 +15,6 @@ using namespace llvm; -namespace { namespace details { // Basic hashing mechanism to detect structural change to the IR, used to verify @@ -67,16 +66,14 @@ class StructuralHash { } // namespace details -} // namespace - uint64_t llvm::StructuralHash(const Function &F) { - details::StructuralHash H; + ::details::StructuralHash H; H.update(F); return H.getHash(); } uint64_t llvm::StructuralHash(const Module &M) { - details::StructuralHash H; + ::details::StructuralHash H; H.update(M); return H.getHash(); } diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt index 91c6c987487061..ccffb42e267ebe 100644 --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -51,7 +51,6 @@ add_llvm_unittest(SupportTests JSONTest.cpp KnownBitsTest.cpp LEB128Test.cpp - LinearPolyBaseTest.cpp LineIteratorTest.cpp LockFileManagerTest.cpp MatchersTest.cpp diff --git a/llvm/unittests/Support/LinearPolyBaseTest.cpp b/llvm/unittests/Support/LinearPolyBaseTest.cpp deleted file mode 100644 index 15b366210bca45..00000000000000 --- a/llvm/unittests/Support/LinearPolyBaseTest.cpp +++ /dev/null @@ -1,176 +0,0 @@ -//===- TestPoly3D.cpp - Poly3D unit tests------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/TypeSize.h" -#include "gtest/gtest.h" - -using namespace llvm; - -class Poly3D; - -namespace llvm { -template <> struct LinearPolyBaseTypeTraits { - using ScalarTy = int64_t; - static const unsigned Dimensions = 3; -}; -} - -using Poly3DBase = LinearPolyBase; -class Poly3D : public Poly3DBase { -public: - using ScalarTy = Poly3DBase::ScalarTy; - Poly3D(ScalarTy x, ScalarTy y, ScalarTy z) : Poly3DBase({x, y, z}) {} - Poly3D(const Poly3DBase &Convert) : Poly3DBase(Convert) {} -}; - -TEST(LinearPolyBase, Poly3D_isZero) { - EXPECT_TRUE(Poly3D(0, 0, 0).isZero()); - EXPECT_TRUE(Poly3D(0, 0, 1).isNonZero()); - EXPECT_TRUE(Poly3D(0, 0, 1)); -} - -TEST(LinearPolyBase, Poly3D_Equality) { - EXPECT_EQ(Poly3D(1, 2, 3), Poly3D(1, 2, 3)); - EXPECT_NE(Poly3D(1, 2, 3), Poly3D(1, 2, 4)); -} - -TEST(LinearPolyBase, Poly3D_GetValue) { - EXPECT_EQ(Poly3D(1, 2, 3).getValue(0), 1); - EXPECT_EQ(Poly3D(1, 2, 3).getValue(1), 2); - EXPECT_EQ(Poly3D(1, 2, 3).getValue(2), 3); -} - -TEST(LinearPolyBase, Poly3D_Add) { - // Test operator+ - EXPECT_EQ(Poly3D(42, 0, 0) + Poly3D(0, 42, 0) + Poly3D(0, 0, 42), - Poly3D(42, 42, 42)); - - // Test operator+= - Poly3D X(42, 0, 0); - X += Poly3D(0, 42, 0); - X += Poly3D(0, 0, 42); - EXPECT_EQ(X, Poly3D(42, 42, 42)); -} - -TEST(LinearPolyBase, Poly3D_Sub) { - // Test operator- - EXPECT_EQ(Poly3D(42, 42, 42) - Poly3D(42, 0, 0) - Poly3D(0, 42, 0) - - Poly3D(0, 0, 42), - Poly3D(0, 0, 0)); - - // Test operator-= - Poly3D X(42, 42, 42); - X -= Poly3D(42, 0, 0); - X -= Poly3D(0, 42, 0); - X -= Poly3D(0, 0, 42); - EXPECT_EQ(X, Poly3D(0, 0, 0)); -} - -TEST(LinearPolyBase, Poly3D_Scale) { - // Test operator* - EXPECT_EQ(Poly3D(1, 2, 4) * 2, Poly3D(2, 4, 8)); - EXPECT_EQ(Poly3D(1, 2, 4) * -2, Poly3D(-2, -4, -8)); -} - -TEST(LinearPolyBase, Poly3D_Invert) { - // Test operator- - EXPECT_EQ(-Poly3D(2, 4, 8), Poly3D(-2, -4, -8)); -} - -class Univariate3D; -namespace llvm { -template <> struct LinearPolyBaseTypeTraits { - using ScalarTy = int64_t; - static const unsigned Dimensions = 3; -}; -} - -using Univariate3DBase = UnivariateLinearPolyBase; -class Univariate3D : public Univariate3DBase { -public: - using ScalarTy = Univariate3DBase::ScalarTy; - constexpr Univariate3D(ScalarTy x, unsigned Dim) : Univariate3DBase(x, Dim) {} - Univariate3D(const Univariate3DBase &Convert) : Univariate3DBase(Convert) {} -}; - -TEST(UnivariateLinearPolyBase, Univariate3D_isZero) { - EXPECT_TRUE(Univariate3D(0, 0).isZero()); - EXPECT_TRUE(Univariate3D(0, 1).isZero()); - EXPECT_TRUE(Univariate3D(0, 2).isZero()); - EXPECT_TRUE(Univariate3D(1, 0).isNonZero()); - EXPECT_TRUE(Univariate3D(1, 1).isNonZero()); - EXPECT_TRUE(Univariate3D(1, 2).isNonZero()); - EXPECT_TRUE(Univariate3D(1, 0)); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_Equality) { - EXPECT_EQ(Univariate3D(1, 0), Univariate3D(1, 0)); - EXPECT_NE(Univariate3D(1, 0), Univariate3D(1, 2)); - EXPECT_NE(Univariate3D(1, 0), Univariate3D(1, 1)); - EXPECT_NE(Univariate3D(1, 0), Univariate3D(2, 0)); - EXPECT_NE(Univariate3D(1, 0), Univariate3D(0, 0)); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_GetValue) { - EXPECT_EQ(Univariate3D(42, 0).getValue(0), 42); - EXPECT_EQ(Univariate3D(42, 0).getValue(1), 0); - EXPECT_EQ(Univariate3D(42, 0).getValue(2), 0); - - EXPECT_EQ(Univariate3D(42, 1).getValue(0), 0); - EXPECT_EQ(Univariate3D(42, 1).getValue(1), 42); - EXPECT_EQ(Univariate3D(42, 1).getValue(2), 0); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_Add) { - // Test operator+ - EXPECT_EQ(Univariate3D(42, 0) + Univariate3D(42, 0), Univariate3D(84, 0)); - EXPECT_EQ(Univariate3D(42, 1) + Univariate3D(42, 1), Univariate3D(84, 1)); - EXPECT_DEBUG_DEATH(Univariate3D(42, 0) + Univariate3D(42, 1), - "Invalid dimensions"); - - // Test operator+= - Univariate3D X(42, 0); - X += Univariate3D(42, 0); - EXPECT_EQ(X, Univariate3D(84, 0)); - - // Test 'getWithIncrement' method - EXPECT_EQ(Univariate3D(42, 0).getWithIncrement(1), Univariate3D(43, 0)); - EXPECT_EQ(Univariate3D(42, 1).getWithIncrement(2), Univariate3D(44, 1)); - EXPECT_EQ(Univariate3D(42, 2).getWithIncrement(3), Univariate3D(45, 2)); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_Sub) { - // Test operator+ - EXPECT_EQ(Univariate3D(84, 0) - Univariate3D(42, 0), Univariate3D(42, 0)); - EXPECT_EQ(Univariate3D(84, 1) - Univariate3D(42, 1), Univariate3D(42, 1)); - EXPECT_DEBUG_DEATH(Univariate3D(84, 0) - Univariate3D(42, 1), - "Invalid dimensions"); - - // Test operator+= - Univariate3D X(84, 0); - X -= Univariate3D(42, 0); - EXPECT_EQ(X, Univariate3D(42, 0)); - - // Test 'getWithDecrement' method - EXPECT_EQ(Univariate3D(43, 0).getWithDecrement(1), Univariate3D(42, 0)); - EXPECT_EQ(Univariate3D(44, 1).getWithDecrement(2), Univariate3D(42, 1)); - EXPECT_EQ(Univariate3D(45, 2).getWithDecrement(3), Univariate3D(42, 2)); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_Scale) { - // Test operator* - EXPECT_EQ(Univariate3D(4, 0) * 2, Univariate3D(8, 0)); - EXPECT_EQ(Univariate3D(4, 1) * -2, Univariate3D(-8, 1)); -} - -TEST(UnivariateLinearPolyBase, Univariate3D_Invert) { - // Test operator- - EXPECT_EQ(-Univariate3D(4, 0), Univariate3D(-4, 0)); - EXPECT_EQ(-Univariate3D(4, 1), Univariate3D(-4, 1)); -} - diff --git a/llvm/unittests/Support/TypeSizeTest.cpp b/llvm/unittests/Support/TypeSizeTest.cpp index 3552c7949a9a0f..6e566be3758172 100644 --- a/llvm/unittests/Support/TypeSizeTest.cpp +++ b/llvm/unittests/Support/TypeSizeTest.cpp @@ -35,7 +35,7 @@ static_assert(!CEElementCountFixed3.isScalable()); constexpr ElementCount CEElementCountScalable4 = ElementCount::getScalable(4); static_assert(CEElementCountScalable4.isScalable()); -static_assert(!ElementCount::getNull().isScalable()); +static_assert(!ElementCount().isScalable()); static_assert( CEElementCountScalable4.hasKnownScalarFactor(ElementCount::getScalable(2))); static_assert(ElementCount::getScalable(8).getKnownScalarFactor( diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index 8c1b0997d86989..bbe04fc769f3df 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -740,7 +740,7 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) { auto NoLength = [](const SmallDenseSet &Lengths, MVT T) -> bool { return !Lengths.count(T.isVector() ? T.getVectorElementCount() - : ElementCount::getNull()); + : ElementCount()); }; SmallVector Modes; @@ -751,11 +751,9 @@ bool TypeInfer::EnforceSameNumElts(TypeSetByHwMode &V, TypeSetByHwMode &W) { SmallDenseSet VN, WN; for (MVT T : VS) - VN.insert(T.isVector() ? T.getVectorElementCount() - : ElementCount::getNull()); + VN.insert(T.isVector() ? T.getVectorElementCount() : ElementCount()); for (MVT T : WS) - WN.insert(T.isVector() ? T.getVectorElementCount() - : ElementCount::getNull()); + WN.insert(T.isVector() ? T.getVectorElementCount() : ElementCount()); Changed |= berase_if(VS, std::bind(NoLength, WN, std::placeholders::_1)); Changed |= berase_if(WS, std::bind(NoLength, VN, std::placeholders::_1));