1 //===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/LowLevelTypeUtils.h"
10 #include "llvm/IR/DataLayout.h"
11 #include "llvm/IR/DerivedTypes.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Type.h"
14 #include "llvm/Support/TypeSize.h"
15 #include "gtest/gtest.h"
21 TEST(LowLevelTypeTest
, Token
) {
24 const LLT TTy
= LLT::token();
27 EXPECT_TRUE(TTy
.isValid());
28 EXPECT_TRUE(TTy
.isScalar());
29 EXPECT_TRUE(TTy
.isToken());
31 EXPECT_FALSE(TTy
.isPointer());
32 EXPECT_FALSE(TTy
.isVector());
34 const LLT STy
= LLT::scalar(0);
38 TEST(LowLevelTypeTest
, Scalar
) {
42 for (unsigned S
: {0U, 1U, 17U, 32U, 64U, 0xfffffU
}) {
43 const LLT Ty
= LLT::scalar(S
);
46 ASSERT_TRUE(Ty
.isValid());
47 ASSERT_TRUE(Ty
.isScalar());
49 ASSERT_FALSE(Ty
.isPointer());
50 ASSERT_FALSE(Ty
.isVector());
52 EXPECT_TRUE(S
!= 0 || Ty
.isToken());
55 EXPECT_EQ(S
, Ty
.getSizeInBits());
56 EXPECT_EQ(S
, Ty
.getScalarSizeInBits());
58 // Test equality operators.
59 EXPECT_TRUE(Ty
== Ty
);
60 EXPECT_FALSE(Ty
!= Ty
);
62 // Test Type->LLT conversion.
64 Type
*IRTy
= IntegerType::get(C
, S
);
65 EXPECT_EQ(Ty
, getLLTForType(*IRTy
, DL
));
70 TEST(LowLevelTypeTest
, Vector
) {
74 for (unsigned S
: {0U, 1U, 17U, 32U, 64U, 0xfffU
}) {
76 {ElementCount::getFixed(2), ElementCount::getFixed(3),
77 ElementCount::getFixed(4), ElementCount::getFixed(32),
78 ElementCount::getFixed(0xff), ElementCount::getScalable(2),
79 ElementCount::getScalable(3), ElementCount::getScalable(4),
80 ElementCount::getScalable(32), ElementCount::getScalable(0xff)}) {
81 const LLT STy
= LLT::scalar(S
);
82 const LLT VTy
= LLT::vector(EC
, S
);
84 // Test the alternative vector().
86 const LLT VSTy
= LLT::vector(EC
, STy
);
90 // Test getElementType().
91 EXPECT_EQ(STy
, VTy
.getElementType());
94 ASSERT_TRUE(VTy
.isValid());
95 ASSERT_TRUE(VTy
.isVector());
97 ASSERT_FALSE(VTy
.isScalar());
98 ASSERT_FALSE(VTy
.isPointer());
99 ASSERT_FALSE(VTy
.isToken());
102 EXPECT_EQ(S
, VTy
.getScalarSizeInBits());
103 EXPECT_EQ(EC
, VTy
.getElementCount());
104 if (!EC
.isScalable())
105 EXPECT_EQ(S
* EC
.getFixedValue(), VTy
.getSizeInBits());
107 EXPECT_EQ(TypeSize::getScalable(S
* EC
.getKnownMinValue()),
108 VTy
.getSizeInBits());
110 // Test equality operators.
111 EXPECT_TRUE(VTy
== VTy
);
112 EXPECT_FALSE(VTy
!= VTy
);
114 // Test inequality operators on..
118 // Test Type->LLT conversion.
120 Type
*IRSTy
= IntegerType::get(C
, S
);
121 Type
*IRTy
= VectorType::get(IRSTy
, EC
);
122 EXPECT_EQ(VTy
, getLLTForType(*IRTy
, DL
));
128 TEST(LowLevelTypeTest
, ScalarOrVector
) {
129 // Test version with number of bits for scalar type.
130 EXPECT_EQ(LLT::scalar(32),
131 LLT::scalarOrVector(ElementCount::getFixed(1), 32));
132 EXPECT_EQ(LLT::fixed_vector(2, 32),
133 LLT::scalarOrVector(ElementCount::getFixed(2), 32));
134 EXPECT_EQ(LLT::scalable_vector(1, 32),
135 LLT::scalarOrVector(ElementCount::getScalable(1), 32));
137 // Test version with LLT for scalar type.
138 EXPECT_EQ(LLT::scalar(32),
139 LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)));
140 EXPECT_EQ(LLT::fixed_vector(2, 32),
141 LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)));
143 // Test with pointer elements.
144 EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(ElementCount::getFixed(1),
145 LLT::pointer(1, 32)));
147 LLT::fixed_vector(2, LLT::pointer(1, 32)),
148 LLT::scalarOrVector(ElementCount::getFixed(2), LLT::pointer(1, 32)));
151 TEST(LowLevelTypeTest
, ChangeElementType
) {
152 const LLT P0
= LLT::pointer(0, 32);
153 const LLT P1
= LLT::pointer(1, 64);
155 const LLT S32
= LLT::scalar(32);
156 const LLT S64
= LLT::scalar(64);
158 const LLT V2S32
= LLT::fixed_vector(2, 32);
159 const LLT V2S64
= LLT::fixed_vector(2, 64);
161 const LLT V2P0
= LLT::fixed_vector(2, P0
);
162 const LLT V2P1
= LLT::fixed_vector(2, P1
);
164 EXPECT_EQ(S64
, S32
.changeElementType(S64
));
165 EXPECT_EQ(S32
, S32
.changeElementType(S32
));
167 EXPECT_EQ(S32
, S64
.changeElementSize(32));
168 EXPECT_EQ(S32
, S32
.changeElementSize(32));
170 EXPECT_EQ(V2S64
, V2S32
.changeElementType(S64
));
171 EXPECT_EQ(V2S32
, V2S64
.changeElementType(S32
));
173 EXPECT_EQ(V2S64
, V2S32
.changeElementSize(64));
174 EXPECT_EQ(V2S32
, V2S64
.changeElementSize(32));
176 EXPECT_EQ(P0
, S32
.changeElementType(P0
));
177 EXPECT_EQ(S32
, P0
.changeElementType(S32
));
179 EXPECT_EQ(V2P1
, V2P0
.changeElementType(P1
));
180 EXPECT_EQ(V2S32
, V2P0
.changeElementType(S32
));
182 // Similar tests for scalable vectors.
183 const LLT NXV2S32
= LLT::scalable_vector(2, 32);
184 const LLT NXV2S64
= LLT::scalable_vector(2, 64);
186 const LLT NXV2P0
= LLT::scalable_vector(2, P0
);
187 const LLT NXV2P1
= LLT::scalable_vector(2, P1
);
189 EXPECT_EQ(NXV2S64
, NXV2S32
.changeElementType(S64
));
190 EXPECT_EQ(NXV2S32
, NXV2S64
.changeElementType(S32
));
192 EXPECT_EQ(NXV2S64
, NXV2S32
.changeElementSize(64));
193 EXPECT_EQ(NXV2S32
, NXV2S64
.changeElementSize(32));
195 EXPECT_EQ(NXV2P1
, NXV2P0
.changeElementType(P1
));
196 EXPECT_EQ(NXV2S32
, NXV2P0
.changeElementType(S32
));
199 TEST(LowLevelTypeTest
, ChangeNumElements
) {
200 const LLT P0
= LLT::pointer(0, 32);
201 const LLT V2P0
= LLT::fixed_vector(2, P0
);
202 const LLT V3P0
= LLT::fixed_vector(3, P0
);
204 const LLT S64
= LLT::scalar(64);
205 const LLT V2S64
= LLT::fixed_vector(2, 64);
206 const LLT V3S64
= LLT::fixed_vector(3, 64);
209 EXPECT_EQ(S64
, V2S64
.changeElementCount(ElementCount::getFixed(1)));
212 EXPECT_EQ(V3S64
, V2S64
.changeElementCount(ElementCount::getFixed(3)));
215 EXPECT_EQ(V2S64
, S64
.changeElementCount(ElementCount::getFixed(2)));
217 EXPECT_EQ(P0
, V2P0
.changeElementCount(ElementCount::getFixed(1)));
218 EXPECT_EQ(V3P0
, V2P0
.changeElementCount(ElementCount::getFixed(3)));
219 EXPECT_EQ(V2P0
, P0
.changeElementCount(ElementCount::getFixed(2)));
221 const LLT NXV2S64
= LLT::scalable_vector(2, 64);
222 const LLT NXV3S64
= LLT::scalable_vector(3, 64);
223 const LLT NXV2P0
= LLT::scalable_vector(2, P0
);
225 // Scalable vector to scalar
226 EXPECT_EQ(S64
, NXV2S64
.changeElementCount(ElementCount::getFixed(1)));
227 EXPECT_EQ(P0
, NXV2P0
.changeElementCount(ElementCount::getFixed(1)));
229 // Fixed-width vector to scalable vector
230 EXPECT_EQ(NXV3S64
, V2S64
.changeElementCount(ElementCount::getScalable(3)));
232 // Scalable vector to fixed-width vector
233 EXPECT_EQ(V3P0
, NXV2P0
.changeElementCount(ElementCount::getFixed(3)));
235 // Scalar to scalable vector
236 EXPECT_EQ(NXV2S64
, S64
.changeElementCount(ElementCount::getScalable(2)));
237 EXPECT_EQ(NXV2P0
, P0
.changeElementCount(ElementCount::getScalable(2)));
240 #ifdef GTEST_HAS_DEATH_TEST
243 // Invalid to directly change the element size for pointers.
244 TEST(LowLevelTypeTest
, ChangeElementTypeDeath
) {
245 const LLT P0
= LLT::pointer(0, 32);
246 const LLT V2P0
= LLT::fixed_vector(2, P0
);
248 EXPECT_DEATH(P0
.changeElementSize(64),
249 "invalid to directly change element size for pointers");
250 EXPECT_DEATH(V2P0
.changeElementSize(64),
251 "invalid to directly change element size for pointers");
253 // Make sure this still fails even without a change in size.
254 EXPECT_DEATH(P0
.changeElementSize(32),
255 "invalid to directly change element size for pointers");
256 EXPECT_DEATH(V2P0
.changeElementSize(32),
257 "invalid to directly change element size for pointers");
263 TEST(LowLevelTypeTest
, Pointer
) {
265 DataLayout
DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
267 for (unsigned AS
: {0U, 1U, 127U, 0xffffU
,
268 static_cast<unsigned>(maxUIntN(23)),
269 static_cast<unsigned>(maxUIntN(24))}) {
270 for (ElementCount EC
:
271 {ElementCount::getFixed(2), ElementCount::getFixed(3),
272 ElementCount::getFixed(4), ElementCount::getFixed(256),
273 ElementCount::getFixed(65535), ElementCount::getScalable(2),
274 ElementCount::getScalable(3), ElementCount::getScalable(4),
275 ElementCount::getScalable(256), ElementCount::getScalable(65535)}) {
276 const LLT Ty
= LLT::pointer(AS
, DL
.getPointerSizeInBits(AS
));
277 const LLT VTy
= LLT::vector(EC
, Ty
);
280 ASSERT_TRUE(Ty
.isValid());
281 ASSERT_TRUE(Ty
.isPointer());
282 ASSERT_TRUE(Ty
.isPointerOrPointerVector());
284 ASSERT_FALSE(Ty
.isScalar());
285 ASSERT_FALSE(Ty
.isVector());
287 ASSERT_TRUE(VTy
.isValid());
288 ASSERT_TRUE(VTy
.isVector());
289 ASSERT_TRUE(VTy
.getElementType().isPointer());
290 ASSERT_TRUE(VTy
.isPointerVector());
291 ASSERT_TRUE(VTy
.isPointerOrPointerVector());
293 EXPECT_EQ(Ty
, VTy
.getElementType());
294 EXPECT_EQ(Ty
.getSizeInBits(), VTy
.getScalarSizeInBits());
296 // Test address space.
297 EXPECT_EQ(AS
, Ty
.getAddressSpace());
298 EXPECT_EQ(AS
, VTy
.getElementType().getAddressSpace());
300 // Test equality operators.
301 EXPECT_TRUE(Ty
== Ty
);
302 EXPECT_FALSE(Ty
!= Ty
);
303 EXPECT_TRUE(VTy
== VTy
);
304 EXPECT_FALSE(VTy
!= VTy
);
306 // Test Type->LLT conversion.
307 Type
*IRTy
= PointerType::get(IntegerType::get(C
, 8), AS
);
308 EXPECT_EQ(Ty
, getLLTForType(*IRTy
, DL
));
310 VectorType::get(PointerType::get(IntegerType::get(C
, 8), AS
), EC
);
311 EXPECT_EQ(VTy
, getLLTForType(*IRVTy
, DL
));
316 TEST(LowLevelTypeTest
, Invalid
) {
319 ASSERT_FALSE(Ty
.isValid());
320 ASSERT_FALSE(Ty
.isScalar());
321 ASSERT_FALSE(Ty
.isPointer());
322 ASSERT_FALSE(Ty
.isVector());
323 ASSERT_FALSE(Ty
.isToken());
326 TEST(LowLevelTypeTest
, Divide
) {
327 // Test basic scalar->scalar cases.
328 EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2));
329 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
330 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
332 // Test pointer->scalar
333 EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2));
335 // Test dividing vectors.
336 EXPECT_EQ(LLT::scalar(32), LLT::fixed_vector(2, 32).divide(2));
337 EXPECT_EQ(LLT::fixed_vector(2, 32), LLT::fixed_vector(4, 32).divide(2));
339 // Test vector of pointers
340 EXPECT_EQ(LLT::pointer(1, 64),
341 LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(4));
342 EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(1, 64)),
343 LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(2));
346 TEST(LowLevelTypeTest
, MultiplyElements
) {
347 // Basic scalar->vector cases
348 EXPECT_EQ(LLT::fixed_vector(2, 16), LLT::scalar(16).multiplyElements(2));
349 EXPECT_EQ(LLT::fixed_vector(3, 16), LLT::scalar(16).multiplyElements(3));
350 EXPECT_EQ(LLT::fixed_vector(4, 32), LLT::scalar(32).multiplyElements(4));
351 EXPECT_EQ(LLT::fixed_vector(4, 7), LLT::scalar(7).multiplyElements(4));
353 // Basic vector to vector cases
354 EXPECT_EQ(LLT::fixed_vector(4, 32),
355 LLT::fixed_vector(2, 32).multiplyElements(2));
356 EXPECT_EQ(LLT::fixed_vector(9, 32),
357 LLT::fixed_vector(3, 32).multiplyElements(3));
359 // Pointer to vector of pointers
360 EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(0, 32)),
361 LLT::pointer(0, 32).multiplyElements(2));
362 EXPECT_EQ(LLT::fixed_vector(3, LLT::pointer(1, 32)),
363 LLT::pointer(1, 32).multiplyElements(3));
364 EXPECT_EQ(LLT::fixed_vector(4, LLT::pointer(1, 64)),
365 LLT::pointer(1, 64).multiplyElements(4));
367 // Vector of pointers to vector of pointers
368 EXPECT_EQ(LLT::fixed_vector(8, LLT::pointer(1, 64)),
369 LLT::fixed_vector(2, LLT::pointer(1, 64)).multiplyElements(4));
370 EXPECT_EQ(LLT::fixed_vector(9, LLT::pointer(1, 32)),
371 LLT::fixed_vector(3, LLT::pointer(1, 32)).multiplyElements(3));
374 EXPECT_EQ(LLT::scalable_vector(4, 16),
375 LLT::scalable_vector(2, 16).multiplyElements(2));
376 EXPECT_EQ(LLT::scalable_vector(6, 16),
377 LLT::scalable_vector(2, 16).multiplyElements(3));
378 EXPECT_EQ(LLT::scalable_vector(9, 16),
379 LLT::scalable_vector(3, 16).multiplyElements(3));
380 EXPECT_EQ(LLT::scalable_vector(4, 32),
381 LLT::scalable_vector(2, 32).multiplyElements(2));
382 EXPECT_EQ(LLT::scalable_vector(256, 32),
383 LLT::scalable_vector(8, 32).multiplyElements(32));
385 // Scalable vectors of pointers
386 EXPECT_EQ(LLT::scalable_vector(4, LLT::pointer(0, 32)),
387 LLT::scalable_vector(2, LLT::pointer(0, 32)).multiplyElements(2));
388 EXPECT_EQ(LLT::scalable_vector(32, LLT::pointer(1, 64)),
389 LLT::scalable_vector(8, LLT::pointer(1, 64)).multiplyElements(4));
392 constexpr LLT CELLT
= LLT();
393 constexpr LLT CES32
= LLT::scalar(32);
394 constexpr LLT CEV2S32
= LLT::fixed_vector(2, 32);
395 constexpr LLT CESV2S32
= LLT::scalable_vector(2, 32);
396 constexpr LLT CEP0
= LLT::pointer(0, 32);
397 constexpr LLT CEV2P1
= LLT::fixed_vector(2, LLT::pointer(1, 64));
399 static_assert(!CELLT
.isValid());
400 static_assert(CES32
.isValid());
401 static_assert(CEV2S32
.isValid());
402 static_assert(CESV2S32
.isValid());
403 static_assert(CEP0
.isValid());
404 static_assert(CEV2P1
.isValid());
405 static_assert(CEV2P1
.isVector());
406 static_assert(CEV2P1
.getElementCount() == ElementCount::getFixed(2));
407 static_assert(CEV2P1
.getElementCount() != ElementCount::getFixed(1));
408 static_assert(CEV2S32
.getElementCount() == ElementCount::getFixed(2));
409 static_assert(CEV2S32
.getSizeInBits() == TypeSize::getFixed(64));
410 static_assert(CEV2P1
.getSizeInBits() == TypeSize::getFixed(128));
411 static_assert(CEV2P1
.getScalarType() == LLT::pointer(1, 64));
412 static_assert(CES32
.getScalarType() == CES32
);
413 static_assert(CEV2S32
.getScalarType() == CES32
);
414 static_assert(CEV2S32
.changeElementType(CEP0
) == LLT::fixed_vector(2, CEP0
));
415 static_assert(CEV2S32
.changeElementSize(16) == LLT::fixed_vector(2, 16));
416 static_assert(CEV2S32
.changeElementCount(ElementCount::getFixed(4)) ==
417 LLT::fixed_vector(4, 32));
418 static_assert(CES32
.isByteSized());
419 static_assert(!LLT::scalar(7).isByteSized());
420 static_assert(CES32
.getScalarSizeInBits() == 32);
421 static_assert(CEP0
.getAddressSpace() == 0);
422 static_assert(LLT::pointer(1, 64).getAddressSpace() == 1);
423 static_assert(CEV2S32
.multiplyElements(2) == LLT::fixed_vector(4, 32));
424 static_assert(CEV2S32
.divide(2) == LLT::scalar(32));
425 static_assert(LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)) ==
427 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)) ==
428 LLT::fixed_vector(2, 32));
429 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), CEP0
) ==
430 LLT::fixed_vector(2, CEP0
));
432 TEST(LowLevelTypeTest
, ConstExpr
) {
433 EXPECT_EQ(LLT(), CELLT
);
434 EXPECT_EQ(LLT::scalar(32), CES32
);
435 EXPECT_EQ(LLT::fixed_vector(2, 32), CEV2S32
);
436 EXPECT_EQ(LLT::pointer(0, 32), CEP0
);
437 EXPECT_EQ(LLT::scalable_vector(2, 32), CESV2S32
);
440 TEST(LowLevelTypeTest
, IsFixedVector
) {
441 EXPECT_FALSE(LLT::scalar(32).isFixedVector());
442 EXPECT_TRUE(LLT::fixed_vector(2, 32).isFixedVector());
443 EXPECT_FALSE(LLT::scalable_vector(2, 32).isFixedVector());
444 EXPECT_FALSE(LLT::scalable_vector(1, 32).isFixedVector());
447 TEST(LowLevelTypeTest
, IsScalableVector
) {
448 EXPECT_FALSE(LLT::scalar(32).isScalableVector());
449 EXPECT_FALSE(LLT::fixed_vector(2, 32).isScalableVector());
450 EXPECT_TRUE(LLT::scalable_vector(2, 32).isScalableVector());
451 EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector());