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