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 "gtest/gtest.h" 15 16 using namespace llvm; 17 18 namespace { 19 20 TEST(LowLevelTypeTest, Scalar) { 21 LLVMContext C; 22 DataLayout DL(""); 23 24 for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) { 25 const LLT Ty = LLT::scalar(S); 26 27 // Test kind. 28 ASSERT_TRUE(Ty.isValid()); 29 ASSERT_TRUE(Ty.isScalar()); 30 31 ASSERT_FALSE(Ty.isPointer()); 32 ASSERT_FALSE(Ty.isVector()); 33 34 // Test sizes. 35 EXPECT_EQ(S, Ty.getSizeInBits()); 36 EXPECT_EQ(S, Ty.getScalarSizeInBits()); 37 38 // Test equality operators. 39 EXPECT_TRUE(Ty == Ty); 40 EXPECT_FALSE(Ty != Ty); 41 42 // Test Type->LLT conversion. 43 Type *IRTy = IntegerType::get(C, S); 44 EXPECT_EQ(Ty, getLLTForType(*IRTy, DL)); 45 } 46 } 47 48 TEST(LowLevelTypeTest, Vector) { 49 LLVMContext C; 50 DataLayout DL(""); 51 52 for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) { 53 for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) { 54 const LLT STy = LLT::scalar(S); 55 const LLT VTy = LLT::vector(Elts, S); 56 57 // Test the alternative vector(). 58 { 59 const LLT VSTy = LLT::vector(Elts, STy); 60 EXPECT_EQ(VTy, VSTy); 61 } 62 63 // Test getElementType(). 64 EXPECT_EQ(STy, VTy.getElementType()); 65 66 // Test kind. 67 ASSERT_TRUE(VTy.isValid()); 68 ASSERT_TRUE(VTy.isVector()); 69 70 ASSERT_FALSE(VTy.isScalar()); 71 ASSERT_FALSE(VTy.isPointer()); 72 73 // Test sizes. 74 EXPECT_EQ(S * Elts, VTy.getSizeInBits()); 75 EXPECT_EQ(S, VTy.getScalarSizeInBits()); 76 EXPECT_EQ(Elts, VTy.getNumElements()); 77 78 // Test equality operators. 79 EXPECT_TRUE(VTy == VTy); 80 EXPECT_FALSE(VTy != VTy); 81 82 // Test inequality operators on.. 83 // ..different kind. 84 EXPECT_NE(VTy, STy); 85 86 // Test Type->LLT conversion. 87 Type *IRSTy = IntegerType::get(C, S); 88 Type *IRTy = VectorType::get(IRSTy, Elts); 89 EXPECT_EQ(VTy, getLLTForType(*IRTy, DL)); 90 } 91 } 92 } 93 94 TEST(LowLevelTypeTest, ScalarOrVector) { 95 // Test version with number of bits for scalar type. 96 EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, 32)); 97 EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, 32)); 98 99 // Test version with LLT for scalar type. 100 EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, LLT::scalar(32))); 101 EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, LLT::scalar(32))); 102 103 // Test with pointer elements. 104 EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(1, LLT::pointer(1, 32))); 105 EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 32)), 106 LLT::scalarOrVector(2, LLT::pointer(1, 32))); 107 } 108 109 TEST(LowLevelTypeTest, ChangeElementType) { 110 const LLT P0 = LLT::pointer(0, 32); 111 const LLT P1 = LLT::pointer(1, 64); 112 113 const LLT S32 = LLT::scalar(32); 114 const LLT S64 = LLT::scalar(64); 115 116 const LLT V2S32 = LLT::vector(2, 32); 117 const LLT V2S64 = LLT::vector(2, 64); 118 119 const LLT V2P0 = LLT::vector(2, P0); 120 const LLT V2P1 = LLT::vector(2, P1); 121 122 EXPECT_EQ(S64, S32.changeElementType(S64)); 123 EXPECT_EQ(S32, S32.changeElementType(S32)); 124 125 EXPECT_EQ(S32, S64.changeElementSize(32)); 126 EXPECT_EQ(S32, S32.changeElementSize(32)); 127 128 EXPECT_EQ(V2S64, V2S32.changeElementType(S64)); 129 EXPECT_EQ(V2S32, V2S64.changeElementType(S32)); 130 131 EXPECT_EQ(V2S64, V2S32.changeElementSize(64)); 132 EXPECT_EQ(V2S32, V2S64.changeElementSize(32)); 133 134 EXPECT_EQ(P0, S32.changeElementType(P0)); 135 EXPECT_EQ(S32, P0.changeElementType(S32)); 136 137 EXPECT_EQ(V2P1, V2P0.changeElementType(P1)); 138 EXPECT_EQ(V2S32, V2P0.changeElementType(S32)); 139 } 140 141 TEST(LowLevelTypeTest, ChangeNumElements) { 142 const LLT P0 = LLT::pointer(0, 32); 143 const LLT V2P0 = LLT::vector(2, P0); 144 const LLT V3P0 = LLT::vector(3, P0); 145 146 const LLT S64 = LLT::scalar(64); 147 const LLT V2S64 = LLT::vector(2, 64); 148 const LLT V3S64 = LLT::vector(3, 64); 149 150 // Vector to scalar 151 EXPECT_EQ(S64, V2S64.changeNumElements(1)); 152 153 // Vector to vector 154 EXPECT_EQ(V3S64, V2S64.changeNumElements(3)); 155 156 // Scalar to vector 157 EXPECT_EQ(V2S64, S64.changeNumElements(2)); 158 159 EXPECT_EQ(P0, V2P0.changeNumElements(1)); 160 EXPECT_EQ(V3P0, V2P0.changeNumElements(3)); 161 EXPECT_EQ(V2P0, P0.changeNumElements(2)); 162 } 163 164 #ifdef GTEST_HAS_DEATH_TEST 165 #ifndef NDEBUG 166 167 // Invalid to directly change the element size for pointers. 168 TEST(LowLevelTypeTest, ChangeElementTypeDeath) { 169 const LLT P0 = LLT::pointer(0, 32); 170 const LLT V2P0 = LLT::vector(2, P0); 171 172 EXPECT_DEATH(P0.changeElementSize(64), 173 "invalid to directly change element size for pointers"); 174 EXPECT_DEATH(V2P0.changeElementSize(64), 175 "invalid to directly change element size for pointers"); 176 177 // Make sure this still fails even without a change in size. 178 EXPECT_DEATH(P0.changeElementSize(32), 179 "invalid to directly change element size for pointers"); 180 EXPECT_DEATH(V2P0.changeElementSize(32), 181 "invalid to directly change element size for pointers"); 182 } 183 184 #endif 185 #endif 186 187 TEST(LowLevelTypeTest, Pointer) { 188 LLVMContext C; 189 DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8"); 190 191 for (unsigned AS : {0U, 1U, 127U, 0xffffU, 192 static_cast<unsigned>(maxUIntN(23)), 193 static_cast<unsigned>(maxUIntN(24))}) { 194 for (unsigned NumElts : {2, 3, 4, 256, 65535}) { 195 const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); 196 const LLT VTy = LLT::vector(NumElts, Ty); 197 198 // Test kind. 199 ASSERT_TRUE(Ty.isValid()); 200 ASSERT_TRUE(Ty.isPointer()); 201 202 ASSERT_FALSE(Ty.isScalar()); 203 ASSERT_FALSE(Ty.isVector()); 204 205 ASSERT_TRUE(VTy.isValid()); 206 ASSERT_TRUE(VTy.isVector()); 207 ASSERT_TRUE(VTy.getElementType().isPointer()); 208 209 EXPECT_EQ(Ty, VTy.getElementType()); 210 EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits()); 211 212 // Test address space. 213 EXPECT_EQ(AS, Ty.getAddressSpace()); 214 EXPECT_EQ(AS, VTy.getElementType().getAddressSpace()); 215 216 // Test equality operators. 217 EXPECT_TRUE(Ty == Ty); 218 EXPECT_FALSE(Ty != Ty); 219 EXPECT_TRUE(VTy == VTy); 220 EXPECT_FALSE(VTy != VTy); 221 222 // Test Type->LLT conversion. 223 Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS); 224 EXPECT_EQ(Ty, getLLTForType(*IRTy, DL)); 225 Type *IRVTy = 226 VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), NumElts); 227 EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL)); 228 } 229 } 230 } 231 232 TEST(LowLevelTypeTest, Invalid) { 233 const LLT Ty; 234 235 ASSERT_FALSE(Ty.isValid()); 236 ASSERT_FALSE(Ty.isScalar()); 237 ASSERT_FALSE(Ty.isPointer()); 238 ASSERT_FALSE(Ty.isVector()); 239 } 240 241 TEST(LowLevelTypeTest, Divide) { 242 // Test basic scalar->scalar cases. 243 EXPECT_EQ(LLT::scalar(16), LLT::scalar(32).divide(2)); 244 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4)); 245 EXPECT_EQ(LLT::scalar(8), LLT::scalar(32).divide(4)); 246 247 // Test pointer->scalar 248 EXPECT_EQ(LLT::scalar(32), LLT::pointer(0, 64).divide(2)); 249 250 // Test dividing vectors. 251 EXPECT_EQ(LLT::scalar(32), LLT::vector(2, 32).divide(2)); 252 EXPECT_EQ(LLT::vector(2, 32), LLT::vector(4, 32).divide(2)); 253 254 // Test vector of pointers 255 EXPECT_EQ(LLT::pointer(1, 64), 256 LLT::vector(4, LLT::pointer(1, 64)).divide(4)); 257 EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 64)), 258 LLT::vector(4, LLT::pointer(1, 64)).divide(2)); 259 } 260 261 } 262