xref: /llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp (revision 97d691b4b3f5ba446d6827fc29fbe15e44a7adac)
1 //===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
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"
16 
17 using namespace llvm;
18 
19 namespace {
20 
21 TEST(LowLevelTypeTest, Token) {
22   LLVMContext C;
23 
24   const LLT TTy = LLT::token();
25 
26   // Test kind.
27   EXPECT_TRUE(TTy.isValid());
28   EXPECT_TRUE(TTy.isScalar());
29   EXPECT_TRUE(TTy.isToken());
30 
31   EXPECT_FALSE(TTy.isPointer());
32   EXPECT_FALSE(TTy.isVector());
33 
34   const LLT STy = LLT::scalar(0);
35   EXPECT_EQ(STy, TTy);
36 }
37 
38 TEST(LowLevelTypeTest, Scalar) {
39   LLVMContext C;
40   DataLayout DL;
41 
42   for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffffU}) {
43     const LLT Ty = LLT::scalar(S);
44 
45     // Test kind.
46     ASSERT_TRUE(Ty.isValid());
47     ASSERT_TRUE(Ty.isScalar());
48 
49     ASSERT_FALSE(Ty.isPointer());
50     ASSERT_FALSE(Ty.isVector());
51 
52     EXPECT_TRUE(S != 0 || Ty.isToken());
53 
54     // Test sizes.
55     EXPECT_EQ(S, Ty.getSizeInBits());
56     EXPECT_EQ(S, Ty.getScalarSizeInBits());
57 
58     // Test equality operators.
59     EXPECT_TRUE(Ty == Ty);
60     EXPECT_FALSE(Ty != Ty);
61 
62     // Test Type->LLT conversion.
63     if (S != 0) {
64       Type *IRTy = IntegerType::get(C, S);
65       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
66     }
67   }
68 }
69 
70 TEST(LowLevelTypeTest, Vector) {
71   LLVMContext C;
72   DataLayout DL;
73 
74   for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffU}) {
75     for (auto EC :
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);
83 
84       // Test the alternative vector().
85       {
86         const LLT VSTy = LLT::vector(EC, STy);
87         EXPECT_EQ(VTy, VSTy);
88       }
89 
90       // Test getElementType().
91       EXPECT_EQ(STy, VTy.getElementType());
92 
93       // Test kind.
94       ASSERT_TRUE(VTy.isValid());
95       ASSERT_TRUE(VTy.isVector());
96 
97       ASSERT_FALSE(VTy.isScalar());
98       ASSERT_FALSE(VTy.isPointer());
99       ASSERT_FALSE(VTy.isToken());
100 
101       // Test sizes.
102       EXPECT_EQ(S, VTy.getScalarSizeInBits());
103       EXPECT_EQ(EC, VTy.getElementCount());
104       if (!EC.isScalable())
105         EXPECT_EQ(S * EC.getFixedValue(), VTy.getSizeInBits());
106       else
107         EXPECT_EQ(TypeSize::getScalable(S * EC.getKnownMinValue()),
108                   VTy.getSizeInBits());
109 
110       // Test equality operators.
111       EXPECT_TRUE(VTy == VTy);
112       EXPECT_FALSE(VTy != VTy);
113 
114       // Test inequality operators on..
115       // ..different kind.
116       EXPECT_NE(VTy, STy);
117 
118       // Test Type->LLT conversion.
119       if (S != 0) {
120         Type *IRSTy = IntegerType::get(C, S);
121         Type *IRTy = VectorType::get(IRSTy, EC);
122         EXPECT_EQ(VTy, getLLTForType(*IRTy, DL));
123       }
124     }
125   }
126 }
127 
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));
136 
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)));
142 
143   // Test with pointer elements.
144   EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(ElementCount::getFixed(1),
145                                                      LLT::pointer(1, 32)));
146   EXPECT_EQ(
147       LLT::fixed_vector(2, LLT::pointer(1, 32)),
148       LLT::scalarOrVector(ElementCount::getFixed(2), LLT::pointer(1, 32)));
149 }
150 
151 TEST(LowLevelTypeTest, ChangeElementType) {
152   const LLT P0 = LLT::pointer(0, 32);
153   const LLT P1 = LLT::pointer(1, 64);
154 
155   const LLT S32 = LLT::scalar(32);
156   const LLT S64 = LLT::scalar(64);
157 
158   const LLT V2S32 = LLT::fixed_vector(2, 32);
159   const LLT V2S64 = LLT::fixed_vector(2, 64);
160 
161   const LLT V2P0 = LLT::fixed_vector(2, P0);
162   const LLT V2P1 = LLT::fixed_vector(2, P1);
163 
164   EXPECT_EQ(S64, S32.changeElementType(S64));
165   EXPECT_EQ(S32, S32.changeElementType(S32));
166 
167   EXPECT_EQ(S32, S64.changeElementSize(32));
168   EXPECT_EQ(S32, S32.changeElementSize(32));
169 
170   EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
171   EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
172 
173   EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
174   EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
175 
176   EXPECT_EQ(P0, S32.changeElementType(P0));
177   EXPECT_EQ(S32, P0.changeElementType(S32));
178 
179   EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
180   EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
181 
182   // Similar tests for scalable vectors.
183   const LLT NXV2S32 = LLT::scalable_vector(2, 32);
184   const LLT NXV2S64 = LLT::scalable_vector(2, 64);
185 
186   const LLT NXV2P0 = LLT::scalable_vector(2, P0);
187   const LLT NXV2P1 = LLT::scalable_vector(2, P1);
188 
189   EXPECT_EQ(NXV2S64, NXV2S32.changeElementType(S64));
190   EXPECT_EQ(NXV2S32, NXV2S64.changeElementType(S32));
191 
192   EXPECT_EQ(NXV2S64, NXV2S32.changeElementSize(64));
193   EXPECT_EQ(NXV2S32, NXV2S64.changeElementSize(32));
194 
195   EXPECT_EQ(NXV2P1, NXV2P0.changeElementType(P1));
196   EXPECT_EQ(NXV2S32, NXV2P0.changeElementType(S32));
197 }
198 
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);
203 
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);
207 
208   // Vector to scalar
209   EXPECT_EQ(S64, V2S64.changeElementCount(ElementCount::getFixed(1)));
210 
211   // Vector to vector
212   EXPECT_EQ(V3S64, V2S64.changeElementCount(ElementCount::getFixed(3)));
213 
214   // Scalar to vector
215   EXPECT_EQ(V2S64, S64.changeElementCount(ElementCount::getFixed(2)));
216 
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)));
220 
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);
224 
225   // Scalable vector to scalar
226   EXPECT_EQ(S64, NXV2S64.changeElementCount(ElementCount::getFixed(1)));
227   EXPECT_EQ(P0, NXV2P0.changeElementCount(ElementCount::getFixed(1)));
228 
229   // Fixed-width vector to scalable vector
230   EXPECT_EQ(NXV3S64, V2S64.changeElementCount(ElementCount::getScalable(3)));
231 
232   // Scalable vector to fixed-width vector
233   EXPECT_EQ(V3P0, NXV2P0.changeElementCount(ElementCount::getFixed(3)));
234 
235   // Scalar to scalable vector
236   EXPECT_EQ(NXV2S64, S64.changeElementCount(ElementCount::getScalable(2)));
237   EXPECT_EQ(NXV2P0, P0.changeElementCount(ElementCount::getScalable(2)));
238 }
239 
240 #ifdef GTEST_HAS_DEATH_TEST
241 #ifndef NDEBUG
242 
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);
247 
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");
252 
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");
258 }
259 
260 #endif
261 #endif
262 
263 TEST(LowLevelTypeTest, Pointer) {
264   LLVMContext C;
265   DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
266 
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);
278 
279       // Test kind.
280       ASSERT_TRUE(Ty.isValid());
281       ASSERT_TRUE(Ty.isPointer());
282       ASSERT_TRUE(Ty.isPointerOrPointerVector());
283 
284       ASSERT_FALSE(Ty.isScalar());
285       ASSERT_FALSE(Ty.isVector());
286 
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());
292 
293       EXPECT_EQ(Ty, VTy.getElementType());
294       EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
295 
296       // Test address space.
297       EXPECT_EQ(AS, Ty.getAddressSpace());
298       EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
299 
300       // Test equality operators.
301       EXPECT_TRUE(Ty == Ty);
302       EXPECT_FALSE(Ty != Ty);
303       EXPECT_TRUE(VTy == VTy);
304       EXPECT_FALSE(VTy != VTy);
305 
306       // Test Type->LLT conversion.
307       Type *IRTy = PointerType::get(C, AS);
308       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
309       Type *IRVTy = VectorType::get(PointerType::get(C, AS), EC);
310       EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
311     }
312   }
313 }
314 
315 TEST(LowLevelTypeTest, Invalid) {
316   const LLT Ty;
317 
318   ASSERT_FALSE(Ty.isValid());
319   ASSERT_FALSE(Ty.isScalar());
320   ASSERT_FALSE(Ty.isPointer());
321   ASSERT_FALSE(Ty.isVector());
322   ASSERT_FALSE(Ty.isToken());
323 }
324 
325 TEST(LowLevelTypeTest, Divide) {
326   // Test basic scalar->scalar cases.
327   EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2));
328   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
329   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
330 
331   // Test pointer->scalar
332   EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2));
333 
334   // Test dividing vectors.
335   EXPECT_EQ(LLT::scalar(32), LLT::fixed_vector(2, 32).divide(2));
336   EXPECT_EQ(LLT::fixed_vector(2, 32), LLT::fixed_vector(4, 32).divide(2));
337 
338   // Test vector of pointers
339   EXPECT_EQ(LLT::pointer(1, 64),
340             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(4));
341   EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(1, 64)),
342             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(2));
343 }
344 
345 TEST(LowLevelTypeTest, MultiplyElements) {
346   // Basic scalar->vector cases
347   EXPECT_EQ(LLT::fixed_vector(2, 16), LLT::scalar(16).multiplyElements(2));
348   EXPECT_EQ(LLT::fixed_vector(3, 16), LLT::scalar(16).multiplyElements(3));
349   EXPECT_EQ(LLT::fixed_vector(4, 32), LLT::scalar(32).multiplyElements(4));
350   EXPECT_EQ(LLT::fixed_vector(4, 7), LLT::scalar(7).multiplyElements(4));
351 
352   // Basic vector to vector cases
353   EXPECT_EQ(LLT::fixed_vector(4, 32),
354             LLT::fixed_vector(2, 32).multiplyElements(2));
355   EXPECT_EQ(LLT::fixed_vector(9, 32),
356             LLT::fixed_vector(3, 32).multiplyElements(3));
357 
358   // Pointer to vector of pointers
359   EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(0, 32)),
360             LLT::pointer(0, 32).multiplyElements(2));
361   EXPECT_EQ(LLT::fixed_vector(3, LLT::pointer(1, 32)),
362             LLT::pointer(1, 32).multiplyElements(3));
363   EXPECT_EQ(LLT::fixed_vector(4, LLT::pointer(1, 64)),
364             LLT::pointer(1, 64).multiplyElements(4));
365 
366   // Vector of pointers to vector of pointers
367   EXPECT_EQ(LLT::fixed_vector(8, LLT::pointer(1, 64)),
368             LLT::fixed_vector(2, LLT::pointer(1, 64)).multiplyElements(4));
369   EXPECT_EQ(LLT::fixed_vector(9, LLT::pointer(1, 32)),
370             LLT::fixed_vector(3, LLT::pointer(1, 32)).multiplyElements(3));
371 
372   // Scalable vectors
373   EXPECT_EQ(LLT::scalable_vector(4, 16),
374             LLT::scalable_vector(2, 16).multiplyElements(2));
375   EXPECT_EQ(LLT::scalable_vector(6, 16),
376             LLT::scalable_vector(2, 16).multiplyElements(3));
377   EXPECT_EQ(LLT::scalable_vector(9, 16),
378             LLT::scalable_vector(3, 16).multiplyElements(3));
379   EXPECT_EQ(LLT::scalable_vector(4, 32),
380             LLT::scalable_vector(2, 32).multiplyElements(2));
381   EXPECT_EQ(LLT::scalable_vector(256, 32),
382             LLT::scalable_vector(8, 32).multiplyElements(32));
383 
384   // Scalable vectors of pointers
385   EXPECT_EQ(LLT::scalable_vector(4, LLT::pointer(0, 32)),
386             LLT::scalable_vector(2, LLT::pointer(0, 32)).multiplyElements(2));
387   EXPECT_EQ(LLT::scalable_vector(32, LLT::pointer(1, 64)),
388             LLT::scalable_vector(8, LLT::pointer(1, 64)).multiplyElements(4));
389 }
390 
391 constexpr LLT CELLT = LLT();
392 constexpr LLT CES32 = LLT::scalar(32);
393 constexpr LLT CEV2S32 = LLT::fixed_vector(2, 32);
394 constexpr LLT CESV2S32 = LLT::scalable_vector(2, 32);
395 constexpr LLT CEP0 = LLT::pointer(0, 32);
396 constexpr LLT CEV2P1 = LLT::fixed_vector(2, LLT::pointer(1, 64));
397 
398 static_assert(!CELLT.isValid());
399 static_assert(CES32.isValid());
400 static_assert(CEV2S32.isValid());
401 static_assert(CESV2S32.isValid());
402 static_assert(CEP0.isValid());
403 static_assert(CEV2P1.isValid());
404 static_assert(CEV2P1.isVector());
405 static_assert(CEV2P1.getElementCount() == ElementCount::getFixed(2));
406 static_assert(CEV2P1.getElementCount() != ElementCount::getFixed(1));
407 static_assert(CEV2S32.getElementCount() == ElementCount::getFixed(2));
408 static_assert(CEV2S32.getSizeInBits() == TypeSize::getFixed(64));
409 static_assert(CEV2P1.getSizeInBits() == TypeSize::getFixed(128));
410 static_assert(CEV2P1.getScalarType() == LLT::pointer(1, 64));
411 static_assert(CES32.getScalarType() == CES32);
412 static_assert(CEV2S32.getScalarType() == CES32);
413 static_assert(CEV2S32.changeElementType(CEP0) == LLT::fixed_vector(2, CEP0));
414 static_assert(CEV2S32.changeElementSize(16) == LLT::fixed_vector(2, 16));
415 static_assert(CEV2S32.changeElementCount(ElementCount::getFixed(4)) ==
416               LLT::fixed_vector(4, 32));
417 static_assert(CES32.isByteSized());
418 static_assert(!LLT::scalar(7).isByteSized());
419 static_assert(CES32.getScalarSizeInBits() == 32);
420 static_assert(CEP0.getAddressSpace() == 0);
421 static_assert(LLT::pointer(1, 64).getAddressSpace() == 1);
422 static_assert(CEV2S32.multiplyElements(2) == LLT::fixed_vector(4, 32));
423 static_assert(CEV2S32.divide(2) == LLT::scalar(32));
424 static_assert(LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)) ==
425               LLT::scalar(32));
426 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)) ==
427               LLT::fixed_vector(2, 32));
428 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), CEP0) ==
429               LLT::fixed_vector(2, CEP0));
430 
431 TEST(LowLevelTypeTest, ConstExpr) {
432   EXPECT_EQ(LLT(), CELLT);
433   EXPECT_EQ(LLT::scalar(32), CES32);
434   EXPECT_EQ(LLT::fixed_vector(2, 32), CEV2S32);
435   EXPECT_EQ(LLT::pointer(0, 32), CEP0);
436   EXPECT_EQ(LLT::scalable_vector(2, 32), CESV2S32);
437 }
438 
439 TEST(LowLevelTypeTest, IsFixedVector) {
440   EXPECT_FALSE(LLT::scalar(32).isFixedVector());
441   EXPECT_TRUE(LLT::fixed_vector(2, 32).isFixedVector());
442   EXPECT_FALSE(LLT::scalable_vector(2, 32).isFixedVector());
443   EXPECT_FALSE(LLT::scalable_vector(1, 32).isFixedVector());
444 }
445 
446 TEST(LowLevelTypeTest, IsScalableVector) {
447   EXPECT_FALSE(LLT::scalar(32).isScalableVector());
448   EXPECT_FALSE(LLT::fixed_vector(2, 32).isScalableVector());
449   EXPECT_TRUE(LLT::scalable_vector(2, 32).isScalableVector());
450   EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector());
451 }
452 }
453