[llvm] Add enum iteration to Sequence

This patch allows iterating typed enum via the ADT/Sequence utility.

Differential Revision: https://reviews.llvm.org/D103900
This commit is contained in:
Guillaume Chatelet 2021-07-13 16:22:19 +00:00
parent 7039dfc6dd
commit a006af5d6e
9 changed files with 256 additions and 127 deletions

View File

@ -15,46 +15,29 @@
#ifndef LLVM_ADT_SEQUENCE_H #ifndef LLVM_ADT_SEQUENCE_H
#define LLVM_ADT_SEQUENCE_H #define LLVM_ADT_SEQUENCE_H
#include <cstddef> //std::ptrdiff_t #include <cassert> // assert
#include <iterator> //std::random_access_iterator_tag #include <cstddef> // std::ptrdiff_t
#include <iterator> // std::random_access_iterator_tag
#include <limits> // std::numeric_limits
#include <type_traits> // std::underlying_type, std::is_enum
namespace llvm { namespace llvm {
namespace detail { namespace detail {
template <typename T, bool IsReversed> struct iota_range_iterator { template <typename T, typename U, bool IsReversed> struct iota_range_iterator {
using iterator_category = std::random_access_iterator_tag; using iterator_category = std::random_access_iterator_tag;
using value_type = T; using value_type = T;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using pointer = T *; using pointer = T *;
using reference = T &; using reference = T &;
private:
struct Forward {
static void increment(T &V) { ++V; }
static void decrement(T &V) { --V; }
static void offset(T &V, difference_type Offset) { V += Offset; }
static T add(const T &V, difference_type Offset) { return V + Offset; }
static difference_type difference(const T &A, const T &B) { return A - B; }
};
struct Reverse {
static void increment(T &V) { --V; }
static void decrement(T &V) { ++V; }
static void offset(T &V, difference_type Offset) { V -= Offset; }
static T add(const T &V, difference_type Offset) { return V - Offset; }
static difference_type difference(const T &A, const T &B) { return B - A; }
};
using Op = std::conditional_t<!IsReversed, Forward, Reverse>;
public:
// default-constructible // default-constructible
iota_range_iterator() = default; iota_range_iterator() = default;
// copy-constructible // copy-constructible
iota_range_iterator(const iota_range_iterator &) = default; iota_range_iterator(const iota_range_iterator &) = default;
// value constructor // value constructor
explicit iota_range_iterator(T Value) : Value(Value) {} explicit iota_range_iterator(U Value) : Value(Value) {}
// copy-assignable // copy-assignable
iota_range_iterator &operator=(const iota_range_iterator &) = default; iota_range_iterator &operator=(const iota_range_iterator &) = default;
// destructible // destructible
@ -83,8 +66,10 @@ public:
} }
// Dereference // Dereference
T operator*() const { return Value; } T operator*() const { return static_cast<T>(Value); }
T operator[](difference_type Offset) const { return Op::add(Value, Offset); } T operator[](difference_type Offset) const {
return static_cast<T>(Op::add(Value, Offset));
}
// Arithmetic // Arithmetic
iota_range_iterator operator+(difference_type Offset) const { iota_range_iterator operator+(difference_type Offset) const {
@ -132,46 +117,116 @@ public:
} }
private: private:
T Value; struct Forward {
static void increment(U &V) { ++V; }
static void decrement(U &V) { --V; }
static void offset(U &V, difference_type Offset) { V += Offset; }
static U add(const U &V, difference_type Offset) { return V + Offset; }
static difference_type difference(const U &A, const U &B) {
return difference_type(A) - difference_type(B);
}
};
struct Reverse {
static void increment(U &V) { --V; }
static void decrement(U &V) { ++V; }
static void offset(U &V, difference_type Offset) { V -= Offset; }
static U add(const U &V, difference_type Offset) { return V - Offset; }
static difference_type difference(const U &A, const U &B) {
return difference_type(B) - difference_type(A);
}
};
using Op = std::conditional_t<!IsReversed, Forward, Reverse>;
U Value;
}; };
// Providing std::type_identity for C++14.
template <class T> struct type_identity { using type = T; };
} // namespace detail } // namespace detail
template <typename ValueT> struct iota_range { template <typename T> struct iota_range {
static_assert(std::is_integral<ValueT>::value, private:
"ValueT must be an integral type"); using underlying_type =
typename std::conditional_t<std::is_enum<T>::value,
std::underlying_type<T>,
detail::type_identity<T>>::type;
using numeric_type =
typename std::conditional_t<std::is_signed<underlying_type>::value,
intmax_t, uintmax_t>;
using value_type = ValueT; static numeric_type compute_past_end(numeric_type End, bool Inclusive) {
using reference = ValueT &; if (Inclusive) {
using const_reference = const ValueT &; // This assertion forbids overflow of `PastEndValue`.
using iterator = detail::iota_range_iterator<value_type, false>; assert(End != std::numeric_limits<numeric_type>::max() &&
"Forbidden End value for seq_inclusive.");
return End + 1;
}
return End;
}
static numeric_type raw(T Value) { return static_cast<numeric_type>(Value); }
numeric_type BeginValue;
numeric_type PastEndValue;
public:
using value_type = T;
using reference = T &;
using const_reference = const T &;
using iterator = detail::iota_range_iterator<value_type, numeric_type, false>;
using const_iterator = iterator; using const_iterator = iterator;
using reverse_iterator = detail::iota_range_iterator<value_type, true>; using reverse_iterator =
detail::iota_range_iterator<value_type, numeric_type, true>;
using const_reverse_iterator = reverse_iterator; using const_reverse_iterator = reverse_iterator;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using size_type = std::size_t; using size_type = std::size_t;
value_type Begin; explicit iota_range(T Begin, T End, bool Inclusive)
value_type End; : BeginValue(raw(Begin)),
PastEndValue(compute_past_end(raw(End), Inclusive)) {
assert(Begin <= End && "Begin must be less or equal to End.");
}
explicit iota_range(ValueT Begin, ValueT End) : Begin(Begin), End(End) {} size_t size() const { return PastEndValue - BeginValue; }
bool empty() const { return BeginValue == PastEndValue; }
size_t size() const { return End - Begin; } auto begin() const { return const_iterator(BeginValue); }
bool empty() const { return Begin == End; } auto end() const { return const_iterator(PastEndValue); }
auto begin() const { return const_iterator(Begin); } auto rbegin() const { return const_reverse_iterator(PastEndValue - 1); }
auto end() const { return const_iterator(End); } auto rend() const {
assert(std::is_unsigned<numeric_type>::value ||
auto rbegin() const { return const_reverse_iterator(End - 1); } BeginValue != std::numeric_limits<numeric_type>::min() &&
auto rend() const { return const_reverse_iterator(Begin - 1); } "Forbidden Begin value for reverse iteration");
return const_reverse_iterator(BeginValue - 1);
}
private: private:
static_assert(std::is_same<ValueT, std::remove_cv_t<ValueT>>::value, static_assert(std::is_integral<T>::value || std::is_enum<T>::value,
"ValueT must not be const nor volatile"); "T must be an integral or enum type");
static_assert(std::is_same<T, std::remove_cv_t<T>>::value,
"T must not be const nor volatile");
static_assert(std::is_integral<numeric_type>::value,
"numeric_type must be an integral type");
}; };
template <typename ValueT> auto seq(ValueT Begin, ValueT End) { /// Iterate over an integral/enum type from Begin up to - but not including -
return iota_range<ValueT>(Begin, End); /// End.
/// Note on enum iteration: `seq` will generate each consecutive value, even if
/// no enumerator with that value exists.
template <typename T> auto seq(T Begin, T End) {
return iota_range<T>(Begin, End, false);
}
/// Iterate over an integral/enum type from Begin to End inclusive.
/// Note on enum iteration: `seq_inclusive` will generate each consecutive
/// value, even if no enumerator with that value exists.
/// To prevent overflow, `End` must be different from INTMAX_MAX if T is signed
/// (resp. UINTMAX_MAX if T is unsigned).
template <typename T> auto seq_inclusive(T Begin, T End) {
return iota_range<T>(Begin, End, true);
} }
} // end namespace llvm } // end namespace llvm

