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