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 = (S % 2) == 0 ? Ty.halfScalarSize() : Ty;
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     EXPECT_EQ(S*2, DoubleTy.getSizeInBits());
55     EXPECT_EQ(S*2, DoubleTy.getScalarSizeInBits());
56 
57     if ((S % 2) == 0) {
58       EXPECT_EQ(S/2, HalfTy.getSizeInBits());
59       EXPECT_EQ(S/2, HalfTy.getScalarSizeInBits());
60     }
61 
62     // Test equality operators.
63     EXPECT_TRUE(Ty == Ty);
64     EXPECT_FALSE(Ty != Ty);
65 
66     EXPECT_NE(Ty, DoubleTy);
67 
68     // Test Type->LLT conversion.
69     Type *IRTy = IntegerType::get(C, S);
70     EXPECT_EQ(Ty, LLT(*IRTy));
71   }
72 }
73 
74 TEST(LowLevelTypeTest, Vector) {
75   LLVMContext C;
76 
77   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) {
78     for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) {
79       const LLT STy = LLT::scalar(S);
80       const LLT VTy = LLT::vector(Elts, S);
81 
82       // Test the alternative vector().
83       {
84         const LLT VSTy = LLT::vector(Elts, STy);
85         EXPECT_EQ(VTy, VSTy);
86       }
87 
88       // Test getElementType().
89       EXPECT_EQ(STy, VTy.getElementType());
90 
91       const LLT HalfSzTy = ((S % 2) == 0) ? VTy.halfScalarSize() : VTy;
92       const LLT DoubleSzTy = VTy.doubleScalarSize();
93 
94       // halfElements requires an even number of elements.
95       const LLT HalfEltIfEvenTy = ((Elts % 2) == 0) ?  VTy.halfElements() : VTy;
96       const LLT DoubleEltTy = VTy.doubleElements();
97 
98       // Test kind.
99       for (const LLT TestTy : {VTy, HalfSzTy, DoubleSzTy, DoubleEltTy}) {
100         ASSERT_TRUE(TestTy.isValid());
101         ASSERT_TRUE(TestTy.isSized());
102         ASSERT_TRUE(TestTy.isVector());
103 
104         ASSERT_FALSE(TestTy.isScalar());
105         ASSERT_FALSE(TestTy.isPointer());
106       }
107 
108       // Test halving elements to a scalar.
109       {
110         ASSERT_TRUE(HalfEltIfEvenTy.isValid());
111         ASSERT_TRUE(HalfEltIfEvenTy.isSized());
112         ASSERT_FALSE(HalfEltIfEvenTy.isPointer());
113         if (Elts > 2) {
114           ASSERT_TRUE(HalfEltIfEvenTy.isVector());
115         } else {
116           ASSERT_FALSE(HalfEltIfEvenTy.isVector());
117           EXPECT_EQ(STy, HalfEltIfEvenTy);
118         }
119       }
120 
121 
122       // Test sizes.
123       EXPECT_EQ(S * Elts, VTy.getSizeInBits());
124       EXPECT_EQ(S, VTy.getScalarSizeInBits());
125       EXPECT_EQ(Elts, VTy.getNumElements());
126 
127       if ((S % 2) == 0) {
128         EXPECT_EQ((S / 2) * Elts, HalfSzTy.getSizeInBits());
129         EXPECT_EQ(S / 2, HalfSzTy.getScalarSizeInBits());
130         EXPECT_EQ(Elts, HalfSzTy.getNumElements());
131       }
132 
133       EXPECT_EQ((S * 2) * Elts, DoubleSzTy.getSizeInBits());
134       EXPECT_EQ(S * 2, DoubleSzTy.getScalarSizeInBits());
135       EXPECT_EQ(Elts, DoubleSzTy.getNumElements());
136 
137       if ((Elts % 2) == 0) {
138         EXPECT_EQ(S * (Elts / 2), HalfEltIfEvenTy.getSizeInBits());
139         EXPECT_EQ(S, HalfEltIfEvenTy.getScalarSizeInBits());
140         if (Elts > 2)
141           EXPECT_EQ(Elts / 2, HalfEltIfEvenTy.getNumElements());
142       }
143 
144       EXPECT_EQ(S * (Elts * 2), DoubleEltTy.getSizeInBits());
145       EXPECT_EQ(S, DoubleEltTy.getScalarSizeInBits());
146       EXPECT_EQ(Elts * 2, DoubleEltTy.getNumElements());
147 
148       // Test equality operators.
149       EXPECT_TRUE(VTy == VTy);
150       EXPECT_FALSE(VTy != VTy);
151 
152       // Test inequality operators on..
153       // ..different kind.
154       EXPECT_NE(VTy, STy);
155       // ..different #elts.
156       EXPECT_NE(VTy, DoubleEltTy);
157       // ..different scalar size.
158       EXPECT_NE(VTy, DoubleSzTy);
159 
160       // Test Type->LLT conversion.
161       Type *IRSTy = IntegerType::get(C, S);
162       Type *IRTy = VectorType::get(IRSTy, Elts);
163       EXPECT_EQ(VTy, LLT(*IRTy));
164     }
165   }
166 }
167 
168 TEST(LowLevelTypeTest, Pointer) {
169   LLVMContext C;
170 
171   for (unsigned AS : {0U, 1U, 127U, 0xffffU}) {
172     const LLT Ty = LLT::pointer(AS);
173 
174     // Test kind.
175     ASSERT_TRUE(Ty.isValid());
176     ASSERT_TRUE(Ty.isPointer());
177 
178     ASSERT_FALSE(Ty.isSized());
179     ASSERT_FALSE(Ty.isScalar());
180     ASSERT_FALSE(Ty.isVector());
181 
182     // Test addressspace.
183     EXPECT_EQ(AS, Ty.getAddressSpace());
184 
185     // Test equality operators.
186     EXPECT_TRUE(Ty == Ty);
187     EXPECT_FALSE(Ty != Ty);
188 
189     // Test Type->LLT conversion.
190     Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
191     EXPECT_EQ(Ty, LLT(*IRTy));
192   }
193 }
194 
195 TEST(LowLevelTypeTest, Invalid) {
196   const LLT Ty;
197 
198   ASSERT_FALSE(Ty.isValid());
199   ASSERT_FALSE(Ty.isScalar());
200   ASSERT_FALSE(Ty.isSized());
201   ASSERT_FALSE(Ty.isPointer());
202   ASSERT_FALSE(Ty.isVector());
203 }
204 
205 TEST(LowLevelTypeTest, Unsized) {
206   LLVMContext C;
207 
208   const LLT Ty = LLT::unsized();
209 
210   ASSERT_TRUE(Ty.isValid());
211   ASSERT_FALSE(Ty.isScalar());
212   ASSERT_FALSE(Ty.isSized());
213   ASSERT_FALSE(Ty.isPointer());
214   ASSERT_FALSE(Ty.isVector());
215 
216   Type *IRTy = Type::getLabelTy(C);
217   EXPECT_EQ(Ty, LLT(*IRTy));
218 }
219 }
220