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