453 lines · cpp
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-exception6//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 17using namespace llvm;18 19namespace {20 21TEST(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 38TEST(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 70TEST(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 else107 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 128TEST(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 151TEST(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 199TEST(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 scalar209 EXPECT_EQ(S64, V2S64.changeElementCount(ElementCount::getFixed(1)));210 211 // Vector to vector212 EXPECT_EQ(V3S64, V2S64.changeElementCount(ElementCount::getFixed(3)));213 214 // Scalar to vector215 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 scalar226 EXPECT_EQ(S64, NXV2S64.changeElementCount(ElementCount::getFixed(1)));227 EXPECT_EQ(P0, NXV2P0.changeElementCount(ElementCount::getFixed(1)));228 229 // Fixed-width vector to scalable vector230 EXPECT_EQ(NXV3S64, V2S64.changeElementCount(ElementCount::getScalable(3)));231 232 // Scalable vector to fixed-width vector233 EXPECT_EQ(V3P0, NXV2P0.changeElementCount(ElementCount::getFixed(3)));234 235 // Scalar to scalable vector236 EXPECT_EQ(NXV2S64, S64.changeElementCount(ElementCount::getScalable(2)));237 EXPECT_EQ(NXV2P0, P0.changeElementCount(ElementCount::getScalable(2)));238}239 240#ifdef GTEST_HAS_DEATH_TEST241#ifndef NDEBUG242 243// Invalid to directly change the element size for pointers.244TEST(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#endif261#endif262 263TEST(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 315TEST(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 325TEST(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->scalar332 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 pointers339 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 345TEST(LowLevelTypeTest, MultiplyElements) {346 // Basic scalar->vector cases347 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 cases353 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 pointers359 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 pointers367 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 vectors373 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 pointers385 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 391constexpr LLT CELLT = LLT();392constexpr LLT CES32 = LLT::scalar(32);393constexpr LLT CEV2S32 = LLT::fixed_vector(2, 32);394constexpr LLT CESV2S32 = LLT::scalable_vector(2, 32);395constexpr LLT CEP0 = LLT::pointer(0, 32);396constexpr LLT CEV2P1 = LLT::fixed_vector(2, LLT::pointer(1, 64));397 398static_assert(!CELLT.isValid());399static_assert(CES32.isValid());400static_assert(CEV2S32.isValid());401static_assert(CESV2S32.isValid());402static_assert(CEP0.isValid());403static_assert(CEV2P1.isValid());404static_assert(CEV2P1.isVector());405static_assert(CEV2P1.getElementCount() == ElementCount::getFixed(2));406static_assert(CEV2P1.getElementCount() != ElementCount::getFixed(1));407static_assert(CEV2S32.getElementCount() == ElementCount::getFixed(2));408static_assert(CEV2S32.getSizeInBits() == TypeSize::getFixed(64));409static_assert(CEV2P1.getSizeInBits() == TypeSize::getFixed(128));410static_assert(CEV2P1.getScalarType() == LLT::pointer(1, 64));411static_assert(CES32.getScalarType() == CES32);412static_assert(CEV2S32.getScalarType() == CES32);413static_assert(CEV2S32.changeElementType(CEP0) == LLT::fixed_vector(2, CEP0));414static_assert(CEV2S32.changeElementSize(16) == LLT::fixed_vector(2, 16));415static_assert(CEV2S32.changeElementCount(ElementCount::getFixed(4)) ==416 LLT::fixed_vector(4, 32));417static_assert(CES32.isByteSized());418static_assert(!LLT::scalar(7).isByteSized());419static_assert(CES32.getScalarSizeInBits() == 32);420static_assert(CEP0.getAddressSpace() == 0);421static_assert(LLT::pointer(1, 64).getAddressSpace() == 1);422static_assert(CEV2S32.multiplyElements(2) == LLT::fixed_vector(4, 32));423static_assert(CEV2S32.divide(2) == LLT::scalar(32));424static_assert(LLT::scalarOrVector(ElementCount::getFixed(1), LLT::scalar(32)) ==425 LLT::scalar(32));426static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), LLT::scalar(32)) ==427 LLT::fixed_vector(2, 32));428static_assert(LLT::scalarOrVector(ElementCount::getFixed(2), CEP0) ==429 LLT::fixed_vector(2, CEP0));430 431TEST(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 439TEST(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 446TEST(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