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/DataLayout.h"
12 #include "llvm/IR/DerivedTypes.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Type.h"
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
19 // Define a pretty printer to help debugging when things go wrong.
20 namespace llvm {
21 std::ostream &
22 operator<<(std::ostream &OS, const llvm::LLT Ty) {
23   std::string Repr;
24   raw_string_ostream SS{Repr};
25   Ty.print(SS);
26   OS << SS.str();
27   return OS;
28 }
29 }
30 
31 namespace {
32 
33 TEST(LowLevelTypeTest, Scalar) {
34   LLVMContext C;
35   DataLayout DL("");
36 
37   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) {
38     const LLT Ty = LLT::scalar(S);
39     const LLT HalfTy = (S % 2) == 0 ? Ty.halfScalarSize() : Ty;
40     const LLT DoubleTy = Ty.doubleScalarSize();
41 
42     // Test kind.
43     for (const LLT TestTy : {Ty, HalfTy, DoubleTy}) {
44       ASSERT_TRUE(TestTy.isValid());
45       ASSERT_TRUE(TestTy.isScalar());
46 
47       ASSERT_FALSE(TestTy.isPointer());
48       ASSERT_FALSE(TestTy.isVector());
49     }
50 
51     // Test sizes.
52     EXPECT_EQ(S, Ty.getSizeInBits());
53     EXPECT_EQ(S, Ty.getScalarSizeInBits());
54 
55     EXPECT_EQ(S*2, DoubleTy.getSizeInBits());
56     EXPECT_EQ(S*2, DoubleTy.getScalarSizeInBits());
57 
58     if ((S % 2) == 0) {
59       EXPECT_EQ(S/2, HalfTy.getSizeInBits());
60       EXPECT_EQ(S/2, HalfTy.getScalarSizeInBits());
61     }
62 
63     // Test equality operators.
64     EXPECT_TRUE(Ty == Ty);
65     EXPECT_FALSE(Ty != Ty);
66 
67     EXPECT_NE(Ty, DoubleTy);
68 
69     // Test Type->LLT conversion.
70     Type *IRTy = IntegerType::get(C, S);
71     EXPECT_EQ(Ty, LLT(*IRTy, DL));
72   }
73 }
74 
75 TEST(LowLevelTypeTest, Vector) {
76   LLVMContext C;
77   DataLayout DL("");
78 
79   for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) {
80     for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) {
81       const LLT STy = LLT::scalar(S);
82       const LLT VTy = LLT::vector(Elts, S);
83 
84       // Test the alternative vector().
85       {
86         const LLT VSTy = LLT::vector(Elts, STy);
87         EXPECT_EQ(VTy, VSTy);
88       }
89 
90       // Test getElementType().
91       EXPECT_EQ(STy, VTy.getElementType());
92 
93       const LLT HalfSzTy = ((S % 2) == 0) ? VTy.halfScalarSize() : VTy;
94       const LLT DoubleSzTy = VTy.doubleScalarSize();
95 
96       // halfElements requires an even number of elements.
97       const LLT HalfEltIfEvenTy = ((Elts % 2) == 0) ?  VTy.halfElements() : VTy;
98       const LLT DoubleEltTy = VTy.doubleElements();
99 
100       // Test kind.
101       for (const LLT TestTy : {VTy, HalfSzTy, DoubleSzTy, DoubleEltTy}) {
102         ASSERT_TRUE(TestTy.isValid());
103         ASSERT_TRUE(TestTy.isVector());
104 
105         ASSERT_FALSE(TestTy.isScalar());
106         ASSERT_FALSE(TestTy.isPointer());
107       }
108 
109       // Test halving elements to a scalar.
110       {
111         ASSERT_TRUE(HalfEltIfEvenTy.isValid());
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, DL));
164     }
165   }
166 }
167 
168 TEST(LowLevelTypeTest, Pointer) {
169   LLVMContext C;
170   DataLayout DL("");
171 
172   for (unsigned AS : {0U, 1U, 127U, 0xffffU}) {
173     const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
174 
175     // Test kind.
176     ASSERT_TRUE(Ty.isValid());
177     ASSERT_TRUE(Ty.isPointer());
178 
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, DL));
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.isPointer());
201   ASSERT_FALSE(Ty.isVector());
202 }
203 
204 }
205