xref: /llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp (revision 111fcb0df02db3db8bed1d5db6d911b7ce544d92)
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, Scalar) {
22   LLVMContext C;
23   DataLayout DL("");
24 
25   for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffffU}) {
26     const LLT Ty = LLT::scalar(S);
27 
28     // Test kind.
29     ASSERT_TRUE(Ty.isValid());
30     ASSERT_TRUE(Ty.isScalar());
31 
32     ASSERT_FALSE(Ty.isPointer());
33     ASSERT_FALSE(Ty.isVector());
34 
35     // Test sizes.
36     EXPECT_EQ(S, Ty.getSizeInBits());
37     EXPECT_EQ(S, Ty.getScalarSizeInBits());
38 
39     // Test equality operators.
40     EXPECT_TRUE(Ty == Ty);
41     EXPECT_FALSE(Ty != Ty);
42 
43     // Test Type->LLT conversion.
44     if (S != 0) {
45       Type *IRTy = IntegerType::get(C, S);
46       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
47     }
48   }
49 }
50 
51 TEST(LowLevelTypeTest, Vector) {
52   LLVMContext C;
53   DataLayout DL("");
54 
55   for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffU}) {
56     for (auto EC :
57          {ElementCount::getFixed(2), ElementCount::getFixed(3),
58           ElementCount::getFixed(4), ElementCount::getFixed(32),
59           ElementCount::getFixed(0xff), ElementCount::getScalable(2),
60           ElementCount::getScalable(3), ElementCount::getScalable(4),
61           ElementCount::getScalable(32), ElementCount::getScalable(0xff)}) {
62       const LLT STy = LLT::scalar(S);
63       const LLT VTy = LLT::vector(EC, S);
64 
65       // Test the alternative vector().
66       {
67         const LLT VSTy = LLT::vector(EC, STy);
68         EXPECT_EQ(VTy, VSTy);
69       }
70 
71       // Test getElementType().
72       EXPECT_EQ(STy, VTy.getElementType());
73 
74       // Test kind.
75       ASSERT_TRUE(VTy.isValid());
76       ASSERT_TRUE(VTy.isVector());
77 
78       ASSERT_FALSE(VTy.isScalar());
79       ASSERT_FALSE(VTy.isPointer());
80 
81       // Test sizes.
82       EXPECT_EQ(S, VTy.getScalarSizeInBits());
83       EXPECT_EQ(EC, VTy.getElementCount());
84       if (!EC.isScalable())
85         EXPECT_EQ(S * EC.getFixedValue(), VTy.getSizeInBits());
86       else
87         EXPECT_EQ(TypeSize::Scalable(S * EC.getKnownMinValue()),
88                   VTy.getSizeInBits());
89 
90       // Test equality operators.
91       EXPECT_TRUE(VTy == VTy);
92       EXPECT_FALSE(VTy != VTy);
93 
94       // Test inequality operators on..
95       // ..different kind.
96       EXPECT_NE(VTy, STy);
97 
98       // Test Type->LLT conversion.
99       if (S != 0) {
100         Type *IRSTy = IntegerType::get(C, S);
101         Type *IRTy = VectorType::get(IRSTy, EC);
102         EXPECT_EQ(VTy, getLLTForType(*IRTy, DL));
103       }
104     }
105   }
106 }
107 
108 TEST(LowLevelTypeTest, ScalarOrVector) {
109   // Test version with number of bits for scalar type.
110   EXPECT_EQ(LLT::scalar(32),
111             LLT::scalarOrVector(ElementCount::getFixed(1), 32));
112   EXPECT_EQ(LLT::fixed_vector(2, 32),
113             LLT::scalarOrVector(ElementCount::getFixed(2), 32));
114   EXPECT_EQ(LLT::scalable_vector(1, 32),
115             LLT::scalarOrVector(ElementCount::getScalable(1), 32));
116 
117   // Test version with LLT for scalar type.
118   EXPECT_EQ(LLT::scalar(32),
119             LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)));
120   EXPECT_EQ(LLT::fixed_vector(2, 32),
121             LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)));
122 
123   // Test with pointer elements.
124   EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(ElementCount::getFixed(1),
125                                                      LLT::pointer(1, 32)));
126   EXPECT_EQ(
127       LLT::fixed_vector(2, LLT::pointer(1, 32)),
128       LLT::scalarOrVector(ElementCount::getFixed(2), LLT::pointer(1, 32)));
129 }
130 
131 TEST(LowLevelTypeTest, ChangeElementType) {
132   const LLT P0 = LLT::pointer(0, 32);
133   const LLT P1 = LLT::pointer(1, 64);
134 
135   const LLT S32 = LLT::scalar(32);
136   const LLT S64 = LLT::scalar(64);
137 
138   const LLT V2S32 = LLT::fixed_vector(2, 32);
139   const LLT V2S64 = LLT::fixed_vector(2, 64);
140 
141   const LLT V2P0 = LLT::fixed_vector(2, P0);
142   const LLT V2P1 = LLT::fixed_vector(2, P1);
143 
144   EXPECT_EQ(S64, S32.changeElementType(S64));
145   EXPECT_EQ(S32, S32.changeElementType(S32));
146 
147   EXPECT_EQ(S32, S64.changeElementSize(32));
148   EXPECT_EQ(S32, S32.changeElementSize(32));
149 
150   EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
151   EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
152 
153   EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
154   EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
155 
156   EXPECT_EQ(P0, S32.changeElementType(P0));
157   EXPECT_EQ(S32, P0.changeElementType(S32));
158 
159   EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
160   EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
161 
162   // Similar tests for scalable vectors.
163   const LLT NXV2S32 = LLT::scalable_vector(2, 32);
164   const LLT NXV2S64 = LLT::scalable_vector(2, 64);
165 
166   const LLT NXV2P0 = LLT::scalable_vector(2, P0);
167   const LLT NXV2P1 = LLT::scalable_vector(2, P1);
168 
169   EXPECT_EQ(NXV2S64, NXV2S32.changeElementType(S64));
170   EXPECT_EQ(NXV2S32, NXV2S64.changeElementType(S32));
171 
172   EXPECT_EQ(NXV2S64, NXV2S32.changeElementSize(64));
173   EXPECT_EQ(NXV2S32, NXV2S64.changeElementSize(32));
174 
175   EXPECT_EQ(NXV2P1, NXV2P0.changeElementType(P1));
176   EXPECT_EQ(NXV2S32, NXV2P0.changeElementType(S32));
177 }
178 
179 TEST(LowLevelTypeTest, ChangeNumElements) {
180   const LLT P0 = LLT::pointer(0, 32);
181   const LLT V2P0 = LLT::fixed_vector(2, P0);
182   const LLT V3P0 = LLT::fixed_vector(3, P0);
183 
184   const LLT S64 = LLT::scalar(64);
185   const LLT V2S64 = LLT::fixed_vector(2, 64);
186   const LLT V3S64 = LLT::fixed_vector(3, 64);
187 
188   // Vector to scalar
189   EXPECT_EQ(S64, V2S64.changeElementCount(ElementCount::getFixed(1)));
190 
191   // Vector to vector
192   EXPECT_EQ(V3S64, V2S64.changeElementCount(ElementCount::getFixed(3)));
193 
194   // Scalar to vector
195   EXPECT_EQ(V2S64, S64.changeElementCount(ElementCount::getFixed(2)));
196 
197   EXPECT_EQ(P0, V2P0.changeElementCount(ElementCount::getFixed(1)));
198   EXPECT_EQ(V3P0, V2P0.changeElementCount(ElementCount::getFixed(3)));
199   EXPECT_EQ(V2P0, P0.changeElementCount(ElementCount::getFixed(2)));
200 
201   const LLT NXV2S64 = LLT::scalable_vector(2, 64);
202   const LLT NXV3S64 = LLT::scalable_vector(3, 64);
203   const LLT NXV2P0 = LLT::scalable_vector(2, P0);
204 
205   // Scalable vector to scalar
206   EXPECT_EQ(S64, NXV2S64.changeElementCount(ElementCount::getFixed(1)));
207   EXPECT_EQ(P0, NXV2P0.changeElementCount(ElementCount::getFixed(1)));
208 
209   // Fixed-width vector to scalable vector
210   EXPECT_EQ(NXV3S64, V2S64.changeElementCount(ElementCount::getScalable(3)));
211 
212   // Scalable vector to fixed-width vector
213   EXPECT_EQ(V3P0, NXV2P0.changeElementCount(ElementCount::getFixed(3)));
214 
215   // Scalar to scalable vector
216   EXPECT_EQ(NXV2S64, S64.changeElementCount(ElementCount::getScalable(2)));
217   EXPECT_EQ(NXV2P0, P0.changeElementCount(ElementCount::getScalable(2)));
218 }
219 
220 #ifdef GTEST_HAS_DEATH_TEST
221 #ifndef NDEBUG
222 
223 // Invalid to directly change the element size for pointers.
224 TEST(LowLevelTypeTest, ChangeElementTypeDeath) {
225   const LLT P0 = LLT::pointer(0, 32);
226   const LLT V2P0 = LLT::fixed_vector(2, P0);
227 
228   EXPECT_DEATH(P0.changeElementSize(64),
229                "invalid to directly change element size for pointers");
230   EXPECT_DEATH(V2P0.changeElementSize(64),
231                "invalid to directly change element size for pointers");
232 
233   // Make sure this still fails even without a change in size.
234   EXPECT_DEATH(P0.changeElementSize(32),
235                "invalid to directly change element size for pointers");
236   EXPECT_DEATH(V2P0.changeElementSize(32),
237                "invalid to directly change element size for pointers");
238 }
239 
240 #endif
241 #endif
242 
243 TEST(LowLevelTypeTest, Pointer) {
244   LLVMContext C;
245   DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
246 
247   for (unsigned AS : {0U, 1U, 127U, 0xffffU,
248         static_cast<unsigned>(maxUIntN(23)),
249         static_cast<unsigned>(maxUIntN(24))}) {
250     for (ElementCount EC :
251          {ElementCount::getFixed(2), ElementCount::getFixed(3),
252           ElementCount::getFixed(4), ElementCount::getFixed(256),
253           ElementCount::getFixed(65535), ElementCount::getScalable(2),
254           ElementCount::getScalable(3), ElementCount::getScalable(4),
255           ElementCount::getScalable(256), ElementCount::getScalable(65535)}) {
256       const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
257       const LLT VTy = LLT::vector(EC, Ty);
258 
259       // Test kind.
260       ASSERT_TRUE(Ty.isValid());
261       ASSERT_TRUE(Ty.isPointer());
262 
263       ASSERT_FALSE(Ty.isScalar());
264       ASSERT_FALSE(Ty.isVector());
265 
266       ASSERT_TRUE(VTy.isValid());
267       ASSERT_TRUE(VTy.isVector());
268       ASSERT_TRUE(VTy.getElementType().isPointer());
269 
270       EXPECT_EQ(Ty, VTy.getElementType());
271       EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
272 
273       // Test address space.
274       EXPECT_EQ(AS, Ty.getAddressSpace());
275       EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
276 
277       // Test equality operators.
278       EXPECT_TRUE(Ty == Ty);
279       EXPECT_FALSE(Ty != Ty);
280       EXPECT_TRUE(VTy == VTy);
281       EXPECT_FALSE(VTy != VTy);
282 
283       // Test Type->LLT conversion.
284       Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
285       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
286       Type *IRVTy =
287           VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), EC);
288       EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
289     }
290   }
291 }
292 
293 TEST(LowLevelTypeTest, Invalid) {
294   const LLT Ty;
295 
296   ASSERT_FALSE(Ty.isValid());
297   ASSERT_FALSE(Ty.isScalar());
298   ASSERT_FALSE(Ty.isPointer());
299   ASSERT_FALSE(Ty.isVector());
300 }
301 
302 TEST(LowLevelTypeTest, Divide) {
303   // Test basic scalar->scalar cases.
304   EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2));
305   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
306   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
307 
308   // Test pointer->scalar
309   EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2));
310 
311   // Test dividing vectors.
312   EXPECT_EQ(LLT::scalar(32), LLT::fixed_vector(2, 32).divide(2));
313   EXPECT_EQ(LLT::fixed_vector(2, 32), LLT::fixed_vector(4, 32).divide(2));
314 
315   // Test vector of pointers
316   EXPECT_EQ(LLT::pointer(1, 64),
317             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(4));
318   EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(1, 64)),
319             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(2));
320 }
321 
322 TEST(LowLevelTypeTest, MultiplyElements) {
323   // Basic scalar->vector cases
324   EXPECT_EQ(LLT::fixed_vector(2, 16), LLT::scalar(16).multiplyElements(2));
325   EXPECT_EQ(LLT::fixed_vector(3, 16), LLT::scalar(16).multiplyElements(3));
326   EXPECT_EQ(LLT::fixed_vector(4, 32), LLT::scalar(32).multiplyElements(4));
327   EXPECT_EQ(LLT::fixed_vector(4, 7), LLT::scalar(7).multiplyElements(4));
328 
329   // Basic vector to vector cases
330   EXPECT_EQ(LLT::fixed_vector(4, 32),
331             LLT::fixed_vector(2, 32).multiplyElements(2));
332   EXPECT_EQ(LLT::fixed_vector(9, 32),
333             LLT::fixed_vector(3, 32).multiplyElements(3));
334 
335   // Pointer to vector of pointers
336   EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(0, 32)),
337             LLT::pointer(0, 32).multiplyElements(2));
338   EXPECT_EQ(LLT::fixed_vector(3, LLT::pointer(1, 32)),
339             LLT::pointer(1, 32).multiplyElements(3));
340   EXPECT_EQ(LLT::fixed_vector(4, LLT::pointer(1, 64)),
341             LLT::pointer(1, 64).multiplyElements(4));
342 
343   // Vector of pointers to vector of pointers
344   EXPECT_EQ(LLT::fixed_vector(8, LLT::pointer(1, 64)),
345             LLT::fixed_vector(2, LLT::pointer(1, 64)).multiplyElements(4));
346   EXPECT_EQ(LLT::fixed_vector(9, LLT::pointer(1, 32)),
347             LLT::fixed_vector(3, LLT::pointer(1, 32)).multiplyElements(3));
348 
349   // Scalable vectors
350   EXPECT_EQ(LLT::scalable_vector(4, 16),
351             LLT::scalable_vector(2, 16).multiplyElements(2));
352   EXPECT_EQ(LLT::scalable_vector(6, 16),
353             LLT::scalable_vector(2, 16).multiplyElements(3));
354   EXPECT_EQ(LLT::scalable_vector(9, 16),
355             LLT::scalable_vector(3, 16).multiplyElements(3));
356   EXPECT_EQ(LLT::scalable_vector(4, 32),
357             LLT::scalable_vector(2, 32).multiplyElements(2));
358   EXPECT_EQ(LLT::scalable_vector(256, 32),
359             LLT::scalable_vector(8, 32).multiplyElements(32));
360 
361   // Scalable vectors of pointers
362   EXPECT_EQ(LLT::scalable_vector(4, LLT::pointer(0, 32)),
363             LLT::scalable_vector(2, LLT::pointer(0, 32)).multiplyElements(2));
364   EXPECT_EQ(LLT::scalable_vector(32, LLT::pointer(1, 64)),
365             LLT::scalable_vector(8, LLT::pointer(1, 64)).multiplyElements(4));
366 }
367 
368 constexpr LLT CELLT = LLT();
369 constexpr LLT CES32 = LLT::scalar(32);
370 constexpr LLT CEV2S32 = LLT::fixed_vector(2, 32);
371 constexpr LLT CESV2S32 = LLT::scalable_vector(2, 32);
372 constexpr LLT CEP0 = LLT::pointer(0, 32);
373 constexpr LLT CEV2P1 = LLT::fixed_vector(2, LLT::pointer(1, 64));
374 
375 static_assert(!CELLT.isValid());
376 static_assert(CES32.isValid());
377 static_assert(CEV2S32.isValid());
378 static_assert(CESV2S32.isValid());
379 static_assert(CEP0.isValid());
380 static_assert(CEV2P1.isValid());
381 static_assert(CEV2P1.isVector());
382 static_assert(CEV2P1.getElementCount() == ElementCount::getFixed(2));
383 static_assert(CEV2P1.getElementCount() != ElementCount::getFixed(1));
384 static_assert(CEV2S32.getElementCount() == ElementCount::getFixed(2));
385 static_assert(CEV2S32.getSizeInBits() == TypeSize::getFixed(64));
386 static_assert(CEV2P1.getSizeInBits() == TypeSize::getFixed(128));
387 static_assert(CEV2P1.getScalarType() == LLT::pointer(1, 64));
388 static_assert(CES32.getScalarType() == CES32);
389 static_assert(CEV2S32.getScalarType() == CES32);
390 static_assert(CEV2S32.changeElementType(CEP0) == LLT::fixed_vector(2, CEP0));
391 static_assert(CEV2S32.changeElementSize(16) == LLT::fixed_vector(2, 16));
392 static_assert(CEV2S32.changeElementCount(ElementCount::getFixed(4)) ==
393               LLT::fixed_vector(4, 32));
394 static_assert(CES32.isByteSized());
395 static_assert(!LLT::scalar(7).isByteSized());
396 static_assert(CES32.getScalarSizeInBits() == 32);
397 static_assert(CEP0.getAddressSpace() == 0);
398 static_assert(LLT::pointer(1, 64).getAddressSpace() == 1);
399 static_assert(CEV2S32.multiplyElements(2) == LLT::fixed_vector(4, 32));
400 static_assert(CEV2S32.divide(2) == LLT::scalar(32));
401 static_assert(LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)) ==
402               LLT::scalar(32));
403 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)) ==
404               LLT::fixed_vector(2, 32));
405 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), CEP0) ==
406               LLT::fixed_vector(2, CEP0));
407 
408 TEST(LowLevelTypeTest, ConstExpr) {
409   EXPECT_EQ(LLT(), CELLT);
410   EXPECT_EQ(LLT::scalar(32), CES32);
411   EXPECT_EQ(LLT::fixed_vector(2, 32), CEV2S32);
412   EXPECT_EQ(LLT::pointer(0, 32), CEP0);
413   EXPECT_EQ(LLT::scalable_vector(2, 32), CESV2S32);
414 }
415 }
416