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
TEST(LowLevelTypeTest,Scalar)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
TEST(LowLevelTypeTest,Vector)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
TEST(LowLevelTypeTest,ScalarOrVector)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
TEST(LowLevelTypeTest,ChangeElementType)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 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
TEST(LowLevelTypeTest,ChangeNumElements)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.
TEST(LowLevelTypeTest,ChangeElementTypeDeath)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
TEST(LowLevelTypeTest,Pointer)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
TEST(LowLevelTypeTest,Invalid)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
TEST(LowLevelTypeTest,Divide)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
TEST(LowLevelTypeTest,MultiplyElements)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