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/LowLevelTypeUtils.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, Token) { 22 LLVMContext C; 23 24 const LLT TTy = LLT::token(); 25 26 // Test kind. 27 EXPECT_TRUE(TTy.isValid()); 28 EXPECT_TRUE(TTy.isScalar()); 29 EXPECT_TRUE(TTy.isToken()); 30 31 EXPECT_FALSE(TTy.isPointer()); 32 EXPECT_FALSE(TTy.isVector()); 33 34 const LLT STy = LLT::scalar(0); 35 EXPECT_EQ(STy, TTy); 36 } 37 38 TEST(LowLevelTypeTest, Scalar) { 39 LLVMContext C; 40 DataLayout DL; 41 42 for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffffU}) { 43 const LLT Ty = LLT::scalar(S); 44 45 // Test kind. 46 ASSERT_TRUE(Ty.isValid()); 47 ASSERT_TRUE(Ty.isScalar()); 48 49 ASSERT_FALSE(Ty.isPointer()); 50 ASSERT_FALSE(Ty.isVector()); 51 52 EXPECT_TRUE(S != 0 || Ty.isToken()); 53 54 // Test sizes. 55 EXPECT_EQ(S, Ty.getSizeInBits()); 56 EXPECT_EQ(S, Ty.getScalarSizeInBits()); 57 58 // Test equality operators. 59 EXPECT_TRUE(Ty == Ty); 60 EXPECT_FALSE(Ty != Ty); 61 62 // Test Type->LLT conversion. 63 if (S != 0) { 64 Type *IRTy = IntegerType::get(C, S); 65 EXPECT_EQ(Ty, getLLTForType(*IRTy, DL)); 66 } 67 } 68 } 69 70 TEST(LowLevelTypeTest, Vector) { 71 LLVMContext C; 72 DataLayout DL; 73 74 for (unsigned S : {0U, 1U, 17U, 32U, 64U, 0xfffU}) { 75 for (auto EC : 76 {ElementCount::getFixed(2), ElementCount::getFixed(3), 77 ElementCount::getFixed(4), ElementCount::getFixed(32), 78 ElementCount::getFixed(0xff), ElementCount::getScalable(2), 79 ElementCount::getScalable(3), ElementCount::getScalable(4), 80 ElementCount::getScalable(32), ElementCount::getScalable(0xff)}) { 81 const LLT STy = LLT::scalar(S); 82 const LLT VTy = LLT::vector(EC, S); 83 84 // Test the alternative vector(). 85 { 86 const LLT VSTy = LLT::vector(EC, STy); 87 EXPECT_EQ(VTy, VSTy); 88 } 89 90 // Test getElementType(). 91 EXPECT_EQ(STy, VTy.getElementType()); 92 93 // Test kind. 94 ASSERT_TRUE(VTy.isValid()); 95 ASSERT_TRUE(VTy.isVector()); 96 97 ASSERT_FALSE(VTy.isScalar()); 98 ASSERT_FALSE(VTy.isPointer()); 99 ASSERT_FALSE(VTy.isToken()); 100 101 // Test sizes. 102 EXPECT_EQ(S, VTy.getScalarSizeInBits()); 103 EXPECT_EQ(EC, VTy.getElementCount()); 104 if (!EC.isScalable()) 105 EXPECT_EQ(S * EC.getFixedValue(), VTy.getSizeInBits()); 106 else 107 EXPECT_EQ(TypeSize::getScalable(S * EC.getKnownMinValue()), 108 VTy.getSizeInBits()); 109 110 // Test equality operators. 111 EXPECT_TRUE(VTy == VTy); 112 EXPECT_FALSE(VTy != VTy); 113 114 // Test inequality operators on.. 115 // ..different kind. 116 EXPECT_NE(VTy, STy); 117 118 // Test Type->LLT conversion. 119 if (S != 0) { 120 Type *IRSTy = IntegerType::get(C, S); 121 Type *IRTy = VectorType::get(IRSTy, EC); 122 EXPECT_EQ(VTy, getLLTForType(*IRTy, DL)); 123 } 124 } 125 } 126 } 127 128 TEST(LowLevelTypeTest, ScalarOrVector) { 129 // Test version with number of bits for scalar type. 130 EXPECT_EQ(LLT::scalar(32), 131 LLT::scalarOrVector(ElementCount::getFixed(1), 32)); 132 EXPECT_EQ(LLT::fixed_vector(2, 32), 133 LLT::scalarOrVector(ElementCount::getFixed(2), 32)); 134 EXPECT_EQ(LLT::scalable_vector(1, 32), 135 LLT::scalarOrVector(ElementCount::getScalable(1), 32)); 136 137 // Test version with LLT for scalar type. 138 EXPECT_EQ(LLT::scalar(32), 139 LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32))); 140 EXPECT_EQ(LLT::fixed_vector(2, 32), 141 LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32))); 142 143 // Test with pointer elements. 144 EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(ElementCount::getFixed(1), 145 LLT::pointer(1, 32))); 146 EXPECT_EQ( 147 LLT::fixed_vector(2, LLT::pointer(1, 32)), 148 LLT::scalarOrVector(ElementCount::getFixed(2), LLT::pointer(1, 32))); 149 } 150 151 TEST(LowLevelTypeTest, ChangeElementType) { 152 const LLT P0 = LLT::pointer(0, 32); 153 const LLT P1 = LLT::pointer(1, 64); 154 155 const LLT S32 = LLT::scalar(32); 156 const LLT S64 = LLT::scalar(64); 157 158 const LLT V2S32 = LLT::fixed_vector(2, 32); 159 const LLT V2S64 = LLT::fixed_vector(2, 64); 160 161 const LLT V2P0 = LLT::fixed_vector(2, P0); 162 const LLT V2P1 = LLT::fixed_vector(2, P1); 163 164 EXPECT_EQ(S64, S32.changeElementType(S64)); 165 EXPECT_EQ(S32, S32.changeElementType(S32)); 166 167 EXPECT_EQ(S32, S64.changeElementSize(32)); 168 EXPECT_EQ(S32, S32.changeElementSize(32)); 169 170 EXPECT_EQ(V2S64, V2S32.changeElementType(S64)); 171 EXPECT_EQ(V2S32, V2S64.changeElementType(S32)); 172 173 EXPECT_EQ(V2S64, V2S32.changeElementSize(64)); 174 EXPECT_EQ(V2S32, V2S64.changeElementSize(32)); 175 176 EXPECT_EQ(P0, S32.changeElementType(P0)); 177 EXPECT_EQ(S32, P0.changeElementType(S32)); 178 179 EXPECT_EQ(V2P1, V2P0.changeElementType(P1)); 180 EXPECT_EQ(V2S32, V2P0.changeElementType(S32)); 181 182 // Similar tests for scalable vectors. 183 const LLT NXV2S32 = LLT::scalable_vector(2, 32); 184 const LLT NXV2S64 = LLT::scalable_vector(2, 64); 185 186 const LLT NXV2P0 = LLT::scalable_vector(2, P0); 187 const LLT NXV2P1 = LLT::scalable_vector(2, P1); 188 189 EXPECT_EQ(NXV2S64, NXV2S32.changeElementType(S64)); 190 EXPECT_EQ(NXV2S32, NXV2S64.changeElementType(S32)); 191 192 EXPECT_EQ(NXV2S64, NXV2S32.changeElementSize(64)); 193 EXPECT_EQ(NXV2S32, NXV2S64.changeElementSize(32)); 194 195 EXPECT_EQ(NXV2P1, NXV2P0.changeElementType(P1)); 196 EXPECT_EQ(NXV2S32, NXV2P0.changeElementType(S32)); 197 } 198 199 TEST(LowLevelTypeTest, ChangeNumElements) { 200 const LLT P0 = LLT::pointer(0, 32); 201 const LLT V2P0 = LLT::fixed_vector(2, P0); 202 const LLT V3P0 = LLT::fixed_vector(3, P0); 203 204 const LLT S64 = LLT::scalar(64); 205 const LLT V2S64 = LLT::fixed_vector(2, 64); 206 const LLT V3S64 = LLT::fixed_vector(3, 64); 207 208 // Vector to scalar 209 EXPECT_EQ(S64, V2S64.changeElementCount(ElementCount::getFixed(1))); 210 211 // Vector to vector 212 EXPECT_EQ(V3S64, V2S64.changeElementCount(ElementCount::getFixed(3))); 213 214 // Scalar to vector 215 EXPECT_EQ(V2S64, S64.changeElementCount(ElementCount::getFixed(2))); 216 217 EXPECT_EQ(P0, V2P0.changeElementCount(ElementCount::getFixed(1))); 218 EXPECT_EQ(V3P0, V2P0.changeElementCount(ElementCount::getFixed(3))); 219 EXPECT_EQ(V2P0, P0.changeElementCount(ElementCount::getFixed(2))); 220 221 const LLT NXV2S64 = LLT::scalable_vector(2, 64); 222 const LLT NXV3S64 = LLT::scalable_vector(3, 64); 223 const LLT NXV2P0 = LLT::scalable_vector(2, P0); 224 225 // Scalable vector to scalar 226 EXPECT_EQ(S64, NXV2S64.changeElementCount(ElementCount::getFixed(1))); 227 EXPECT_EQ(P0, NXV2P0.changeElementCount(ElementCount::getFixed(1))); 228 229 // Fixed-width vector to scalable vector 230 EXPECT_EQ(NXV3S64, V2S64.changeElementCount(ElementCount::getScalable(3))); 231 232 // Scalable vector to fixed-width vector 233 EXPECT_EQ(V3P0, NXV2P0.changeElementCount(ElementCount::getFixed(3))); 234 235 // Scalar to scalable vector 236 EXPECT_EQ(NXV2S64, S64.changeElementCount(ElementCount::getScalable(2))); 237 EXPECT_EQ(NXV2P0, P0.changeElementCount(ElementCount::getScalable(2))); 238 } 239 240 #ifdef GTEST_HAS_DEATH_TEST 241 #ifndef NDEBUG 242 243 // Invalid to directly change the element size for pointers. 244 TEST(LowLevelTypeTest, ChangeElementTypeDeath) { 245 const LLT P0 = LLT::pointer(0, 32); 246 const LLT V2P0 = LLT::fixed_vector(2, P0); 247 248 EXPECT_DEATH(P0.changeElementSize(64), 249 "invalid to directly change element size for pointers"); 250 EXPECT_DEATH(V2P0.changeElementSize(64), 251 "invalid to directly change element size for pointers"); 252 253 // Make sure this still fails even without a change in size. 254 EXPECT_DEATH(P0.changeElementSize(32), 255 "invalid to directly change element size for pointers"); 256 EXPECT_DEATH(V2P0.changeElementSize(32), 257 "invalid to directly change element size for pointers"); 258 } 259 260 #endif 261 #endif 262 263 TEST(LowLevelTypeTest, Pointer) { 264 LLVMContext C; 265 DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8"); 266 267 for (unsigned AS : {0U, 1U, 127U, 0xffffU, 268 static_cast<unsigned>(maxUIntN(23)), 269 static_cast<unsigned>(maxUIntN(24))}) { 270 for (ElementCount EC : 271 {ElementCount::getFixed(2), ElementCount::getFixed(3), 272 ElementCount::getFixed(4), ElementCount::getFixed(256), 273 ElementCount::getFixed(65535), ElementCount::getScalable(2), 274 ElementCount::getScalable(3), ElementCount::getScalable(4), 275 ElementCount::getScalable(256), ElementCount::getScalable(65535)}) { 276 const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); 277 const LLT VTy = LLT::vector(EC, Ty); 278 279 // Test kind. 280 ASSERT_TRUE(Ty.isValid()); 281 ASSERT_TRUE(Ty.isPointer()); 282 ASSERT_TRUE(Ty.isPointerOrPointerVector()); 283 284 ASSERT_FALSE(Ty.isScalar()); 285 ASSERT_FALSE(Ty.isVector()); 286 287 ASSERT_TRUE(VTy.isValid()); 288 ASSERT_TRUE(VTy.isVector()); 289 ASSERT_TRUE(VTy.getElementType().isPointer()); 290 ASSERT_TRUE(VTy.isPointerVector()); 291 ASSERT_TRUE(VTy.isPointerOrPointerVector()); 292 293 EXPECT_EQ(Ty, VTy.getElementType()); 294 EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits()); 295 296 // Test address space. 297 EXPECT_EQ(AS, Ty.getAddressSpace()); 298 EXPECT_EQ(AS, VTy.getElementType().getAddressSpace()); 299 300 // Test equality operators. 301 EXPECT_TRUE(Ty == Ty); 302 EXPECT_FALSE(Ty != Ty); 303 EXPECT_TRUE(VTy == VTy); 304 EXPECT_FALSE(VTy != VTy); 305 306 // Test Type->LLT conversion. 307 Type *IRTy = PointerType::get(C, AS); 308 EXPECT_EQ(Ty, getLLTForType(*IRTy, DL)); 309 Type *IRVTy = VectorType::get(PointerType::get(C, AS), EC); 310 EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL)); 311 } 312 } 313 } 314 315 TEST(LowLevelTypeTest, Invalid) { 316 const LLT Ty; 317 318 ASSERT_FALSE(Ty.isValid()); 319 ASSERT_FALSE(Ty.isScalar()); 320 ASSERT_FALSE(Ty.isPointer()); 321 ASSERT_FALSE(Ty.isVector()); 322 ASSERT_FALSE(Ty.isToken()); 323 } 324 325 TEST(LowLevelTypeTest, Divide) { 326 // Test basic scalar->scalar cases. 327 EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2)); 328 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4)); 329 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4)); 330 331 // Test pointer->scalar 332 EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2)); 333 334 // Test dividing vectors. 335 EXPECT_EQ(LLT::scalar(32), LLT::fixed_vector(2, 32).divide(2)); 336 EXPECT_EQ(LLT::fixed_vector(2, 32), LLT::fixed_vector(4, 32).divide(2)); 337 338 // Test vector of pointers 339 EXPECT_EQ(LLT::pointer(1, 64), 340 LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(4)); 341 EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(1, 64)), 342 LLT::fixed_vector(4, LLT::pointer(1, 64)).divide(2)); 343 } 344 345 TEST(LowLevelTypeTest, MultiplyElements) { 346 // Basic scalar->vector cases 347 EXPECT_EQ(LLT::fixed_vector(2, 16), LLT::scalar(16).multiplyElements(2)); 348 EXPECT_EQ(LLT::fixed_vector(3, 16), LLT::scalar(16).multiplyElements(3)); 349 EXPECT_EQ(LLT::fixed_vector(4, 32), LLT::scalar(32).multiplyElements(4)); 350 EXPECT_EQ(LLT::fixed_vector(4, 7), LLT::scalar(7).multiplyElements(4)); 351 352 // Basic vector to vector cases 353 EXPECT_EQ(LLT::fixed_vector(4, 32), 354 LLT::fixed_vector(2, 32).multiplyElements(2)); 355 EXPECT_EQ(LLT::fixed_vector(9, 32), 356 LLT::fixed_vector(3, 32).multiplyElements(3)); 357 358 // Pointer to vector of pointers 359 EXPECT_EQ(LLT::fixed_vector(2, LLT::pointer(0, 32)), 360 LLT::pointer(0, 32).multiplyElements(2)); 361 EXPECT_EQ(LLT::fixed_vector(3, LLT::pointer(1, 32)), 362 LLT::pointer(1, 32).multiplyElements(3)); 363 EXPECT_EQ(LLT::fixed_vector(4, LLT::pointer(1, 64)), 364 LLT::pointer(1, 64).multiplyElements(4)); 365 366 // Vector of pointers to vector of pointers 367 EXPECT_EQ(LLT::fixed_vector(8, LLT::pointer(1, 64)), 368 LLT::fixed_vector(2, LLT::pointer(1, 64)).multiplyElements(4)); 369 EXPECT_EQ(LLT::fixed_vector(9, LLT::pointer(1, 32)), 370 LLT::fixed_vector(3, LLT::pointer(1, 32)).multiplyElements(3)); 371 372 // Scalable vectors 373 EXPECT_EQ(LLT::scalable_vector(4, 16), 374 LLT::scalable_vector(2, 16).multiplyElements(2)); 375 EXPECT_EQ(LLT::scalable_vector(6, 16), 376 LLT::scalable_vector(2, 16).multiplyElements(3)); 377 EXPECT_EQ(LLT::scalable_vector(9, 16), 378 LLT::scalable_vector(3, 16).multiplyElements(3)); 379 EXPECT_EQ(LLT::scalable_vector(4, 32), 380 LLT::scalable_vector(2, 32).multiplyElements(2)); 381 EXPECT_EQ(LLT::scalable_vector(256, 32), 382 LLT::scalable_vector(8, 32).multiplyElements(32)); 383 384 // Scalable vectors of pointers 385 EXPECT_EQ(LLT::scalable_vector(4, LLT::pointer(0, 32)), 386 LLT::scalable_vector(2, LLT::pointer(0, 32)).multiplyElements(2)); 387 EXPECT_EQ(LLT::scalable_vector(32, LLT::pointer(1, 64)), 388 LLT::scalable_vector(8, LLT::pointer(1, 64)).multiplyElements(4)); 389 } 390 391 constexpr LLT CELLT = LLT(); 392 constexpr LLT CES32 = LLT::scalar(32); 393 constexpr LLT CEV2S32 = LLT::fixed_vector(2, 32); 394 constexpr LLT CESV2S32 = LLT::scalable_vector(2, 32); 395 constexpr LLT CEP0 = LLT::pointer(0, 32); 396 constexpr LLT CEV2P1 = LLT::fixed_vector(2, LLT::pointer(1, 64)); 397 398 static_assert(!CELLT.isValid()); 399 static_assert(CES32.isValid()); 400 static_assert(CEV2S32.isValid()); 401 static_assert(CESV2S32.isValid()); 402 static_assert(CEP0.isValid()); 403 static_assert(CEV2P1.isValid()); 404 static_assert(CEV2P1.isVector()); 405 static_assert(CEV2P1.getElementCount() == ElementCount::getFixed(2)); 406 static_assert(CEV2P1.getElementCount() != ElementCount::getFixed(1)); 407 static_assert(CEV2S32.getElementCount() == ElementCount::getFixed(2)); 408 static_assert(CEV2S32.getSizeInBits() == TypeSize::getFixed(64)); 409 static_assert(CEV2P1.getSizeInBits() == TypeSize::getFixed(128)); 410 static_assert(CEV2P1.getScalarType() == LLT::pointer(1, 64)); 411 static_assert(CES32.getScalarType() == CES32); 412 static_assert(CEV2S32.getScalarType() == CES32); 413 static_assert(CEV2S32.changeElementType(CEP0) == LLT::fixed_vector(2, CEP0)); 414 static_assert(CEV2S32.changeElementSize(16) == LLT::fixed_vector(2, 16)); 415 static_assert(CEV2S32.changeElementCount(ElementCount::getFixed(4)) == 416 LLT::fixed_vector(4, 32)); 417 static_assert(CES32.isByteSized()); 418 static_assert(!LLT::scalar(7).isByteSized()); 419 static_assert(CES32.getScalarSizeInBits() == 32); 420 static_assert(CEP0.getAddressSpace() == 0); 421 static_assert(LLT::pointer(1, 64).getAddressSpace() == 1); 422 static_assert(CEV2S32.multiplyElements(2) == LLT::fixed_vector(4, 32)); 423 static_assert(CEV2S32.divide(2) == LLT::scalar(32)); 424 static_assert(LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)) == 425 LLT::scalar(32)); 426 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)) == 427 LLT::fixed_vector(2, 32)); 428 static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), CEP0) == 429 LLT::fixed_vector(2, CEP0)); 430 431 TEST(LowLevelTypeTest, ConstExpr) { 432 EXPECT_EQ(LLT(), CELLT); 433 EXPECT_EQ(LLT::scalar(32), CES32); 434 EXPECT_EQ(LLT::fixed_vector(2, 32), CEV2S32); 435 EXPECT_EQ(LLT::pointer(0, 32), CEP0); 436 EXPECT_EQ(LLT::scalable_vector(2, 32), CESV2S32); 437 } 438 439 TEST(LowLevelTypeTest, IsFixedVector) { 440 EXPECT_FALSE(LLT::scalar(32).isFixedVector()); 441 EXPECT_TRUE(LLT::fixed_vector(2, 32).isFixedVector()); 442 EXPECT_FALSE(LLT::scalable_vector(2, 32).isFixedVector()); 443 EXPECT_FALSE(LLT::scalable_vector(1, 32).isFixedVector()); 444 } 445 446 TEST(LowLevelTypeTest, IsScalableVector) { 447 EXPECT_FALSE(LLT::scalar(32).isScalableVector()); 448 EXPECT_FALSE(LLT::fixed_vector(2, 32).isScalableVector()); 449 EXPECT_TRUE(LLT::scalable_vector(2, 32).isScalableVector()); 450 EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector()); 451 } 452 } 453