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