xref: /llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp (revision f48fe2c36e80e4d3820b5b56f5ad8c9bdbe813c4)
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 "gtest/gtest.h"
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 TEST(LowLevelTypeTest, Scalar) {
21   LLVMContext C;
22   DataLayout DL("");
23 
24   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) {
25     const LLT Ty = LLT::scalar(S);
26 
27     // Test kind.
28     ASSERT_TRUE(Ty.isValid());
29     ASSERT_TRUE(Ty.isScalar());
30 
31     ASSERT_FALSE(Ty.isPointer());
32     ASSERT_FALSE(Ty.isVector());
33 
34     // Test sizes.
35     EXPECT_EQ(S, Ty.getSizeInBits());
36     EXPECT_EQ(S, Ty.getScalarSizeInBits());
37 
38     // Test equality operators.
39     EXPECT_TRUE(Ty == Ty);
40     EXPECT_FALSE(Ty != Ty);
41 
42     // Test Type->LLT conversion.
43     Type *IRTy = IntegerType::get(C, S);
44     EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
45   }
46 }
47 
48 TEST(LowLevelTypeTest, Vector) {
49   LLVMContext C;
50   DataLayout DL("");
51 
52   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) {
53     for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) {
54       const LLT STy = LLT::scalar(S);
55       const LLT VTy = LLT::vector(Elts, S);
56 
57       // Test the alternative vector().
58       {
59         const LLT VSTy = LLT::vector(Elts, STy);
60         EXPECT_EQ(VTy, VSTy);
61       }
62 
63       // Test getElementType().
64       EXPECT_EQ(STy, VTy.getElementType());
65 
66       // Test kind.
67       ASSERT_TRUE(VTy.isValid());
68       ASSERT_TRUE(VTy.isVector());
69 
70       ASSERT_FALSE(VTy.isScalar());
71       ASSERT_FALSE(VTy.isPointer());
72 
73       // Test sizes.
74       EXPECT_EQ(S * Elts, VTy.getSizeInBits());
75       EXPECT_EQ(S, VTy.getScalarSizeInBits());
76       EXPECT_EQ(Elts, VTy.getNumElements());
77 
78       // Test equality operators.
79       EXPECT_TRUE(VTy == VTy);
80       EXPECT_FALSE(VTy != VTy);
81 
82       // Test inequality operators on..
83       // ..different kind.
84       EXPECT_NE(VTy, STy);
85 
86       // Test Type->LLT conversion.
87       Type *IRSTy = IntegerType::get(C, S);
88       Type *IRTy = VectorType::get(IRSTy, Elts);
89       EXPECT_EQ(VTy, getLLTForType(*IRTy, DL));
90     }
91   }
92 }
93 
94 TEST(LowLevelTypeTest, ScalarOrVector) {
95   // Test version with number of bits for scalar type.
96   EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, 32));
97   EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, 32));
98 
99   // Test version with LLT for scalar type.
100   EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, LLT::scalar(32)));
101   EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, LLT::scalar(32)));
102 
103   // Test with pointer elements.
104   EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(1, LLT::pointer(1, 32)));
105   EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 32)),
106             LLT::scalarOrVector(2, LLT::pointer(1, 32)));
107 }
108 
109 TEST(LowLevelTypeTest, ChangeElementType) {
110   const LLT P0 = LLT::pointer(0, 32);
111   const LLT P1 = LLT::pointer(1, 64);
112 
113   const LLT S32 = LLT::scalar(32);
114   const LLT S64 = LLT::scalar(64);
115 
116   const LLT V2S32 = LLT::vector(2, 32);
117   const LLT V2S64 = LLT::vector(2, 64);
118 
119   const LLT V2P0 = LLT::vector(2, P0);
120   const LLT V2P1 = LLT::vector(2, P1);
121 
122   EXPECT_EQ(S64, S32.changeElementType(S64));
123   EXPECT_EQ(S32, S32.changeElementType(S32));
124 
125   EXPECT_EQ(S32, S64.changeElementSize(32));
126   EXPECT_EQ(S32, S32.changeElementSize(32));
127 
128   EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
129   EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
130 
131   EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
132   EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
133 
134   EXPECT_EQ(P0, S32.changeElementType(P0));
135   EXPECT_EQ(S32, P0.changeElementType(S32));
136 
137   EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
138   EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
139 }
140 
141 TEST(LowLevelTypeTest, ChangeNumElements) {
142   const LLT P0 = LLT::pointer(0, 32);
143   const LLT V2P0 = LLT::vector(2, P0);
144   const LLT V3P0 = LLT::vector(3, P0);
145 
146   const LLT S64 = LLT::scalar(64);
147   const LLT V2S64 = LLT::vector(2, 64);
148   const LLT V3S64 = LLT::vector(3, 64);
149 
150   // Vector to scalar
151   EXPECT_EQ(S64, V2S64.changeNumElements(1));
152 
153   // Vector to vector
154   EXPECT_EQ(V3S64, V2S64.changeNumElements(3));
155 
156   // Scalar to vector
157   EXPECT_EQ(V2S64, S64.changeNumElements(2));
158 
159   EXPECT_EQ(P0, V2P0.changeNumElements(1));
160   EXPECT_EQ(V3P0, V2P0.changeNumElements(3));
161   EXPECT_EQ(V2P0, P0.changeNumElements(2));
162 }
163 
164 #ifdef GTEST_HAS_DEATH_TEST
165 #ifndef NDEBUG
166 
167 // Invalid to directly change the element size for pointers.
168 TEST(LowLevelTypeTest, ChangeElementTypeDeath) {
169   const LLT P0 = LLT::pointer(0, 32);
170   const LLT V2P0 = LLT::vector(2, P0);
171 
172   EXPECT_DEATH(P0.changeElementSize(64),
173                "invalid to directly change element size for pointers");
174   EXPECT_DEATH(V2P0.changeElementSize(64),
175                "invalid to directly change element size for pointers");
176 
177   // Make sure this still fails even without a change in size.
178   EXPECT_DEATH(P0.changeElementSize(32),
179                "invalid to directly change element size for pointers");
180   EXPECT_DEATH(V2P0.changeElementSize(32),
181                "invalid to directly change element size for pointers");
182 }
183 
184 #endif
185 #endif
186 
187 TEST(LowLevelTypeTest, Pointer) {
188   LLVMContext C;
189   DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
190 
191   for (unsigned AS : {0U, 1U, 127U, 0xffffU,
192         static_cast<unsigned>(maxUIntN(23)),
193         static_cast<unsigned>(maxUIntN(24))}) {
194     for (unsigned NumElts : {2, 3, 4, 256, 65535}) {
195       const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
196       const LLT VTy = LLT::vector(NumElts, Ty);
197 
198       // Test kind.
199       ASSERT_TRUE(Ty.isValid());
200       ASSERT_TRUE(Ty.isPointer());
201 
202       ASSERT_FALSE(Ty.isScalar());
203       ASSERT_FALSE(Ty.isVector());
204 
205       ASSERT_TRUE(VTy.isValid());
206       ASSERT_TRUE(VTy.isVector());
207       ASSERT_TRUE(VTy.getElementType().isPointer());
208 
209       EXPECT_EQ(Ty, VTy.getElementType());
210       EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
211 
212       // Test address space.
213       EXPECT_EQ(AS, Ty.getAddressSpace());
214       EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
215 
216       // Test equality operators.
217       EXPECT_TRUE(Ty == Ty);
218       EXPECT_FALSE(Ty != Ty);
219       EXPECT_TRUE(VTy == VTy);
220       EXPECT_FALSE(VTy != VTy);
221 
222       // Test Type->LLT conversion.
223       Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
224       EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
225       Type *IRVTy =
226         VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), NumElts);
227       EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
228     }
229   }
230 }
231 
232 TEST(LowLevelTypeTest, Invalid) {
233   const LLT Ty;
234 
235   ASSERT_FALSE(Ty.isValid());
236   ASSERT_FALSE(Ty.isScalar());
237   ASSERT_FALSE(Ty.isPointer());
238   ASSERT_FALSE(Ty.isVector());
239 }
240 
241 TEST(LowLevelTypeTest, Divide) {
242   // Test basic scalar->scalar cases.
243   EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2));
244   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
245   EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4));
246 
247   // Test pointer->scalar
248   EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2));
249 
250   // Test dividing vectors.
251   EXPECT_EQ(LLT::scalar(32), LLT::vector(2, 32).divide(2));
252   EXPECT_EQ(LLT::vector(2, 32), LLT::vector(4, 32).divide(2));
253 
254   // Test vector of pointers
255   EXPECT_EQ(LLT::pointer(1, 64),
256             LLT::vector(4, LLT::pointer(1, 64)).divide(4));
257   EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 64)),
258             LLT::vector(4, LLT::pointer(1, 64)).divide(2));
259 }
260 
261 }
262