diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -1,3 +1,6 @@ +set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/include/llvm/CodeGen/ValueTypes.td) +tablegen(LLVM GenVT.inc -gen-vt) + set(LLVM_LINK_COMPONENTS Support TargetParser @@ -53,6 +56,7 @@ LockFileManagerTest.cpp MatchersTest.cpp MD5Test.cpp + MVTTest.cpp ManagedStatic.cpp MathExtrasTest.cpp MemoryBufferRefTest.cpp @@ -101,6 +105,7 @@ raw_pwrite_stream_test.cpp raw_sha1_ostream_test.cpp xxhashTest.cpp + GenVT.inc ) target_link_libraries(SupportTests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/Support/MVTTest.cpp b/llvm/unittests/Support/MVTTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Support/MVTTest.cpp @@ -0,0 +1,106 @@ +//===- llvm/unittest/Support/MVTTest.cpp - Test compatibility -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Make sure the generated version of MachineValueType.h to be equivalent to +// the constant version of llvm/Support/MachineValueType.h. +// +//===----------------------------------------------------------------------===// + +#include "MachineValueType.h" +#include "llvm/Support/MachineValueType.h" +#include "gtest/gtest.h" +#include +#include + +using namespace llvm; + +namespace { + +TEST(MVTTest, Properties) { + for (int i = 0; i <= std::numeric_limits::max(); ++i) { + SCOPED_TRACE("i=" + std::to_string(i)); + auto Org = MVT(MVT::SimpleValueType(i)); + auto New = tmp::MVT(tmp::MVT::SimpleValueType(i)); + +#define MVTTEST_EXPECT_EQ_M(LHS, RHS, M) EXPECT_EQ((LHS).M(), (RHS).M()) +#define MVTTEST_EXPECT_EQ_SVT(LHS, RHS) \ + EXPECT_EQ(int((LHS).SimpleTy), int((RHS).SimpleTy)) +#define MVTTEST_EXPECT_EQ_SVT_M(LHS, RHS, M) \ + MVTTEST_EXPECT_EQ_SVT((LHS).M(), (RHS).M()) +#define MVTTEST_EXPECT_EQ_SVT_F(F, ...) \ + MVTTEST_EXPECT_EQ_SVT(MVT::F(__VA_ARGS__), tmp::MVT::F(__VA_ARGS__)) + + MVTTEST_EXPECT_EQ_M(New, Org, isValid); + MVTTEST_EXPECT_EQ_M(New, Org, isFloatingPoint); + MVTTEST_EXPECT_EQ_M(New, Org, isInteger); + MVTTEST_EXPECT_EQ_M(New, Org, isScalarInteger); + MVTTEST_EXPECT_EQ_M(New, Org, isVector); + MVTTEST_EXPECT_EQ_M(New, Org, isScalableVector); + MVTTEST_EXPECT_EQ_M(New, Org, isScalableTargetExtVT); + MVTTEST_EXPECT_EQ_M(New, Org, isScalableVT); + MVTTEST_EXPECT_EQ_M(New, Org, isFixedLengthVector); + MVTTEST_EXPECT_EQ_M(New, Org, is16BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is32BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is64BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is128BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is256BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is512BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is1024BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, is2048BitVector); + MVTTEST_EXPECT_EQ_M(New, Org, isOverloaded); + if (New.isVector()) { + MVTTEST_EXPECT_EQ_SVT_M(New, Org, changeVectorElementTypeToInteger); + MVTTEST_EXPECT_EQ_SVT_M(New, Org, changeTypeToInteger); + if (New.getVectorElementCount().isKnownEven()) { + MVTTEST_EXPECT_EQ_SVT_M(New, Org, getHalfNumVectorElementsVT); + } + MVTTEST_EXPECT_EQ_M(New, Org, isPow2VectorType); + MVTTEST_EXPECT_EQ_SVT_M(New, Org, getPow2VectorType); + MVTTEST_EXPECT_EQ_SVT_M(New, Org, getVectorElementType); + MVTTEST_EXPECT_EQ_M(New, Org, getVectorMinNumElements); + MVTTEST_EXPECT_EQ_M(New, Org, getVectorElementCount); + + auto n = New.getVectorMinNumElements(); + auto sc = New.isScalableVector(); + auto LHS = tmp::MVT::getVectorVT(New.getVectorElementType(), n, sc); + auto RHS = MVT::getVectorVT(Org.getVectorElementType(), n, sc); + MVTTEST_EXPECT_EQ_SVT(LHS, RHS); + } else if (New.isInteger()) { + auto bw = New.getSizeInBits(); + MVTTEST_EXPECT_EQ_SVT_F(getIntegerVT, bw); + } else if (New.isFloatingPoint()) { + auto bw = New.getSizeInBits(); + MVTTEST_EXPECT_EQ_SVT_F(getFloatingPointVT, bw); + } + MVTTEST_EXPECT_EQ_SVT_M(New, Org, getScalarType); + if (New.isValid()) { + switch (New.SimpleTy) { + case tmp::MVT::Other: + case tmp::MVT::Glue: + case tmp::MVT::isVoid: + case tmp::MVT::Untyped: + case tmp::MVT::spirvbuiltin: + break; + case tmp::MVT::aarch64svcount: + break; + default: + MVTTEST_EXPECT_EQ_M(New, Org, getSizeInBits); + MVTTEST_EXPECT_EQ_M(New, Org, getScalarSizeInBits); + MVTTEST_EXPECT_EQ_M(New, Org, getStoreSize); + MVTTEST_EXPECT_EQ_M(New, Org, getScalarStoreSize); + MVTTEST_EXPECT_EQ_M(New, Org, getStoreSizeInBits); + MVTTEST_EXPECT_EQ_M(New, Org, isByteSized); + if (!New.isScalableVector()) { + MVTTEST_EXPECT_EQ_M(New, Org, getFixedSizeInBits); + } + break; + } + } + } +} +} // namespace diff --git a/llvm/unittests/Support/MachineValueType.h b/llvm/unittests/Support/MachineValueType.h --- a/llvm/unittests/Support/MachineValueType.h +++ b/llvm/unittests/Support/MachineValueType.h @@ -1,4 +1,4 @@ -//===- Support/MachineValueType.h - Machine-Level types ---------*- C++ -*-===// +//===- MachineValueType.h - Machine-Level types -----------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,21 +9,24 @@ // This file defines the set of machine-level target independent types which // legal values in the code generator use. // +// Constants and properties are defined in ValueTypes.td. +// //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_MACHINEVALUETYPE_H -#define LLVM_SUPPORT_MACHINEVALUETYPE_H +#ifndef LLVM_TMP_MACHINEVALUETYPE_H +#define LLVM_TMP_MACHINEVALUETYPE_H #include "llvm/ADT/Sequence.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/TypeSize.h" #include +#include -namespace llvm { +namespace llvm::tmp { class Type; + class raw_ostream; /// Machine Value Type. Every type that is supported natively by some /// processor targeted by LLVM occurs here. This means that any legal value @@ -31,243 +34,34 @@ class MVT { public: enum SimpleValueType : uint8_t { - // clang-format off - // Simple value types that aren't explicitly part of this enumeration // are considered extended value types. INVALID_SIMPLE_VALUE_TYPE = 0, - // If you change this numbering, you must change the values in - // ValueTypes.td as well! - Other = 1, // This is a non-standard value - i1 = 2, // This is a 1 bit integer value - i2 = 3, // This is a 2 bit integer value - i4 = 4, // This is a 4 bit integer value - i8 = 5, // This is an 8 bit integer value - i16 = 6, // This is a 16 bit integer value - i32 = 7, // This is a 32 bit integer value - i64 = 8, // This is a 64 bit integer value - i128 = 9, // This is a 128 bit integer value +#define GET_VT_ATTR(Ty, n, sz) Ty = n, +#define GET_VT_RANGES +#include "GenVT.inc" +#undef GET_VT_ATTR +#undef GET_VT_RANGES FIRST_INTEGER_VALUETYPE = i1, LAST_INTEGER_VALUETYPE = i128, - bf16 = 10, // This is a 16 bit brain floating point value - f16 = 11, // This is a 16 bit floating point value - f32 = 12, // This is a 32 bit floating point value - f64 = 13, // This is a 64 bit floating point value - f80 = 14, // This is a 80 bit floating point value - f128 = 15, // This is a 128 bit floating point value - ppcf128 = 16, // This is a PPC 128-bit floating point value - FIRST_FP_VALUETYPE = bf16, LAST_FP_VALUETYPE = ppcf128, - v1i1 = 17, // 1 x i1 - v2i1 = 18, // 2 x i1 - v4i1 = 19, // 4 x i1 - v8i1 = 20, // 8 x i1 - v16i1 = 21, // 16 x i1 - v32i1 = 22, // 32 x i1 - v64i1 = 23, // 64 x i1 - v128i1 = 24, // 128 x i1 - v256i1 = 25, // 256 x i1 - v512i1 = 26, // 512 x i1 - v1024i1 = 27, // 1024 x i1 - v2048i1 = 28, // 2048 x i1 - - v128i2 = 29, // 128 x i2 - v256i2 = 30, // 256 x i2 - - v64i4 = 31, // 64 x i4 - v128i4 = 32, // 128 x i4 - - v1i8 = 33, // 1 x i8 - v2i8 = 34, // 2 x i8 - v4i8 = 35, // 4 x i8 - v8i8 = 36, // 8 x i8 - v16i8 = 37, // 16 x i8 - v32i8 = 38, // 32 x i8 - v64i8 = 39, // 64 x i8 - v128i8 = 40, // 128 x i8 - v256i8 = 41, // 256 x i8 - v512i8 = 42, // 512 x i8 - v1024i8 = 43, // 1024 x i8 - - v1i16 = 44, // 1 x i16 - v2i16 = 45, // 2 x i16 - v3i16 = 46, // 3 x i16 - v4i16 = 47, // 4 x i16 - v8i16 = 48, // 8 x i16 - v16i16 = 49, // 16 x i16 - v32i16 = 50, // 32 x i16 - v64i16 = 51, // 64 x i16 - v128i16 = 52, // 128 x i16 - v256i16 = 53, // 256 x i16 - v512i16 = 54, // 512 x i16 - - v1i32 = 55, // 1 x i32 - v2i32 = 56, // 2 x i32 - v3i32 = 57, // 3 x i32 - v4i32 = 58, // 4 x i32 - v5i32 = 59, // 5 x i32 - v6i32 = 60, // 6 x i32 - v7i32 = 61, // 7 x i32 - v8i32 = 62, // 8 x i32 - v9i32 = 63, // 9 x i32 - v10i32 = 64, // 10 x i32 - v11i32 = 65, // 11 x i32 - v12i32 = 66, // 12 x i32 - v16i32 = 67, // 16 x i32 - v32i32 = 68, // 32 x i32 - v64i32 = 69, // 64 x i32 - v128i32 = 70, // 128 x i32 - v256i32 = 71, // 256 x i32 - v512i32 = 72, // 512 x i32 - v1024i32 = 73, // 1024 x i32 - v2048i32 = 74, // 2048 x i32 - - v1i64 = 75, // 1 x i64 - v2i64 = 76, // 2 x i64 - v3i64 = 77, // 3 x i64 - v4i64 = 78, // 4 x i64 - v8i64 = 79, // 8 x i64 - v16i64 = 80, // 16 x i64 - v32i64 = 81, // 32 x i64 - v64i64 = 82, // 64 x i64 - v128i64 = 83, // 128 x i64 - v256i64 = 84, // 256 x i64 - - v1i128 = 85, // 1 x i128 - FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i1, LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i128, - v1f16 = 86, // 1 x f16 - v2f16 = 87, // 2 x f16 - v3f16 = 88, // 3 x f16 - v4f16 = 89, // 4 x f16 - v8f16 = 90, // 8 x f16 - v16f16 = 91, // 16 x f16 - v32f16 = 92, // 32 x f16 - v64f16 = 93, // 64 x f16 - v128f16 = 94, // 128 x f16 - v256f16 = 95, // 256 x f16 - v512f16 = 96, // 512 x f16 - - v2bf16 = 97, // 2 x bf16 - v3bf16 = 98, // 3 x bf16 - v4bf16 = 99, // 4 x bf16 - v8bf16 = 100, // 8 x bf16 - v16bf16 = 101, // 16 x bf16 - v32bf16 = 102, // 32 x bf16 - v64bf16 = 103, // 64 x bf16 - v128bf16 = 104, // 128 x bf16 - - v1f32 = 105, // 1 x f32 - v2f32 = 106, // 2 x f32 - v3f32 = 107, // 3 x f32 - v4f32 = 108, // 4 x f32 - v5f32 = 109, // 5 x f32 - v6f32 = 110, // 6 x f32 - v7f32 = 111, // 7 x f32 - v8f32 = 112, // 8 x f32 - v9f32 = 113, // 9 x f32 - v10f32 = 114, // 10 x f32 - v11f32 = 115, // 11 x f32 - v12f32 = 116, // 12 x f32 - v16f32 = 117, // 16 x f32 - - v32f32 = 118, // 32 x f32 - v64f32 = 119, // 64 x f32 - v128f32 = 120, // 128 x f32 - v256f32 = 121, // 256 x f32 - v512f32 = 122, // 512 x f32 - v1024f32 = 123, // 1024 x f32 - v2048f32 = 124, // 2048 x f32 - - v1f64 = 125, // 1 x f64 - v2f64 = 126, // 2 x f64 - v3f64 = 127, // 3 x f64 - v4f64 = 128, // 4 x f64 - v8f64 = 129, // 8 x f64 - v16f64 = 130, // 16 x f64 - v32f64 = 131, // 32 x f64 - v64f64 = 132, // 64 x f64 - v128f64 = 133, // 128 x f64 - v256f64 = 134, // 256 x f64 - FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE = v1f16, LAST_FP_FIXEDLEN_VECTOR_VALUETYPE = v256f64, FIRST_FIXEDLEN_VECTOR_VALUETYPE = v1i1, LAST_FIXEDLEN_VECTOR_VALUETYPE = v256f64, - nxv1i1 = 135, // n x 1 x i1 - nxv2i1 = 136, // n x 2 x i1 - nxv4i1 = 137, // n x 4 x i1 - nxv8i1 = 138, // n x 8 x i1 - nxv16i1 = 139, // n x 16 x i1 - nxv32i1 = 140, // n x 32 x i1 - nxv64i1 = 141, // n x 64 x i1 - - nxv1i8 = 142, // n x 1 x i8 - nxv2i8 = 143, // n x 2 x i8 - nxv4i8 = 144, // n x 4 x i8 - nxv8i8 = 145, // n x 8 x i8 - nxv16i8 = 146, // n x 16 x i8 - nxv32i8 = 147, // n x 32 x i8 - nxv64i8 = 148, // n x 64 x i8 - - nxv1i16 = 149, // n x 1 x i16 - nxv2i16 = 150, // n x 2 x i16 - nxv4i16 = 151, // n x 4 x i16 - nxv8i16 = 152, // n x 8 x i16 - nxv16i16 = 153, // n x 16 x i16 - nxv32i16 = 154, // n x 32 x i16 - - nxv1i32 = 155, // n x 1 x i32 - nxv2i32 = 156, // n x 2 x i32 - nxv4i32 = 157, // n x 4 x i32 - nxv8i32 = 158, // n x 8 x i32 - nxv16i32 = 159, // n x 16 x i32 - nxv32i32 = 160, // n x 32 x i32 - - nxv1i64 = 161, // n x 1 x i64 - nxv2i64 = 162, // n x 2 x i64 - nxv4i64 = 163, // n x 4 x i64 - nxv8i64 = 164, // n x 8 x i64 - nxv16i64 = 165, // n x 16 x i64 - nxv32i64 = 166, // n x 32 x i64 - FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv1i1, LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv32i64, - nxv1f16 = 167, // n x 1 x f16 - nxv2f16 = 168, // n x 2 x f16 - nxv4f16 = 169, // n x 4 x f16 - nxv8f16 = 170, // n x 8 x f16 - nxv16f16 = 171, // n x 16 x f16 - nxv32f16 = 172, // n x 32 x f16 - - nxv1bf16 = 173, // n x 1 x bf16 - nxv2bf16 = 174, // n x 2 x bf16 - nxv4bf16 = 175, // n x 4 x bf16 - nxv8bf16 = 176, // n x 8 x bf16 - nxv16bf16 = 177, // n x 16 x bf16 - nxv32bf16 = 178, // n x 32 x bf16 - - nxv1f32 = 179, // n x 1 x f32 - nxv2f32 = 180, // n x 2 x f32 - nxv4f32 = 181, // n x 4 x f32 - nxv8f32 = 182, // n x 8 x f32 - nxv16f32 = 183, // n x 16 x f32 - - nxv1f64 = 184, // n x 1 x f64 - nxv2f64 = 185, // n x 2 x f64 - nxv4f64 = 186, // n x 4 x f64 - nxv8f64 = 187, // n x 8 x f64 - FIRST_FP_SCALABLE_VECTOR_VALUETYPE = nxv1f16, LAST_FP_SCALABLE_VECTOR_VALUETYPE = nxv8f64, @@ -277,69 +71,17 @@ FIRST_VECTOR_VALUETYPE = v1i1, LAST_VECTOR_VALUETYPE = nxv8f64, - x86mmx = 188, // This is an X86 MMX value - - Glue = 189, // This glues nodes together during pre-RA sched - - isVoid = 190, // This has no value - - Untyped = 191, // This value takes a register, but has - // unspecified type. The register class - // will be determined by the opcode. - - funcref = 192, // WebAssembly's funcref type - externref = 193, // WebAssembly's externref type - x86amx = 194, // This is an X86 AMX value - i64x8 = 195, // 8 Consecutive GPRs (AArch64) - aarch64svcount = 196, // AArch64 predicate-as-counter - spirvbuiltin = 197, // SPIR-V's builtin type - - FIRST_VALUETYPE = 1, // This is always the beginning of the list. - LAST_VALUETYPE = spirvbuiltin, // This always remains at the end of the list. VALUETYPE_SIZE = LAST_VALUETYPE + 1, // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors // This value must be a multiple of 32. MAX_ALLOWED_VALUETYPE = 224, - - // A value of type llvm::TokenTy - token = 248, - - // This is MDNode or MDString. - Metadata = 249, - - // An int value the size of the pointer of the current - // target to any address space. This must only be used internal to - // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR. - iPTRAny = 250, - - // A vector with any length and element size. This is used - // for intrinsics that have overloadings based on vector types. - // This is only for tblgen's consumption! - vAny = 251, - - // Any floating-point or vector floating-point value. This is used - // for intrinsics that have overloadings based on floating-point types. - // This is only for tblgen's consumption! - fAny = 252, - - // An integer or vector integer value of any bit width. This is - // used for intrinsics that have overloadings based on integer bit widths. - // This is only for tblgen's consumption! - iAny = 253, - - // An int value the size of the pointer of the current - // target. This should only be used internal to tblgen! - iPTR = 254, - - // Any type. This is used for intrinsics that have overloadings. - // This is only for tblgen's consumption! - Any = 255 - - // clang-format on }; + static_assert(FIRST_VALUETYPE > 0); + static_assert(LAST_VALUETYPE < MAX_ALLOWED_VALUETYPE); + SimpleValueType SimpleTy = INVALID_SIMPLE_VALUE_TYPE; constexpr MVT() = default; @@ -420,72 +162,42 @@ /// Return true if this is a 16-bit vector type. bool is16BitVector() const { - return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 || - SimpleTy == MVT::v16i1 || SimpleTy == MVT::v1f16); + return (isFixedLengthVector() && getFixedSizeInBits() == 16); } /// Return true if this is a 32-bit vector type. bool is32BitVector() const { - return (SimpleTy == MVT::v32i1 || SimpleTy == MVT::v4i8 || - SimpleTy == MVT::v2i16 || SimpleTy == MVT::v1i32 || - SimpleTy == MVT::v2f16 || SimpleTy == MVT::v2bf16 || - SimpleTy == MVT::v1f32); + return (isFixedLengthVector() && getFixedSizeInBits() == 32); } /// Return true if this is a 64-bit vector type. bool is64BitVector() const { - return (SimpleTy == MVT::v64i1 || SimpleTy == MVT::v8i8 || - SimpleTy == MVT::v4i16 || SimpleTy == MVT::v2i32 || - SimpleTy == MVT::v1i64 || SimpleTy == MVT::v4f16 || - SimpleTy == MVT::v4bf16 ||SimpleTy == MVT::v2f32 || - SimpleTy == MVT::v1f64); + return (isFixedLengthVector() && getFixedSizeInBits() == 64); } /// Return true if this is a 128-bit vector type. bool is128BitVector() const { - return (SimpleTy == MVT::v128i1 || SimpleTy == MVT::v16i8 || - SimpleTy == MVT::v8i16 || SimpleTy == MVT::v4i32 || - SimpleTy == MVT::v2i64 || SimpleTy == MVT::v1i128 || - SimpleTy == MVT::v8f16 || SimpleTy == MVT::v8bf16 || - SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64); + return (isFixedLengthVector() && getFixedSizeInBits() == 128); } /// Return true if this is a 256-bit vector type. bool is256BitVector() const { - return (SimpleTy == MVT::v16f16 || SimpleTy == MVT::v16bf16 || - SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 || - SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 || - SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64 || - SimpleTy == MVT::v256i1 || SimpleTy == MVT::v128i2 || - SimpleTy == MVT::v64i4); + return (isFixedLengthVector() && getFixedSizeInBits() == 256); } /// Return true if this is a 512-bit vector type. bool is512BitVector() const { - return (SimpleTy == MVT::v32f16 || SimpleTy == MVT::v32bf16 || - SimpleTy == MVT::v16f32 || SimpleTy == MVT::v8f64 || - SimpleTy == MVT::v512i1 || SimpleTy == MVT::v256i2 || - SimpleTy == MVT::v128i4 || SimpleTy == MVT::v64i8 || - SimpleTy == MVT::v32i16 || SimpleTy == MVT::v16i32 || - SimpleTy == MVT::v8i64); + return (isFixedLengthVector() && getFixedSizeInBits() == 512); } /// Return true if this is a 1024-bit vector type. bool is1024BitVector() const { - return (SimpleTy == MVT::v1024i1 || SimpleTy == MVT::v128i8 || - SimpleTy == MVT::v64i16 || SimpleTy == MVT::v32i32 || - SimpleTy == MVT::v16i64 || SimpleTy == MVT::v64f16 || - SimpleTy == MVT::v32f32 || SimpleTy == MVT::v16f64 || - SimpleTy == MVT::v64bf16); + return (isFixedLengthVector() && getFixedSizeInBits() == 1024); } /// Return true if this is a 2048-bit vector type. bool is2048BitVector() const { - return (SimpleTy == MVT::v256i8 || SimpleTy == MVT::v128i16 || - SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64 || - SimpleTy == MVT::v128f16 || SimpleTy == MVT::v64f32 || - SimpleTy == MVT::v32f64 || SimpleTy == MVT::v128bf16 || - SimpleTy == MVT::v2048i1); + return (isFixedLengthVector() && getFixedSizeInBits() == 2048); } /// Return true if this is an overloaded type for TableGen. @@ -937,7 +649,17 @@ TypeSize getSizeInBits() const { switch (SimpleTy) { default: - llvm_unreachable("getSizeInBits called on extended MVT."); + switch (SimpleTy) { + default: + llvm_unreachable("getSizeInBits called on extended MVT."); + +#define GET_VT_ATTR(Ty, N, Sz) \ + case Ty: \ + return (MVT(Ty).isScalableVector() ? TypeSize::Scalable(Sz) \ + : TypeSize::Fixed(Sz)); +#include "GenVT.inc" +#undef GET_VT_ATTR + } case Other: llvm_unreachable("Value type is non-standard value, Other."); case iPTR: @@ -953,200 +675,6 @@ "in codegen and has no size"); case Metadata: llvm_unreachable("Value type is metadata."); - case i1: - case v1i1: return TypeSize::Fixed(1); - case nxv1i1: return TypeSize::Scalable(1); - case i2: - case v2i1: return TypeSize::Fixed(2); - case nxv2i1: return TypeSize::Scalable(2); - case i4: - case v4i1: return TypeSize::Fixed(4); - case nxv4i1: return TypeSize::Scalable(4); - case i8 : - case v1i8: - case v8i1: return TypeSize::Fixed(8); - case nxv1i8: - case nxv8i1: return TypeSize::Scalable(8); - case i16 : - case f16: - case bf16: - case v16i1: - case v2i8: - case v1i16: - case v1f16: return TypeSize::Fixed(16); - case aarch64svcount: - case nxv16i1: - case nxv2i8: - case nxv1i16: - case nxv1bf16: - case nxv1f16: return TypeSize::Scalable(16); - case f32 : - case i32 : - case v32i1: - case v4i8: - case v2i16: - case v2f16: - case v2bf16: - case v1f32: - case v1i32: return TypeSize::Fixed(32); - case nxv32i1: - case nxv4i8: - case nxv2i16: - case nxv1i32: - case nxv2f16: - case nxv2bf16: - case nxv1f32: return TypeSize::Scalable(32); - case v3i16: - case v3f16: - case v3bf16: return TypeSize::Fixed(48); - case x86mmx: - case f64 : - case i64 : - case v64i1: - case v8i8: - case v4i16: - case v2i32: - case v1i64: - case v4f16: - case v4bf16: - case v2f32: - case v1f64: return TypeSize::Fixed(64); - case nxv64i1: - case nxv8i8: - case nxv4i16: - case nxv2i32: - case nxv1i64: - case nxv4f16: - case nxv4bf16: - case nxv2f32: - case nxv1f64: return TypeSize::Scalable(64); - case f80 : return TypeSize::Fixed(80); - case v3i32: - case v3f32: return TypeSize::Fixed(96); - case f128: - case ppcf128: - case i128: - case v128i1: - case v16i8: - case v8i16: - case v4i32: - case v2i64: - case v1i128: - case v8f16: - case v8bf16: - case v4f32: - case v2f64: return TypeSize::Fixed(128); - case nxv16i8: - case nxv8i16: - case nxv4i32: - case nxv2i64: - case nxv8f16: - case nxv8bf16: - case nxv4f32: - case nxv2f64: return TypeSize::Scalable(128); - case v5i32: - case v5f32: return TypeSize::Fixed(160); - case v6i32: - case v3i64: - case v6f32: - case v3f64: return TypeSize::Fixed(192); - case v7i32: - case v7f32: return TypeSize::Fixed(224); - case v256i1: - case v128i2: - case v64i4: - case v32i8: - case v16i16: - case v8i32: - case v4i64: - case v16f16: - case v16bf16: - case v8f32: - case v4f64: return TypeSize::Fixed(256); - case nxv32i8: - case nxv16i16: - case nxv8i32: - case nxv4i64: - case nxv16f16: - case nxv16bf16: - case nxv8f32: - case nxv4f64: return TypeSize::Scalable(256); - case v9i32: - case v9f32: return TypeSize::Fixed(288); - case v10i32: - case v10f32: return TypeSize::Fixed(320); - case v11i32: - case v11f32: return TypeSize::Fixed(352); - case v12i32: - case v12f32: return TypeSize::Fixed(384); - case i64x8: - case v512i1: - case v256i2: - case v128i4: - case v64i8: - case v32i16: - case v16i32: - case v8i64: - case v32f16: - case v32bf16: - case v16f32: - case v8f64: return TypeSize::Fixed(512); - case nxv64i8: - case nxv32i16: - case nxv16i32: - case nxv8i64: - case nxv32f16: - case nxv32bf16: - case nxv16f32: - case nxv8f64: return TypeSize::Scalable(512); - case v1024i1: - case v128i8: - case v64i16: - case v32i32: - case v16i64: - case v64f16: - case v64bf16: - case v32f32: - case v16f64: return TypeSize::Fixed(1024); - case nxv32i32: - case nxv16i64: return TypeSize::Scalable(1024); - case v2048i1: - case v256i8: - case v128i16: - case v64i32: - case v32i64: - case v128f16: - case v128bf16: - case v64f32: - case v32f64: return TypeSize::Fixed(2048); - case nxv32i64: return TypeSize::Scalable(2048); - case v512i8: - case v256i16: - case v128i32: - case v64i64: - case v256f16: - case v128f32: - case v64f64: return TypeSize::Fixed(4096); - case v1024i8: - case v512i16: - case v256i32: - case v128i64: - case v512f16: - case v256f32: - case x86amx: - case v128f64: return TypeSize::Fixed(8192); - case v512i32: - case v256i64: - case v512f32: - case v256f64: return TypeSize::Fixed(16384); - case v1024i32: - case v1024f32: return TypeSize::Fixed(32768); - case v2048i32: - case v2048f32: return TypeSize::Fixed(65536); - case funcref: - case externref: - case spirvbuiltin: - return TypeSize::Fixed(0); // opaque type } } @@ -1597,6 +1125,6 @@ return OS; } -} // end namespace llvm +} // namespace llvm::tmp -#endif // LLVM_SUPPORT_MACHINEVALUETYPE_H +#endif // LLVM_TMP_MACHINEVALUETYPE_H diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt --- a/llvm/utils/TableGen/CMakeLists.txt +++ b/llvm/utils/TableGen/CMakeLists.txt @@ -54,6 +54,7 @@ SubtargetFeatureInfo.cpp TableGen.cpp Types.cpp + VTEmitter.cpp VarLenCodeEmitterGen.cpp X86DisassemblerTables.cpp X86EVEX2VEXTablesEmitter.cpp diff --git a/llvm/utils/TableGen/VTEmitter.cpp b/llvm/utils/TableGen/VTEmitter.cpp new file mode 100644 --- /dev/null +++ b/llvm/utils/TableGen/VTEmitter.cpp @@ -0,0 +1,99 @@ +//===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===// +// +// 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/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include +#include +#include +using namespace llvm; + +namespace { + +class VTEmitter { +private: + RecordKeeper &Records; + +public: + VTEmitter(RecordKeeper &R) : Records(R) {} + + void run(raw_ostream &OS); +}; + +} // End anonymous namespace. + +void VTEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("ValueTypes Source Fragment", OS); + + std::array VTsByNumber = {}; + auto ValueTypes = Records.getAllDerivedDefinitions("ValueType"); + for (auto *VT : ValueTypes) { + auto Number = VT->getValueAsInt("Value"); + assert(0 <= Number && Number < (int)VTsByNumber.size() && + "ValueType should be uint8_t"); + assert(!VTsByNumber[Number] && "Duplicate ValueType"); + VTsByNumber[Number] = VT; + } + + struct VTRange { + StringRef First; + StringRef Last; + bool Closed; + }; + + std::map VTRanges; + + auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name, + bool Valid) { + if (Valid) { + if (!VTRanges.count(Key)) + VTRanges[Key].First = Name; + assert(!VTRanges[Key].Closed && "Gap detected!"); + VTRanges[Key].Last = Name; + } else if (VTRanges.count(Key)) { + VTRanges[Key].Closed = true; + } + }; + + OS << "#ifdef GET_VT_ATTR // (Ty, n, sz)\n"; + for (const auto *VT : VTsByNumber) { + if (!VT) + continue; + auto Name = VT->getName(); + Name = StringSwitch(Name) + .Case("OtherVT", "Other") + .Case("FlagVT", "Glue") + .Case("untyped", "Untyped") + .Case("MetadataVT", "Metadata") + .Default(Name); + auto Value = VT->getValueAsInt("Value"); + + UpdateVTRange("VALUETYPE", Name, Value < 224); + + // clang-format off + OS << " GET_VT_ATTR(" + << Name << ", " + << Value << ", " + << VT->getValueAsInt("Size") << ")\n"; + // clang-format on + } + OS << "#endif\n\n"; + + OS << "#ifdef GET_VT_RANGES\n"; + for (const auto &KV : VTRanges) { + assert(KV.second.Closed); + OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n" + << " LAST_" << KV.first << " = " << KV.second.Last << ",\n"; + } + OS << "#endif\n\n"; +} + +static TableGen::Emitter::OptClass X("gen-vt", "Generate ValueType"); diff --git a/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel @@ -554,6 +554,17 @@ ], ) +gentbl( + name = "vt_gen", + strip_include_prefix = "Support", + tbl_outs = [("-gen-vt", "Support/GenVT.inc")], + tblgen = "//llvm:llvm-tblgen", + td_file = "//llvm:include/llvm/CodeGen/ValueTypes.td", + td_srcs = [ + "//llvm:include/llvm/CodeGen/ValueTypes.td", + ], +) + cc_test( name = "option_tests", size = "small", @@ -639,6 +650,7 @@ "//llvm:TargetParser", "//llvm:TestingSupport", "//llvm:config", + ":vt_gen", "//third-party/unittest:gmock", "//third-party/unittest:gtest", "//third-party/unittest:gtest_main",