xref: /llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp (revision aeab9d9570ac8cb554aff6e1af24a471fdf5b4e5)
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/LowLevelType.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 : {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     Type *IRTy = IntegerType::get(C, S);
45     EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
46   }
47 }
48 
49 TEST(LowLevelTypeTest, Vector) {
50   LLVMContext C;
51   DataLayout DL("");
52 
53   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) {
54     for (auto EC :
55          {ElementCount::getFixed(2), ElementCount::getFixed(3),
56           ElementCount::getFixed(4), ElementCount::getFixed(32),
57           ElementCount::getFixed(0xff), ElementCount::getScalable(2),
58           ElementCount::getScalable(3), ElementCount::getScalable(4),
59           ElementCount::getScalable(32), ElementCount::getScalable(0xff)}) {
60       const LLT STy = LLT::scalar(S);
61       const LLT VTy = LLT::vector(EC, S);
62 
63       // Test the alternative vector().
64       {
65         const LLT VSTy = LLT::vector(EC, STy);
66         EXPECT_EQ(VTy, VSTy);
67       }
68 
69       // Test getElementType().
70       EXPECT_EQ(STy, VTy.getElementType());
71 
72       // Test kind.
73       ASSERT_TRUE(VTy.isValid());
74       ASSERT_TRUE(VTy.isVector());
75 
76       ASSERT_FALSE(VTy.isScalar());
77       ASSERT_FALSE(VTy.isPointer());
78 
79       // Test sizes.
80       EXPECT_EQ(S, VTy.getScalarSizeInBits());
81       EXPECT_EQ(EC, VTy.getElementCount());
82       if (!EC.isScalable())
83         EXPECT_EQ(S * EC.getFixedValue(), VTy.getSizeInBits());
84       else
85         EXPECT_EQ(TypeSize::Scalable(S * EC.getKnownMinValue()),
86                   VTy.getSizeInBits());
87 
88       // Test equality operators.
89       EXPECT_TRUE(VTy == VTy);
90       EXPECT_FALSE(VTy != VTy);
91 
92       // Test inequality operators on..
93       // ..different kind.
94       EXPECT_NE(VTy, STy);
95 
96       // Test Type->LLT conversion.
97       Type *IRSTy = IntegerType::get(C, S);
98       Type *IRTy = VectorType::get(IRSTy, EC);
99       EXPECT_EQ(VTy, getLLTForType(*IRTy, DL));
100     }
101   }
102 }
103 
104 TEST(LowLevelTypeTest, ScalarOrVector) {
105   // Test version with number of bits for scalar type.
106   EXPECT_EQ(LLT::scalar(32),
107             LLT::scalarOrVector(ElementCount::getFixed(1), 32));
108   EXPECT_EQ(LLT::fixed_vector(2, 32),
109             LLT::scalarOrVector(ElementCount::getFixed(2), 32));
110   EXPECT_EQ(LLT::scalable_vector(1, 32),
111             LLT::scalarOrVector(ElementCount::getScalable(1), 32));
112 
113   // Test version with LLT for scalar type.
114   EXPECT_EQ(LLT::scalar(32),
115             LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)));
116   EXPECT_EQ(LLT::fixed_vector(2, 32),
117             LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)));
118 
119   // Test with pointer elements.
120   EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(ElementCount::getFixed(1),
121                                                      LLT::pointer(1, 32)));
122   EXPECT_EQ(
123       LLT::fixed_vector(2, LLT::pointer(1, 32)),
124       LLT::scalarOrVector(ElementCount::getFixed(2), LLT::pointer(1, 32)));
125 }
126 
127 TEST(LowLevelTypeTest, ChangeElementType) {
128   const LLT P0 = LLT::pointer(0, 32);
129   const LLT P1 = LLT::pointer(1, 64);
130 
131   const LLT S32 = LLT::scalar(32);
132   const LLT S64 = LLT::scalar(64);
133 
134   const LLT V2S32 = LLT::fixed_vector(2, 32);
135   const LLT V2S64 = LLT::fixed_vector(2, 64);
136 
137   const LLT V2P0 = LLT::fixed_vector(2, P0);
138   const LLT V2P1 = LLT::fixed_vector(2, P1);
139 
140   EXPECT_EQ(S64, S32.changeElementType(S64));
141   EXPECT_EQ(S32, S32.changeElementType(S32));
142 
143   EXPECT_EQ(S32, S64.changeElementSize(32));
144   EXPECT_EQ(S32, S32.changeElementSize(32));
145 
146   EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
147   EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
148 
149   EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
150   EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
151 
152   EXPECT_EQ(P0, S32.changeElementType(P0));
153   EXPECT_EQ(S32, P0.changeElementType(S32));
154 
155   EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
156   EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
157 
158   // Similar tests for for scalable vectors.
159   const LLT NXV2S32 = LLT::scalable_vector(2, 32);
160   const LLT NXV2S64 = LLT::scalable_vector(2, 64);
161 
162   const LLT NXV2P0 = LLT::scalable_vector(2, P0);
163   const LLT NXV2P1 = LLT::scalable_vector(2, P1);
164 
165   EXPECT_EQ(NXV2S64, NXV2S32.changeElementType(S64));
166   EXPECT_EQ(NXV2S32, NXV2S64.changeElementType(S32));
167 
168   EXPECT_EQ(NXV2S64, NXV2S32.changeElementSize(64));
169   EXPECT_EQ(NXV2S32, NXV2S64.changeElementSize(32));
170 
171   EXPECT_EQ(NXV2P1, NXV2P0.changeElementType(P1));
172   EXPECT_EQ(NXV2S32, NXV2P0.changeElementType(S32));
173 }
174 
175 TEST(LowLevelTypeTest, ChangeNumElements) {
176   const LLT P0 = LLT::pointer(0, 32);
177   const LLT V2P0 = LLT::fixed_vector(2, P0);
178   const LLT V3P0 = LLT::fixed_vector(3, P0);
179 
180   const LLT S64 = LLT::scalar(64);
181   const LLT V2S64 = LLT::fixed_vector(2, 64);
182   const LLT V3S64 = LLT::fixed_vector(3, 64);
183 
184   // Vector to scalar
185   EXPECT_EQ(S64, V2S64.changeElementCount(ElementCount::getFixed(1)));
186 
187   // Vector to vector
188   EXPECT_EQ(V3S64, V2S64.changeElementCount(ElementCount::getFixed(3)));
189 
190   // Scalar to vector
191   EXPECT_EQ(V2S64, S64.changeElementCount(ElementCount::getFixed(2)));
192 
193   EXPECT_EQ(P0, V2P0.changeElementCount(ElementCount::getFixed(1)));
194   EXPECT_EQ(V3P0, V2P0.changeElementCount(ElementCount::getFixed(3)));
195   EXPECT_EQ(V2P0, P0.changeElementCount(ElementCount::getFixed(2)));
196 
197   const LLT NXV2S64 = LLT::scalable_vector(2, 64);
198   const LLT NXV3S64 = LLT::scalable_vector(3, 64);
199   const LLT NXV2P0 = LLT::scalable_vector(2, P0);
200 
201   // Scalable vector to scalar
202   EXPECT_EQ(S64, NXV2S64.changeElementCount(ElementCount::getFixed(1)));
203   EXPECT_EQ(P0, NXV2P0.changeElementCount(ElementCount::getFixed(1)));
204 
205   // Fixed-width vector to scalable vector
206   EXPECT_EQ(NXV3S64, V2S64.changeElementCount(ElementCount::getScalable(3)));
207 
208   // Scalable vector to fixed-width vector
209   EXPECT_EQ(V3P0, NXV2P0.changeElementCount(ElementCount::getFixed(3)));
210 
211   // Scalar to scalable vector
212   EXPECT_EQ(NXV2S64, S64.changeElementCount(ElementCount::getScalable(2)));
213   EXPECT_EQ(NXV2P0, P0.changeElementCount(ElementCount::getScalable(2)));
214 }
215 
216 #ifdef GTEST_HAS_DEATH_TEST
217 #ifndef NDEBUG
218 
219 // Invalid to directly change the element size for pointers.
220 TEST(LowLevelTypeTest, ChangeElementTypeDeath) {
221   const LLT P0 = LLT::pointer(0, 32);
222   const LLT V2P0 = LLT::fixed_vector(2, P0);
223 
224   EXPECT_DEATH(P0.changeElementSize(64),
225                "invalid to directly change element size for pointers");
226   EXPECT_DEATH(V2P0.changeElementSize(64),
227                "invalid to directly change element size for pointers");
228 
229   // Make sure this still fails even without a change in size.
230   EXPECT_DEATH(P0.changeElementSize(32),
231                "invalid to directly change element size for pointers");
232   EXPECT_DEATH(V2P0.changeElementSize(32),
233                "invalid to directly change element size for pointers");
234 }
235 
236 #endif
237 #endif
238 
239 TEST(LowLevelTypeTest, Pointer) {
240   LLVMContext C;
241   DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
242 
243   for (unsigned AS : {0U, 1U, 127U, 0xffffU,
244         static_cast<unsigned>(maxUIntN(23)),
245         static_cast<unsigned>(maxUIntN(24))}) {
246     for (ElementCount EC :
247          {ElementCount::getFixed(2), ElementCount::getFixed(3),
248           ElementCount::getFixed(4), ElementCount::getFixed(256),
249           ElementCount::getFixed(65535), ElementCount::getScalable(2),
250           ElementCount::getScalable(3), ElementCount::getScalable(4),
251           ElementCount::getScalable(256), ElementCount::getScalable(65535)}) {
252       const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
253       const LLT VTy = LLT::vector(EC, Ty);
254 
255       // Test kind.
256       ASSERT_TRUE(Ty.isValid());
257       ASSERT_TRUE(Ty.isPointer());
258 
259       ASSERT_FALSE(Ty.isScalar());
260       ASSERT_FALSE(Ty.isVector());
261 
262       ASSERT_TRUE(VTy.isValid());
263       ASSERT_TRUE(VTy.isVector());
264       ASSERT_TRUE(VTy.getElementType().isPointer());
265 
266       EXPECT_EQ(Ty, VTy.getElementType());
267       EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
268 
269       // Test address space.
270       EXPECT_EQ(AS, Ty.getAddressSpace());
271       EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
272 
273       // Test equality operators.
274       EXPECT_TRUE(Ty == Ty);
275       EXPECT_FALSE(Ty != Ty);
276       EXPECT_TRUE(VTy == VTy);
277       EXPECT_FALSE(VTy != VTy);
278 
279       // Test Type->LLT conversion.
280       Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
281       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
282       Type *IRVTy =
283           VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), EC);
284       EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
285     }
286   }
287 }
288 
289 TEST(LowLevelTypeTest, Invalid) {
290   const LLT Ty;
291 
292   ASSERT_FALSE(Ty.isValid());
293   ASSERT_FALSE(Ty.isScalar());
294   ASSERT_FALSE(Ty.isPointer());
295   ASSERT_FALSE(Ty.isVector());
296 }
297 
298 TEST(LowLevelTypeTest, Divide) {
299   // Test basic scalar->scalar cases.
300   EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2));
301   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
302   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
303 
304   // Test pointer->scalar
305   EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2));
306 
307   // Test dividing vectors.
308   EXPECT_EQ(LLT::scalar(32), LLT::fixed_vector(2, 32).divide(2));
309   EXPECT_EQ(LLT::fixed_vector(2, 32), LLT::fixed_vector(4, 32).divide(2));
310 
311   // Test vector of pointers
312   EXPECT_EQ(LLT::pointer(1, 64),
313             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(4));
314   EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(1, 64)),
315             LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(2));
316 }
317 
318 }
319