1 //===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/CodeGen/LowLevelType.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 // Define a pretty printer to help debugging when things go wrong. 19 namespace llvm { 20 std::ostream & 21 operator<<(std::ostream &OS, const llvm::LLT Ty) { 22 std::string Repr; 23 raw_string_ostream SS{Repr}; 24 Ty.print(SS); 25 OS << SS.str(); 26 return OS; 27 } 28 } 29 30 namespace { 31 32 TEST(LowLevelTypeTest, Scalar) { 33 LLVMContext C; 34 35 for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) { 36 const LLT Ty = LLT::scalar(S); 37 const LLT HalfTy = Ty.halfScalarSize(); 38 const LLT DoubleTy = Ty.doubleScalarSize(); 39 40 // Test kind. 41 for (const LLT TestTy : {Ty, HalfTy, DoubleTy}) { 42 ASSERT_TRUE(TestTy.isValid()); 43 ASSERT_TRUE(TestTy.isScalar()); 44 ASSERT_TRUE(TestTy.isSized()); 45 46 ASSERT_FALSE(TestTy.isPointer()); 47 ASSERT_FALSE(TestTy.isVector()); 48 } 49 50 // Test sizes. 51 EXPECT_EQ(S, Ty.getSizeInBits()); 52 EXPECT_EQ(S, Ty.getScalarSizeInBits()); 53 54 // Is it OK to half an odd-sized scalar? It currently is. 55 EXPECT_EQ(S/2, HalfTy.getSizeInBits()); 56 EXPECT_EQ(S/2, HalfTy.getScalarSizeInBits()); 57 58 EXPECT_EQ(S*2, DoubleTy.getSizeInBits()); 59 EXPECT_EQ(S*2, DoubleTy.getScalarSizeInBits()); 60 61 // Test equality operators. 62 EXPECT_TRUE(Ty == Ty); 63 EXPECT_FALSE(Ty != Ty); 64 65 EXPECT_NE(Ty, DoubleTy); 66 67 // Test Type->LLT conversion. 68 const Type *IRTy = IntegerType::get(C, S); 69 EXPECT_EQ(Ty, LLT(*IRTy)); 70 } 71 } 72 73 TEST(LowLevelTypeTest, Vector) { 74 LLVMContext C; 75 76 for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) { 77 for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) { 78 const LLT STy = LLT::scalar(S); 79 const LLT VTy = LLT::vector(Elts, S); 80 81 // Test the alternative vector(). 82 { 83 const LLT VSTy = LLT::vector(Elts, STy); 84 EXPECT_EQ(VTy, VSTy); 85 } 86 87 // Test getElementType(). 88 EXPECT_EQ(STy, VTy.getElementType()); 89 90 const LLT HalfSzTy = VTy.halfScalarSize(); 91 const LLT DoubleSzTy = VTy.doubleScalarSize(); 92 93 // halfElements requires an even number of elements. 94 const LLT HalfEltIfEvenTy = ((Elts % 2) == 0) ? VTy.halfElements() : VTy; 95 const LLT DoubleEltTy = VTy.doubleElements(); 96 97 // Test kind. 98 for (const LLT TestTy : {VTy, HalfSzTy, DoubleSzTy, DoubleEltTy}) { 99 ASSERT_TRUE(TestTy.isValid()); 100 ASSERT_TRUE(TestTy.isSized()); 101 ASSERT_TRUE(TestTy.isVector()); 102 103 ASSERT_FALSE(TestTy.isScalar()); 104 ASSERT_FALSE(TestTy.isPointer()); 105 } 106 107 // Test halving elements to a scalar. 108 { 109 ASSERT_TRUE(HalfEltIfEvenTy.isValid()); 110 ASSERT_TRUE(HalfEltIfEvenTy.isSized()); 111 ASSERT_FALSE(HalfEltIfEvenTy.isPointer()); 112 if (Elts > 2) { 113 ASSERT_TRUE(HalfEltIfEvenTy.isVector()); 114 } else { 115 ASSERT_FALSE(HalfEltIfEvenTy.isVector()); 116 EXPECT_EQ(STy, HalfEltIfEvenTy); 117 } 118 } 119 120 121 // Test sizes. 122 EXPECT_EQ(S * Elts, VTy.getSizeInBits()); 123 EXPECT_EQ(S, VTy.getScalarSizeInBits()); 124 EXPECT_EQ(Elts, VTy.getNumElements()); 125 126 EXPECT_EQ((S / 2) * Elts, HalfSzTy.getSizeInBits()); 127 EXPECT_EQ(S / 2, HalfSzTy.getScalarSizeInBits()); 128 EXPECT_EQ(Elts, HalfSzTy.getNumElements()); 129 130 EXPECT_EQ((S * 2) * Elts, DoubleSzTy.getSizeInBits()); 131 EXPECT_EQ(S * 2, DoubleSzTy.getScalarSizeInBits()); 132 EXPECT_EQ(Elts, DoubleSzTy.getNumElements()); 133 134 if ((Elts % 2) == 0) { 135 EXPECT_EQ(S * (Elts / 2), HalfEltIfEvenTy.getSizeInBits()); 136 EXPECT_EQ(S, HalfEltIfEvenTy.getScalarSizeInBits()); 137 if (Elts > 2) 138 EXPECT_EQ(Elts / 2, HalfEltIfEvenTy.getNumElements()); 139 } 140 141 EXPECT_EQ(S * (Elts * 2), DoubleEltTy.getSizeInBits()); 142 EXPECT_EQ(S, DoubleEltTy.getScalarSizeInBits()); 143 EXPECT_EQ(Elts * 2, DoubleEltTy.getNumElements()); 144 145 // Test equality operators. 146 EXPECT_TRUE(VTy == VTy); 147 EXPECT_FALSE(VTy != VTy); 148 149 // Test inequality operators on.. 150 // ..different kind. 151 EXPECT_NE(VTy, STy); 152 // ..different #elts. 153 EXPECT_NE(VTy, DoubleEltTy); 154 // ..different scalar size. 155 EXPECT_NE(VTy, DoubleSzTy); 156 157 // Test Type->LLT conversion. 158 Type *IRSTy = IntegerType::get(C, S); 159 const Type *IRTy = VectorType::get(IRSTy, Elts); 160 EXPECT_EQ(VTy, LLT(*IRTy)); 161 } 162 } 163 } 164 165 TEST(LowLevelTypeTest, Pointer) { 166 LLVMContext C; 167 168 for (unsigned AS : {0U, 1U, 127U, 0xffffU}) { 169 const LLT Ty = LLT::pointer(AS); 170 171 // Test kind. 172 ASSERT_TRUE(Ty.isValid()); 173 ASSERT_TRUE(Ty.isPointer()); 174 175 ASSERT_FALSE(Ty.isSized()); 176 ASSERT_FALSE(Ty.isScalar()); 177 ASSERT_FALSE(Ty.isVector()); 178 179 // Test addressspace. 180 EXPECT_EQ(AS, Ty.getAddressSpace()); 181 182 // Test equality operators. 183 EXPECT_TRUE(Ty == Ty); 184 EXPECT_FALSE(Ty != Ty); 185 186 // Test Type->LLT conversion. 187 const Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS); 188 EXPECT_EQ(Ty, LLT(*IRTy)); 189 } 190 } 191 192 TEST(LowLevelTypeTest, Invalid) { 193 const LLT Ty; 194 195 ASSERT_FALSE(Ty.isValid()); 196 ASSERT_FALSE(Ty.isScalar()); 197 ASSERT_FALSE(Ty.isSized()); 198 ASSERT_FALSE(Ty.isPointer()); 199 ASSERT_FALSE(Ty.isVector()); 200 } 201 202 TEST(LowLevelTypeTest, Unsized) { 203 LLVMContext C; 204 205 const LLT Ty = LLT::unsized(); 206 207 ASSERT_TRUE(Ty.isValid()); 208 ASSERT_FALSE(Ty.isScalar()); 209 ASSERT_FALSE(Ty.isSized()); 210 ASSERT_FALSE(Ty.isPointer()); 211 ASSERT_FALSE(Ty.isVector()); 212 213 const Type *IRTy = Type::getLabelTy(C); 214 EXPECT_EQ(Ty, LLT(*IRTy)); 215 } 216 } 217