View File

@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_MACHINEVALUETYPE_H #ifndef LLVM_SUPPORT_MACHINEVALUETYPE_H
#define LLVM_SUPPORT_MACHINEVALUETYPE_H #define LLVM_SUPPORT_MACHINEVALUETYPE_H
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
@ -1398,84 +1399,55 @@ namespace llvm {
/// returned as Other, otherwise they are invalid. /// returned as Other, otherwise they are invalid.
static MVT getVT(Type *Ty, bool HandleUnknown = false); static MVT getVT(Type *Ty, bool HandleUnknown = false);
private:
/// A simple iterator over the MVT::SimpleValueType enum.
struct mvt_iterator {
SimpleValueType VT;
mvt_iterator(SimpleValueType VT) : VT(VT) {}
MVT operator*() const { return VT; }
bool operator!=(const mvt_iterator &LHS) const { return VT != LHS.VT; }
mvt_iterator& operator++() {
VT = (MVT::SimpleValueType)((int)VT + 1);
assert((int)VT <= MVT::MAX_ALLOWED_VALUETYPE &&
"MVT iterator overflowed.");
return *this;
}
};
/// A range of the MVT::SimpleValueType enum.
using mvt_range = iterator_range<mvt_iterator>;
public: public:
/// SimpleValueType Iteration /// SimpleValueType Iteration
/// @{ /// @{
static mvt_range all_valuetypes() { static auto all_valuetypes() {
return mvt_range(MVT::FIRST_VALUETYPE, return seq_inclusive(MVT::FIRST_VALUETYPE, MVT::LAST_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_VALUETYPE + 1));
} }
static mvt_range integer_valuetypes() { static auto integer_valuetypes() {
return mvt_range(MVT::FIRST_INTEGER_VALUETYPE, return seq_inclusive(MVT::FIRST_INTEGER_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_INTEGER_VALUETYPE + 1)); MVT::LAST_INTEGER_VALUETYPE);
} }
static mvt_range fp_valuetypes() { static auto fp_valuetypes() {
return mvt_range(MVT::FIRST_FP_VALUETYPE, return seq_inclusive(MVT::FIRST_FP_VALUETYPE, MVT::LAST_FP_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_FP_VALUETYPE + 1));
} }
static mvt_range vector_valuetypes() { static auto vector_valuetypes() {
return mvt_range(MVT::FIRST_VECTOR_VALUETYPE, return seq_inclusive(MVT::FIRST_VECTOR_VALUETYPE,
(MVT::SimpleValueType)(MVT::LAST_VECTOR_VALUETYPE + 1)); MVT::LAST_VECTOR_VALUETYPE);
} }
static mvt_range fixedlen_vector_valuetypes() { static auto fixedlen_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE,
MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE, MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE + 1));
} }
static mvt_range scalable_vector_valuetypes() { static auto scalable_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_SCALABLE_VECTOR_VALUETYPE,
MVT::FIRST_SCALABLE_VECTOR_VALUETYPE, MVT::LAST_SCALABLE_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_SCALABLE_VECTOR_VALUETYPE + 1));
} }
static mvt_range integer_fixedlen_vector_valuetypes() { static auto integer_fixedlen_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE,
MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE, MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE + 1));
} }
static mvt_range fp_fixedlen_vector_valuetypes() { static auto fp_fixedlen_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE,
MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE, MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE + 1));
} }
static mvt_range integer_scalable_vector_valuetypes() { static auto integer_scalable_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE,
MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE, MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE + 1));
} }
static mvt_range fp_scalable_vector_valuetypes() { static auto fp_scalable_vector_valuetypes() {
return mvt_range( return seq_inclusive(MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE,
MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE, MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE);
(MVT::SimpleValueType)(MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE + 1));
} }
/// @} /// @}
}; };

