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