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