View File

@ -4634,8 +4634,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) {
EVT InVT = InOp.getValueType(); EVT InVT = InOp.getValueType();
if (InVT.getSizeInBits() != VT.getSizeInBits()) { if (InVT.getSizeInBits() != VT.getSizeInBits()) {
EVT InEltVT = InVT.getVectorElementType(); EVT InEltVT = InVT.getVectorElementType();
for (int i = MVT::FIRST_VECTOR_VALUETYPE, e = MVT::LAST_VECTOR_VALUETYPE; i < e; ++i) { for (EVT FixedVT : MVT::vector_valuetypes()) {
EVT FixedVT = (MVT::SimpleValueType)i;
EVT FixedEltVT = FixedVT.getVectorElementType(); EVT FixedEltVT = FixedVT.getVectorElementType();
if (TLI.isTypeLegal(FixedVT) && if (TLI.isTypeLegal(FixedVT) &&
FixedVT.getSizeInBits() == VT.getSizeInBits() && FixedVT.getSizeInBits() == VT.getSizeInBits() &&
@ -5162,14 +5161,11 @@ static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
if (!Scalable && Width == WidenEltWidth) if (!Scalable && Width == WidenEltWidth)
return RetVT; return RetVT;
// See if there is larger legal integer than the element type to load/store.
unsigned VT;
// Don't bother looking for an integer type if the vector is scalable, skip // Don't bother looking for an integer type if the vector is scalable, skip
// to vector types. // to vector types.
if (!Scalable) { if (!Scalable) {
for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE; // See if there is larger legal integer than the element type to load/store.
VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) { for (EVT MemVT : reverse(MVT::integer_valuetypes())) {
EVT MemVT((MVT::SimpleValueType) VT);
unsigned MemVTWidth = MemVT.getSizeInBits(); unsigned MemVTWidth = MemVT.getSizeInBits();
if (MemVT.getSizeInBits() <= WidenEltWidth) if (MemVT.getSizeInBits() <= WidenEltWidth)
break; break;
@ -5190,9 +5186,7 @@ static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
// See if there is a larger vector type to load/store that has the same vector // See if there is a larger vector type to load/store that has the same vector
// element type and is evenly divisible with the WidenVT. // element type and is evenly divisible with the WidenVT.
for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; for (EVT MemVT : reverse(MVT::vector_valuetypes())) {
VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) {
EVT MemVT = (MVT::SimpleValueType) VT;
// Skip vector MVTs which don't match the scalable property of WidenVT. // Skip vector MVTs which don't match the scalable property of WidenVT.
if (Scalable != MemVT.isScalableVector()) if (Scalable != MemVT.isScalableVector())
continue; continue;

View File

@ -918,9 +918,9 @@ std::vector<InstructionTemplate> ExegesisX86Target::generateInstructionVariants(
continue; continue;
case X86::OperandType::OPERAND_COND_CODE: { case X86::OperandType::OPERAND_COND_CODE: {
Exploration = true; Exploration = true;
auto CondCodes = seq((int)X86::CondCode::COND_O, auto CondCodes =
1 + (int)X86::CondCode::LAST_VALID_COND); seq_inclusive(X86::CondCode::COND_O, X86::CondCode::LAST_VALID_COND);
Choices.reserve(std::distance(CondCodes.begin(), CondCodes.end())); Choices.reserve(CondCodes.size());
for (int CondCode : CondCodes) for (int CondCode : CondCodes)
Choices.emplace_back(MCOperand::createImm(CondCode)); Choices.emplace_back(MCOperand::createImm(CondCode));
break; break;

View File

@ -84,7 +84,8 @@ public:
AttrPtrVecVecTy &AttributeSetsToPreserve) { AttrPtrVecVecTy &AttributeSetsToPreserve) {
assert(AttributeSetsToPreserve.empty() && "Should not be sharing vectors."); assert(AttributeSetsToPreserve.empty() && "Should not be sharing vectors.");
AttributeSetsToPreserve.reserve(AL.getNumAttrSets()); AttributeSetsToPreserve.reserve(AL.getNumAttrSets());
for (unsigned SetIdx : seq(AL.index_begin(), AL.index_end())) { for (unsigned SetIdx = AL.index_begin(), SetEndIdx = AL.index_end();
SetIdx != SetEndIdx; ++SetIdx) {
AttrPtrIdxVecVecTy AttributesToPreserve; AttrPtrIdxVecVecTy AttributesToPreserve;
AttributesToPreserve.first = SetIdx; AttributesToPreserve.first = SetIdx;
visitAttributeSet(AL.getAttributes(AttributesToPreserve.first), visitAttributeSet(AL.getAttributes(AttributesToPreserve.first),

View File

@ -7,12 +7,15 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ADT/Sequence.h" #include "llvm/ADT/Sequence.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <list> #include <list>
using namespace llvm; using namespace llvm;
using testing::ElementsAre;
namespace { namespace {
TEST(SequenceTest, Forward) { TEST(SequenceTest, Forward) {
@ -48,4 +51,108 @@ TEST(SequenceTest, Dereference) {
EXPECT_EQ(Backward[2], 7); EXPECT_EQ(Backward[2], 7);
} }
enum class CharEnum : char { A = 1, B, C, D, E };
TEST(SequenceTest, ForwardIteration) {
EXPECT_THAT(seq_inclusive(CharEnum::C, CharEnum::E),
ElementsAre(CharEnum::C, CharEnum::D, CharEnum::E));
}
TEST(SequenceTest, BackwardIteration) {
EXPECT_THAT(reverse(seq_inclusive(CharEnum::B, CharEnum::D)),
ElementsAre(CharEnum::D, CharEnum::C, CharEnum::B));
}
using IntegralTypes =
testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, uintmax_t, //
int8_t, int16_t, int32_t, int64_t, intmax_t>;
template <class T> class SequenceTest : public testing::Test {
public:
const T min = std::numeric_limits<T>::min();
const T minp1 = min + 1;
const T max = std::numeric_limits<T>::max();
const T maxm1 = max - 1;
void checkIteration() const {
// Forward
EXPECT_THAT(seq(min, min), ElementsAre());
EXPECT_THAT(seq(min, minp1), ElementsAre(min));
EXPECT_THAT(seq(maxm1, max), ElementsAre(maxm1));
EXPECT_THAT(seq(max, max), ElementsAre());
// Reverse
if (!std::is_same<T, intmax_t>::value) {
EXPECT_THAT(reverse(seq(min, min)), ElementsAre());
EXPECT_THAT(reverse(seq(min, minp1)), ElementsAre(min));
}
EXPECT_THAT(reverse(seq(maxm1, max)), ElementsAre(maxm1));
EXPECT_THAT(reverse(seq(max, max)), ElementsAre());
// Inclusive
EXPECT_THAT(seq_inclusive(min, min), ElementsAre(min));
EXPECT_THAT(seq_inclusive(min, minp1), ElementsAre(min, minp1));
EXPECT_THAT(seq_inclusive(maxm1, maxm1), ElementsAre(maxm1));
// Inclusive Reverse
if (!std::is_same<T, intmax_t>::value) {
EXPECT_THAT(reverse(seq_inclusive(min, min)), ElementsAre(min));
EXPECT_THAT(reverse(seq_inclusive(min, minp1)), ElementsAre(minp1, min));
}
EXPECT_THAT(reverse(seq_inclusive(maxm1, maxm1)), ElementsAre(maxm1));
}
void checkIterators() const {
auto checkValidIterators = [](auto sequence) {
EXPECT_LE(sequence.begin(), sequence.end());
};
checkValidIterators(seq(min, min));
checkValidIterators(seq(max, max));
checkValidIterators(seq_inclusive(min, min));
checkValidIterators(seq_inclusive(maxm1, maxm1));
}
};
TYPED_TEST_SUITE(SequenceTest, IntegralTypes);
TYPED_TEST(SequenceTest, Boundaries) {
this->checkIteration();
this->checkIterators();
}
#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
template <class T> class SequenceDeathTest : public SequenceTest<T> {
public:
using SequenceTest<T>::min;
using SequenceTest<T>::minp1;
using SequenceTest<T>::max;
using SequenceTest<T>::maxm1;
void checkInvalidOrder() const {
EXPECT_DEATH(seq(max, min), "Begin must be less or equal to End.");
EXPECT_DEATH(seq(minp1, min), "Begin must be less or equal to End.");
EXPECT_DEATH(seq_inclusive(maxm1, min),
"Begin must be less or equal to End.");
EXPECT_DEATH(seq_inclusive(minp1, min),
"Begin must be less or equal to End.");
}
void checkInvalidValues() const {
if (std::is_same<T, intmax_t>::value || std::is_same<T, uintmax_t>::value) {
EXPECT_DEATH(seq_inclusive(min, max),
"Forbidden End value for seq_inclusive.");
EXPECT_DEATH(seq_inclusive(minp1, max),
"Forbidden End value for seq_inclusive.");
}
if (std::is_same<T, intmax_t>::value) {
EXPECT_DEATH(reverse(seq(min, min)),
"Forbidden Begin value for reverse iteration");
EXPECT_DEATH(reverse(seq_inclusive(min, min)),
"Forbidden Begin value for reverse iteration");
// Note it is fine to use `Begin == 0` when `iota_range::numeric_type ==
// uintmax_t` as unsigned integer underflow is well-defined.
}
}
};
TYPED_TEST_SUITE(SequenceDeathTest, IntegralTypes);
TYPED_TEST(SequenceDeathTest, DeathTests) {
this->checkInvalidOrder();
this->checkInvalidValues();
}
#endif // defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
} // anonymous namespace } // anonymous namespace

View File

@ -18,7 +18,7 @@ using namespace llvm;
namespace { namespace {
TEST(ScalableVectorMVTsTest, IntegerMVTs) { TEST(ScalableVectorMVTsTest, IntegerMVTs) {
for (auto VecTy : MVT::integer_scalable_vector_valuetypes()) { for (MVT VecTy : MVT::integer_scalable_vector_valuetypes()) {
ASSERT_TRUE(VecTy.isValid()); ASSERT_TRUE(VecTy.isValid());
ASSERT_TRUE(VecTy.isInteger()); ASSERT_TRUE(VecTy.isInteger());
ASSERT_TRUE(VecTy.isVector()); ASSERT_TRUE(VecTy.isVector());
@ -30,7 +30,7 @@ TEST(ScalableVectorMVTsTest, IntegerMVTs) {
} }
TEST(ScalableVectorMVTsTest, FloatMVTs) { TEST(ScalableVectorMVTsTest, FloatMVTs) {
for (auto VecTy : MVT::fp_scalable_vector_valuetypes()) { for (MVT VecTy : MVT::fp_scalable_vector_valuetypes()) {
ASSERT_TRUE(VecTy.isValid()); ASSERT_TRUE(VecTy.isValid());
ASSERT_TRUE(VecTy.isFloatingPoint()); ASSERT_TRUE(VecTy.isFloatingPoint());
ASSERT_TRUE(VecTy.isVector()); ASSERT_TRUE(VecTy.isVector());

View File

@ -1551,9 +1551,9 @@ void ICmpTestImpl(CmpInst::Predicate Pred) {
} }
TEST(ConstantRange, ICmp) { TEST(ConstantRange, ICmp) {
for (auto Pred : seq<unsigned>(CmpInst::Predicate::FIRST_ICMP_PREDICATE, for (auto Pred : seq_inclusive(CmpInst::Predicate::FIRST_ICMP_PREDICATE,
1 + CmpInst::Predicate::LAST_ICMP_PREDICATE)) CmpInst::Predicate::LAST_ICMP_PREDICATE))
ICmpTestImpl((CmpInst::Predicate)Pred); ICmpTestImpl(Pred);
} }
TEST(ConstantRange, MakeGuaranteedNoWrapRegion) { TEST(ConstantRange, MakeGuaranteedNoWrapRegion) {

View File

@ -1282,7 +1282,7 @@ getCollapsedOutputDimFromInputShape(OpBuilder &builder, Location loc,
unsigned endPos = map.getResults().back().cast<AffineDimExpr>().getPosition(); unsigned endPos = map.getResults().back().cast<AffineDimExpr>().getPosition();
AffineExpr expr; AffineExpr expr;
SmallVector<Value, 2> dynamicDims; SmallVector<Value, 2> dynamicDims;
for (auto dim : llvm::seq(startPos, endPos + 1)) { for (auto dim : llvm::seq_inclusive(startPos, endPos)) {
dynamicDims.push_back(builder.createOrFold<tensor::DimOp>(loc, src, dim)); dynamicDims.push_back(builder.createOrFold<tensor::DimOp>(loc, src, dim));
AffineExpr currExpr = builder.getAffineSymbolExpr(dim - startPos); AffineExpr currExpr = builder.getAffineSymbolExpr(dim - startPos);
expr = (expr ? expr * currExpr : currExpr); expr = (expr ? expr * currExpr : currExpr);
@ -1315,7 +1315,7 @@ getExpandedDimToCollapsedDimMap(ArrayRef<AffineMap> reassociation) {
map.value().getResults().front().cast<AffineDimExpr>().getPosition(); map.value().getResults().front().cast<AffineDimExpr>().getPosition();
unsigned endPos = unsigned endPos =
map.value().getResults().back().cast<AffineDimExpr>().getPosition(); map.value().getResults().back().cast<AffineDimExpr>().getPosition();
for (auto dim : llvm::seq(startPos, endPos + 1)) { for (auto dim : llvm::seq_inclusive(startPos, endPos)) {
expandedDimToCollapsedDim[dim] = map.index(); expandedDimToCollapsedDim[dim] = map.index();
} }
} }