123e79ec2SAmara Emerson //===-------- llvm/unittest/CodeGen/ScalableVectorMVTsTest.cpp ------------===//
223e79ec2SAmara Emerson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
623e79ec2SAmara Emerson //
723e79ec2SAmara Emerson //===----------------------------------------------------------------------===//
823e79ec2SAmara Emerson
92fa14362SCraig Topper #include "llvm/CodeGen/ValueTypes.h"
10*184ca395SNico Weber #include "llvm/CodeGenTypes/MachineValueType.h"
11208d63eaSGraham Hunter #include "llvm/IR/DerivedTypes.h"
1223e79ec2SAmara Emerson #include "llvm/IR/LLVMContext.h"
13b302561bSGraham Hunter #include "llvm/Support/TypeSize.h"
1423e79ec2SAmara Emerson #include "gtest/gtest.h"
1523e79ec2SAmara Emerson
1623e79ec2SAmara Emerson using namespace llvm;
1723e79ec2SAmara Emerson
1823e79ec2SAmara Emerson namespace {
1923e79ec2SAmara Emerson
TEST(ScalableVectorMVTsTest,IntegerMVTs)2023e79ec2SAmara Emerson TEST(ScalableVectorMVTsTest, IntegerMVTs) {
21d6da02d9SGuillaume Chatelet for (MVT VecTy : MVT::integer_scalable_vector_valuetypes()) {
2223e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isValid());
2323e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isInteger());
2423e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isVector());
2523e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isScalableVector());
2623e79ec2SAmara Emerson ASSERT_TRUE(VecTy.getScalarType().isValid());
2723e79ec2SAmara Emerson
2823e79ec2SAmara Emerson ASSERT_FALSE(VecTy.isFloatingPoint());
2923e79ec2SAmara Emerson }
3023e79ec2SAmara Emerson }
3123e79ec2SAmara Emerson
TEST(ScalableVectorMVTsTest,FloatMVTs)3223e79ec2SAmara Emerson TEST(ScalableVectorMVTsTest, FloatMVTs) {
33d6da02d9SGuillaume Chatelet for (MVT VecTy : MVT::fp_scalable_vector_valuetypes()) {
3423e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isValid());
3523e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isFloatingPoint());
3623e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isVector());
3723e79ec2SAmara Emerson ASSERT_TRUE(VecTy.isScalableVector());
3823e79ec2SAmara Emerson ASSERT_TRUE(VecTy.getScalarType().isValid());
3923e79ec2SAmara Emerson
4023e79ec2SAmara Emerson ASSERT_FALSE(VecTy.isInteger());
4123e79ec2SAmara Emerson }
4223e79ec2SAmara Emerson }
4323e79ec2SAmara Emerson
TEST(ScalableVectorMVTsTest,HelperFuncs)4423e79ec2SAmara Emerson TEST(ScalableVectorMVTsTest, HelperFuncs) {
4523e79ec2SAmara Emerson LLVMContext Ctx;
4623e79ec2SAmara Emerson
4723e79ec2SAmara Emerson // Create with scalable flag
4823e79ec2SAmara Emerson EVT Vnx4i32 = EVT::getVectorVT(Ctx, MVT::i32, 4, /*Scalable=*/true);
4923e79ec2SAmara Emerson ASSERT_TRUE(Vnx4i32.isScalableVector());
5023e79ec2SAmara Emerson
51208d63eaSGraham Hunter // Create with separate llvm::ElementCount
52a407ec9bSMehdi Amini auto EltCnt = ElementCount::getScalable(2);
5323e79ec2SAmara Emerson EVT Vnx2i32 = EVT::getVectorVT(Ctx, MVT::i32, EltCnt);
5423e79ec2SAmara Emerson ASSERT_TRUE(Vnx2i32.isScalableVector());
5523e79ec2SAmara Emerson
56208d63eaSGraham Hunter // Create with inline llvm::ElementCount
57a407ec9bSMehdi Amini EVT Vnx2i64 = EVT::getVectorVT(Ctx, MVT::i64, ElementCount::getScalable(2));
5823e79ec2SAmara Emerson ASSERT_TRUE(Vnx2i64.isScalableVector());
5923e79ec2SAmara Emerson
6023e79ec2SAmara Emerson // Check that changing scalar types/element count works
6123e79ec2SAmara Emerson EXPECT_EQ(Vnx2i32.widenIntegerVectorElementType(Ctx), Vnx2i64);
6223e79ec2SAmara Emerson EXPECT_EQ(Vnx4i32.getHalfNumVectorElementsVT(Ctx), Vnx2i32);
6323e79ec2SAmara Emerson
64bafdd113SDavid Sherwood // Check that operators work
6523e79ec2SAmara Emerson EXPECT_EQ(EVT::getVectorVT(Ctx, MVT::i64, EltCnt * 2), MVT::nxv4i64);
66bafdd113SDavid Sherwood EXPECT_EQ(EVT::getVectorVT(Ctx, MVT::i64, EltCnt.divideCoefficientBy(2)),
67bafdd113SDavid Sherwood MVT::nxv1i64);
6823e79ec2SAmara Emerson
6923e79ec2SAmara Emerson // Check that float->int conversion works
70a407ec9bSMehdi Amini EVT Vnx2f64 = EVT::getVectorVT(Ctx, MVT::f64, ElementCount::getScalable(2));
7123e79ec2SAmara Emerson EXPECT_EQ(Vnx2f64.changeTypeToInteger(), Vnx2i64);
7223e79ec2SAmara Emerson
73208d63eaSGraham Hunter // Check fields inside llvm::ElementCount
7423e79ec2SAmara Emerson EltCnt = Vnx4i32.getVectorElementCount();
75f4257c58SDavid Sherwood EXPECT_EQ(EltCnt.getKnownMinValue(), 4U);
76f4257c58SDavid Sherwood ASSERT_TRUE(EltCnt.isScalable());
7723e79ec2SAmara Emerson
7823e79ec2SAmara Emerson // Check that fixed-length vector types aren't scalable.
7923e79ec2SAmara Emerson EVT V8i32 = EVT::getVectorVT(Ctx, MVT::i32, 8);
8023e79ec2SAmara Emerson ASSERT_FALSE(V8i32.isScalableVector());
81a407ec9bSMehdi Amini EVT V4f64 = EVT::getVectorVT(Ctx, MVT::f64, ElementCount::getFixed(4));
8223e79ec2SAmara Emerson ASSERT_FALSE(V4f64.isScalableVector());
8323e79ec2SAmara Emerson
84208d63eaSGraham Hunter // Check that llvm::ElementCount works for fixed-length types.
8523e79ec2SAmara Emerson EltCnt = V8i32.getVectorElementCount();
86f4257c58SDavid Sherwood EXPECT_EQ(EltCnt.getKnownMinValue(), 8U);
87f4257c58SDavid Sherwood ASSERT_FALSE(EltCnt.isScalable());
8823e79ec2SAmara Emerson }
8923e79ec2SAmara Emerson
TEST(ScalableVectorMVTsTest,IRToVTTranslation)90208d63eaSGraham Hunter TEST(ScalableVectorMVTsTest, IRToVTTranslation) {
91208d63eaSGraham Hunter LLVMContext Ctx;
92208d63eaSGraham Hunter
93208d63eaSGraham Hunter Type *Int64Ty = Type::getInt64Ty(Ctx);
94a407ec9bSMehdi Amini VectorType *ScV8Int64Ty =
95a407ec9bSMehdi Amini VectorType::get(Int64Ty, ElementCount::getScalable(8));
96208d63eaSGraham Hunter
97208d63eaSGraham Hunter // Check that we can map a scalable IR type to an MVT
98208d63eaSGraham Hunter MVT Mnxv8i64 = MVT::getVT(ScV8Int64Ty);
99208d63eaSGraham Hunter ASSERT_TRUE(Mnxv8i64.isScalableVector());
100208d63eaSGraham Hunter ASSERT_EQ(ScV8Int64Ty->getElementCount(), Mnxv8i64.getVectorElementCount());
101208d63eaSGraham Hunter ASSERT_EQ(MVT::getVT(ScV8Int64Ty->getElementType()),
102208d63eaSGraham Hunter Mnxv8i64.getScalarType());
103208d63eaSGraham Hunter
104208d63eaSGraham Hunter // Check that we can map a scalable IR type to an EVT
105208d63eaSGraham Hunter EVT Enxv8i64 = EVT::getEVT(ScV8Int64Ty);
106208d63eaSGraham Hunter ASSERT_TRUE(Enxv8i64.isScalableVector());
107208d63eaSGraham Hunter ASSERT_EQ(ScV8Int64Ty->getElementCount(), Enxv8i64.getVectorElementCount());
108208d63eaSGraham Hunter ASSERT_EQ(EVT::getEVT(ScV8Int64Ty->getElementType()),
109208d63eaSGraham Hunter Enxv8i64.getScalarType());
11023e79ec2SAmara Emerson }
111208d63eaSGraham Hunter
TEST(ScalableVectorMVTsTest,VTToIRTranslation)112208d63eaSGraham Hunter TEST(ScalableVectorMVTsTest, VTToIRTranslation) {
113208d63eaSGraham Hunter LLVMContext Ctx;
114208d63eaSGraham Hunter
115a407ec9bSMehdi Amini EVT Enxv4f64 = EVT::getVectorVT(Ctx, MVT::f64, ElementCount::getScalable(4));
116208d63eaSGraham Hunter
117208d63eaSGraham Hunter Type *Ty = Enxv4f64.getTypeForEVT(Ctx);
118208d63eaSGraham Hunter VectorType *ScV4Float64Ty = cast<VectorType>(Ty);
119ccd623eaSChristopher Tetreault ASSERT_TRUE(isa<ScalableVectorType>(ScV4Float64Ty));
120208d63eaSGraham Hunter ASSERT_EQ(Enxv4f64.getVectorElementCount(), ScV4Float64Ty->getElementCount());
121208d63eaSGraham Hunter ASSERT_EQ(Enxv4f64.getScalarType().getTypeForEVT(Ctx),
122208d63eaSGraham Hunter ScV4Float64Ty->getElementType());
123208d63eaSGraham Hunter }
124208d63eaSGraham Hunter
TEST(ScalableVectorMVTsTest,SizeQueries)1253f08ad61SGraham Hunter TEST(ScalableVectorMVTsTest, SizeQueries) {
1263f08ad61SGraham Hunter LLVMContext Ctx;
1273f08ad61SGraham Hunter
1283f08ad61SGraham Hunter EVT nxv4i32 = EVT::getVectorVT(Ctx, MVT::i32, 4, /*Scalable=*/ true);
1293f08ad61SGraham Hunter EVT nxv2i32 = EVT::getVectorVT(Ctx, MVT::i32, 2, /*Scalable=*/ true);
1303f08ad61SGraham Hunter EVT nxv2i64 = EVT::getVectorVT(Ctx, MVT::i64, 2, /*Scalable=*/ true);
1313f08ad61SGraham Hunter EVT nxv2f64 = EVT::getVectorVT(Ctx, MVT::f64, 2, /*Scalable=*/ true);
1323f08ad61SGraham Hunter
1333f08ad61SGraham Hunter EVT v4i32 = EVT::getVectorVT(Ctx, MVT::i32, 4);
1343f08ad61SGraham Hunter EVT v2i32 = EVT::getVectorVT(Ctx, MVT::i32, 2);
1353f08ad61SGraham Hunter EVT v2i64 = EVT::getVectorVT(Ctx, MVT::i64, 2);
1363f08ad61SGraham Hunter EVT v2f64 = EVT::getVectorVT(Ctx, MVT::f64, 2);
1373f08ad61SGraham Hunter
138e1afd063SMaciej Gabka EVT nxv5i32 = EVT::getVectorVT(Ctx, MVT::i32, 5, /*Scalable=*/true);
139e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is16BitVector());
140e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is32BitVector());
141e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is64BitVector());
142e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is128BitVector());
143e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is256BitVector());
144e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is512BitVector());
145e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is1024BitVector());
146e1afd063SMaciej Gabka ASSERT_FALSE(nxv5i32.is2048BitVector());
147e1afd063SMaciej Gabka
1483f08ad61SGraham Hunter // Check equivalence and ordering on scalable types.
1493f08ad61SGraham Hunter EXPECT_EQ(nxv4i32.getSizeInBits(), nxv2i64.getSizeInBits());
1503f08ad61SGraham Hunter EXPECT_EQ(nxv2f64.getSizeInBits(), nxv2i64.getSizeInBits());
1513f08ad61SGraham Hunter EXPECT_NE(nxv2i32.getSizeInBits(), nxv4i32.getSizeInBits());
15248f5d77eSGuillaume Chatelet EXPECT_LT(nxv2i32.getSizeInBits().getKnownMinValue(),
15348f5d77eSGuillaume Chatelet nxv2i64.getSizeInBits().getKnownMinValue());
15448f5d77eSGuillaume Chatelet EXPECT_LE(nxv4i32.getSizeInBits().getKnownMinValue(),
15548f5d77eSGuillaume Chatelet nxv2i64.getSizeInBits().getKnownMinValue());
15648f5d77eSGuillaume Chatelet EXPECT_GT(nxv4i32.getSizeInBits().getKnownMinValue(),
15748f5d77eSGuillaume Chatelet nxv2i32.getSizeInBits().getKnownMinValue());
15848f5d77eSGuillaume Chatelet EXPECT_GE(nxv2i64.getSizeInBits().getKnownMinValue(),
15948f5d77eSGuillaume Chatelet nxv4i32.getSizeInBits().getKnownMinValue());
1603f08ad61SGraham Hunter
1613f08ad61SGraham Hunter // Check equivalence and ordering on fixed types.
1623f08ad61SGraham Hunter EXPECT_EQ(v4i32.getSizeInBits(), v2i64.getSizeInBits());
1633f08ad61SGraham Hunter EXPECT_EQ(v2f64.getSizeInBits(), v2i64.getSizeInBits());
1643f08ad61SGraham Hunter EXPECT_NE(v2i32.getSizeInBits(), v4i32.getSizeInBits());
165f5815105SDavid Sherwood EXPECT_LT(v2i32.getFixedSizeInBits(), v2i64.getFixedSizeInBits());
166f5815105SDavid Sherwood EXPECT_LE(v4i32.getFixedSizeInBits(), v2i64.getFixedSizeInBits());
167f5815105SDavid Sherwood EXPECT_GT(v4i32.getFixedSizeInBits(), v2i32.getFixedSizeInBits());
168f5815105SDavid Sherwood EXPECT_GE(v2i64.getFixedSizeInBits(), v4i32.getFixedSizeInBits());
1693f08ad61SGraham Hunter
1703f08ad61SGraham Hunter // Check that scalable and non-scalable types with the same minimum size
1713f08ad61SGraham Hunter // are not considered equal.
1723f08ad61SGraham Hunter ASSERT_TRUE(v4i32.getSizeInBits() != nxv4i32.getSizeInBits());
1733f08ad61SGraham Hunter ASSERT_FALSE(v2i64.getSizeInBits() == nxv2f64.getSizeInBits());
1743f08ad61SGraham Hunter
1753f08ad61SGraham Hunter // Check that we can obtain a known-exact size from a non-scalable type.
176f5815105SDavid Sherwood EXPECT_EQ(v4i32.getFixedSizeInBits(), 128U);
177b8ce6a67SDavid Sherwood EXPECT_EQ(v2i64.getFixedSizeInBits(), 128U);
1783f08ad61SGraham Hunter
1793f08ad61SGraham Hunter // Check that we can query the known minimum size for both scalable and
1803f08ad61SGraham Hunter // fixed length types.
18148f5d77eSGuillaume Chatelet EXPECT_EQ(nxv2i32.getSizeInBits().getKnownMinValue(), 64U);
18248f5d77eSGuillaume Chatelet EXPECT_EQ(nxv2f64.getSizeInBits().getKnownMinValue(), 128U);
18348f5d77eSGuillaume Chatelet EXPECT_EQ(v2i32.getSizeInBits().getKnownMinValue(),
18448f5d77eSGuillaume Chatelet nxv2i32.getSizeInBits().getKnownMinValue());
1853f08ad61SGraham Hunter
1863f08ad61SGraham Hunter // Check scalable property.
1873f08ad61SGraham Hunter ASSERT_FALSE(v4i32.getSizeInBits().isScalable());
1883f08ad61SGraham Hunter ASSERT_TRUE(nxv4i32.getSizeInBits().isScalable());
1893f08ad61SGraham Hunter
1903f08ad61SGraham Hunter // Check convenience size scaling methods.
1913f08ad61SGraham Hunter EXPECT_EQ(v2i32.getSizeInBits() * 2, v4i32.getSizeInBits());
1923f08ad61SGraham Hunter EXPECT_EQ(2 * nxv2i32.getSizeInBits(), nxv4i32.getSizeInBits());
1930f7bbbc4SSander de Smalen EXPECT_EQ(nxv2f64.getSizeInBits().divideCoefficientBy(2),
1940f7bbbc4SSander de Smalen nxv2i32.getSizeInBits());
1953f08ad61SGraham Hunter }
1963f08ad61SGraham Hunter
197208d63eaSGraham Hunter } // end anonymous namespace
198