xref: /llvm-project/llvm/unittests/SandboxIR/TypesTest.cpp (revision 830bd0e8f263c6efcfd37f38cc621b0476582b83)
1 //===- TypesTest.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/ADT/SmallPtrSet.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/DataLayout.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/SandboxIR/Constant.h"
18 #include "llvm/SandboxIR/Context.h"
19 #include "llvm/SandboxIR/Function.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "gtest/gtest.h"
22 
23 using namespace llvm;
24 
25 struct SandboxTypeTest : public testing::Test {
26   LLVMContext C;
27   std::unique_ptr<Module> M;
28 
29   void parseIR(LLVMContext &C, const char *IR) {
30     SMDiagnostic Err;
31     M = parseAssemblyString(IR, Err, C);
32     if (!M)
33       Err.print("SandboxTypeTest", errs());
34   }
35   BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
36     for (BasicBlock &BB : F)
37       if (BB.getName() == Name)
38         return &BB;
39     llvm_unreachable("Expected to find basic block!");
40   }
41 };
42 
43 TEST_F(SandboxTypeTest, Type) {
44   parseIR(C, R"IR(
45 define void @foo(i32 %v0) {
46   ret void
47 }
48 )IR");
49   llvm::Function *LLVMF = &*M->getFunction("foo");
50   sandboxir::Context Ctx(C);
51   auto *F = Ctx.createFunction(LLVMF);
52   sandboxir::Type *I32Ty = F->getArg(0)->getType();
53 
54   auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C);
55   auto *LLVMFloatTy = llvm::Type::getFloatTy(C);
56   auto *LLVMInt8Ty = llvm::Type::getInt8Ty(C);
57 
58   auto *Int32Ty = Ctx.getType(LLVMInt32Ty);
59   auto *FloatTy = Ctx.getType(LLVMFloatTy);
60 
61   // Check print().
62   std::string Buff1;
63   raw_string_ostream BS1(Buff1);
64   Int32Ty->print(BS1, /*IsForDebug=*/true, /*NoDetails=*/false);
65   std::string Buff2;
66   raw_string_ostream BS2(Buff2);
67   LLVMInt32Ty->print(BS2, /*IsForDebug=*/true, /*NoDetails=*/false);
68   EXPECT_EQ(Buff1, Buff2);
69 
70   // Check getContext().
71   EXPECT_EQ(&I32Ty->getContext(), &Ctx);
72   // Check that Ctx.getType(nullptr) == nullptr.
73   EXPECT_EQ(Ctx.getType(nullptr), nullptr);
74 
75 #define CHK(LLVMCreate, SBCheck)                                               \
76   Ctx.getType(llvm::Type::LLVMCreate(C))->SBCheck()
77   // Check isVoidTy().
78   EXPECT_TRUE(Ctx.getType(llvm::Type::getVoidTy(C))->isVoidTy());
79   EXPECT_TRUE(CHK(getVoidTy, isVoidTy));
80   // Check isHalfTy().
81   EXPECT_TRUE(CHK(getHalfTy, isHalfTy));
82   // Check isBFloatTy().
83   EXPECT_TRUE(CHK(getBFloatTy, isBFloatTy));
84   // Check is16bitFPTy().
85   EXPECT_TRUE(CHK(getHalfTy, is16bitFPTy));
86   // Check isFloatTy().
87   EXPECT_TRUE(CHK(getFloatTy, isFloatTy));
88   // Check isDoubleTy().
89   EXPECT_TRUE(CHK(getDoubleTy, isDoubleTy));
90   // Check isX86_FP80Ty().
91   EXPECT_TRUE(CHK(getX86_FP80Ty, isX86_FP80Ty));
92   // Check isFP128Ty().
93   EXPECT_TRUE(CHK(getFP128Ty, isFP128Ty));
94   // Check isPPC_FP128Ty().
95   EXPECT_TRUE(CHK(getPPC_FP128Ty, isPPC_FP128Ty));
96   // Check isIEEELikeFPTy().
97   EXPECT_TRUE(CHK(getFloatTy, isIEEELikeFPTy));
98   // Check isFloatingPointTy().
99   EXPECT_TRUE(CHK(getFloatTy, isFloatingPointTy));
100   EXPECT_TRUE(CHK(getDoubleTy, isFloatingPointTy));
101   // Check isMultiUnitFPType().
102   EXPECT_TRUE(CHK(getPPC_FP128Ty, isMultiUnitFPType));
103   EXPECT_FALSE(CHK(getFloatTy, isMultiUnitFPType));
104   // Check getFltSemantics().
105   EXPECT_EQ(&sandboxir::Type::getFloatTy(Ctx)->getFltSemantics(),
106             &llvm::Type::getFloatTy(C)->getFltSemantics());
107   // Check isX86_AMXTy().
108   EXPECT_TRUE(CHK(getX86_AMXTy, isX86_AMXTy));
109   // Check isTargetExtTy().
110   EXPECT_TRUE(Ctx.getType(llvm::TargetExtType::get(C, "foo"))->isTargetExtTy());
111   // Check isScalableTargetExtTy().
112   EXPECT_TRUE(Ctx.getType(llvm::TargetExtType::get(C, "aarch64.svcount"))
113                   ->isScalableTargetExtTy());
114   // Check isScalableTy().
115   EXPECT_TRUE(Ctx.getType(llvm::ScalableVectorType::get(LLVMInt32Ty, 2u))
116                   ->isScalableTy());
117   // Check isFPOrFPVectorTy().
118   EXPECT_TRUE(CHK(getFloatTy, isFPOrFPVectorTy));
119   EXPECT_FALSE(CHK(getInt32Ty, isFPOrFPVectorTy));
120   // Check isLabelTy().
121   EXPECT_TRUE(CHK(getLabelTy, isLabelTy));
122   // Check isMetadataTy().
123   EXPECT_TRUE(CHK(getMetadataTy, isMetadataTy));
124   // Check isTokenTy().
125   EXPECT_TRUE(CHK(getTokenTy, isTokenTy));
126   // Check isIntegerTy().
127   EXPECT_TRUE(CHK(getInt32Ty, isIntegerTy));
128   EXPECT_FALSE(CHK(getFloatTy, isIntegerTy));
129   // Check isIntegerTy(Bitwidth).
130   EXPECT_TRUE(LLVMInt32Ty->isIntegerTy(32u));
131   EXPECT_FALSE(LLVMInt32Ty->isIntegerTy(31u));
132   EXPECT_FALSE(Ctx.getType(llvm::Type::getFloatTy(C))->isIntegerTy(32u));
133   // Check isIntOrIntVectorTy().
134   EXPECT_TRUE(LLVMInt32Ty->isIntOrIntVectorTy());
135   EXPECT_TRUE(Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8))
136                   ->isIntOrIntVectorTy());
137   EXPECT_FALSE(Ctx.getType(LLVMFloatTy)->isIntOrIntVectorTy());
138   EXPECT_FALSE(Ctx.getType(llvm::FixedVectorType::get(LLVMFloatTy, 8))
139                    ->isIntOrIntVectorTy());
140   // Check isIntOrPtrTy().
141   EXPECT_TRUE(Int32Ty->isIntOrPtrTy());
142   EXPECT_TRUE(Ctx.getType(llvm::PointerType::get(C, 0u))->isIntOrPtrTy());
143   EXPECT_FALSE(FloatTy->isIntOrPtrTy());
144   // Check isFunctionTy().
145   EXPECT_TRUE(Ctx.getType(llvm::FunctionType::get(LLVMInt32Ty, {}, false))
146                   ->isFunctionTy());
147   // Check isStructTy().
148   EXPECT_TRUE(Ctx.getType(llvm::StructType::get(C))->isStructTy());
149   // Check isArrayTy().
150   EXPECT_TRUE(Ctx.getType(llvm::ArrayType::get(LLVMInt32Ty, 10))->isArrayTy());
151   // Check isPointerTy().
152   EXPECT_TRUE(Ctx.getType(llvm::PointerType::get(C, 0u))->isPointerTy());
153   // Check isPtrOrPtrVectroTy().
154   EXPECT_TRUE(
155       Ctx.getType(llvm::FixedVectorType::get(llvm::PointerType::get(C, 0u), 8u))
156           ->isPtrOrPtrVectorTy());
157   // Check isVectorTy().
158   EXPECT_TRUE(
159       Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8u))->isVectorTy());
160   // Check canLosslesslyBitCastTo().
161   auto *VecTy32x4 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 4u));
162   auto *VecTy32x2 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 2u));
163   auto *VecTy8x16 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt8Ty, 16u));
164   EXPECT_TRUE(VecTy32x4->canLosslesslyBitCastTo(VecTy8x16));
165   EXPECT_FALSE(VecTy32x4->canLosslesslyBitCastTo(VecTy32x2));
166   // Check isEmptyTy().
167   EXPECT_TRUE(Ctx.getType(llvm::StructType::get(C))->isEmptyTy());
168   // Check isFirstClassType().
169   EXPECT_TRUE(Int32Ty->isFirstClassType());
170   // Check isSingleValueType().
171   EXPECT_TRUE(Int32Ty->isSingleValueType());
172   // Check isAggregateType().
173   EXPECT_FALSE(Int32Ty->isAggregateType());
174   // Check isSized().
175   SmallPtrSet<sandboxir::Type *, 1> Visited;
176   EXPECT_TRUE(Int32Ty->isSized(&Visited));
177   // Check getPrimitiveSizeInBits().
178   EXPECT_EQ(VecTy32x2->getPrimitiveSizeInBits(), 32u * 2);
179   // Check getScalarSizeInBits().
180   EXPECT_EQ(VecTy32x2->getScalarSizeInBits(), 32u);
181   // Check getFPMantissaWidth().
182   EXPECT_EQ(FloatTy->getFPMantissaWidth(), LLVMFloatTy->getFPMantissaWidth());
183   // Check isIEEE().
184   EXPECT_EQ(FloatTy->isIEEE(), LLVMFloatTy->isIEEE());
185   // Check getScalarType().
186   EXPECT_EQ(
187       Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8u))->getScalarType(),
188       Int32Ty);
189 
190 #define CHK_GET(TY)                                                            \
191   EXPECT_EQ(Ctx.getType(llvm::Type::get##TY##Ty(C)),                           \
192             sandboxir::Type::get##TY##Ty(Ctx))
193   // Check getInt64Ty().
194   CHK_GET(Int64);
195   // Check getInt32Ty().
196   CHK_GET(Int32);
197   // Check getInt16Ty().
198   CHK_GET(Int16);
199   // Check getInt8Ty().
200   CHK_GET(Int8);
201   // Check getInt1Ty().
202   CHK_GET(Int1);
203   // Check getDoubleTy().
204   CHK_GET(Double);
205   // Check getFloatTy().
206   CHK_GET(Float);
207 }
208 
209 TEST_F(SandboxTypeTest, PointerType) {
210   parseIR(C, R"IR(
211 define void @foo(ptr %ptr) {
212   ret void
213 }
214 )IR");
215   llvm::Function *LLVMF = &*M->getFunction("foo");
216   sandboxir::Context Ctx(C);
217   auto *F = Ctx.createFunction(LLVMF);
218   // Check classof(), creation.
219   auto *PtrTy = cast<sandboxir::PointerType>(F->getArg(0)->getType());
220   // Check get(Ctx, AddressSpace).
221   auto *NewPtrTy2 = sandboxir::PointerType::get(Ctx, 0u);
222   EXPECT_EQ(NewPtrTy2, PtrTy);
223 }
224 
225 TEST_F(SandboxTypeTest, ArrayType) {
226   parseIR(C, R"IR(
227 define void @foo([2 x i8] %v0) {
228   ret void
229 }
230 )IR");
231   llvm::Function *LLVMF = &*M->getFunction("foo");
232   sandboxir::Context Ctx(C);
233   auto *F = Ctx.createFunction(LLVMF);
234   // Check classof(), creation.
235   [[maybe_unused]] auto *ArrayTy =
236       cast<sandboxir::ArrayType>(F->getArg(0)->getType());
237   // Check get().
238   auto *NewArrayTy =
239       sandboxir::ArrayType::get(sandboxir::Type::getInt8Ty(Ctx), 2u);
240   EXPECT_EQ(NewArrayTy, ArrayTy);
241 }
242 
243 TEST_F(SandboxTypeTest, StructType) {
244   parseIR(C, R"IR(
245 define void @foo({i32, i8} %v0) {
246   ret void
247 }
248 )IR");
249   llvm::Function *LLVMF = &*M->getFunction("foo");
250   sandboxir::Context Ctx(C);
251   auto *F = Ctx.createFunction(LLVMF);
252   auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
253   auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
254   // Check classof(), creation.
255   [[maybe_unused]] auto *StructTy =
256       cast<sandboxir::StructType>(F->getArg(0)->getType());
257   // Check get().
258   auto *NewStructTy = sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty});
259   EXPECT_EQ(NewStructTy, StructTy);
260   // Check get(Packed).
261   auto *NewStructTyPacked =
262       sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty}, /*Packed=*/true);
263   EXPECT_NE(NewStructTyPacked, StructTy);
264   EXPECT_TRUE(NewStructTyPacked->isPacked());
265 }
266 
267 TEST_F(SandboxTypeTest, VectorType) {
268   parseIR(C, R"IR(
269 define void @foo(<4 x i16> %vi0, <4 x float> %vf1, i8 %i0) {
270   ret void
271 }
272 )IR");
273   llvm::Function *LLVMF = &*M->getFunction("foo");
274   sandboxir::Context Ctx(C);
275   auto *F = Ctx.createFunction(LLVMF);
276   // Check classof(), creation, accessors
277   auto *VecTy = cast<sandboxir::VectorType>(F->getArg(0)->getType());
278   EXPECT_TRUE(VecTy->getElementType()->isIntegerTy(16));
279   EXPECT_EQ(VecTy->getElementCount(), ElementCount::getFixed(4));
280 
281   // get(ElementType, NumElements, Scalable)
282   EXPECT_EQ(sandboxir::VectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4,
283                                        /*Scalable=*/false),
284             F->getArg(0)->getType());
285   // get(ElementType, Other)
286   EXPECT_EQ(sandboxir::VectorType::get(
287                 sandboxir::Type::getInt16Ty(Ctx),
288                 cast<sandboxir::VectorType>(F->getArg(0)->getType())),
289             F->getArg(0)->getType());
290   auto *FVecTy = cast<sandboxir::VectorType>(F->getArg(1)->getType());
291   EXPECT_TRUE(FVecTy->getElementType()->isFloatTy());
292   // getInteger
293   auto *IVecTy = sandboxir::VectorType::getInteger(FVecTy);
294   EXPECT_TRUE(IVecTy->getElementType()->isIntegerTy(32));
295   EXPECT_EQ(IVecTy->getElementCount(), FVecTy->getElementCount());
296   // getExtendedElementCountVectorType
297   auto *ExtVecTy = sandboxir::VectorType::getExtendedElementVectorType(IVecTy);
298   EXPECT_TRUE(ExtVecTy->getElementType()->isIntegerTy(64));
299   EXPECT_EQ(ExtVecTy->getElementCount(), VecTy->getElementCount());
300   // getTruncatedElementVectorType
301   auto *TruncVecTy =
302       sandboxir::VectorType::getTruncatedElementVectorType(IVecTy);
303   EXPECT_TRUE(TruncVecTy->getElementType()->isIntegerTy(16));
304   EXPECT_EQ(TruncVecTy->getElementCount(), VecTy->getElementCount());
305   // getSubdividedVectorType
306   auto *SubVecTy = sandboxir::VectorType::getSubdividedVectorType(VecTy, 1);
307   EXPECT_TRUE(SubVecTy->getElementType()->isIntegerTy(8));
308   EXPECT_EQ(SubVecTy->getElementCount(), ElementCount::getFixed(8));
309   // getHalfElementsVectorType
310   auto *HalfVecTy = sandboxir::VectorType::getHalfElementsVectorType(VecTy);
311   EXPECT_TRUE(HalfVecTy->getElementType()->isIntegerTy(16));
312   EXPECT_EQ(HalfVecTy->getElementCount(), ElementCount::getFixed(2));
313   // getDoubleElementsVectorType
314   auto *DoubleVecTy = sandboxir::VectorType::getDoubleElementsVectorType(VecTy);
315   EXPECT_TRUE(DoubleVecTy->getElementType()->isIntegerTy(16));
316   EXPECT_EQ(DoubleVecTy->getElementCount(), ElementCount::getFixed(8));
317   // isValidElementType
318   auto *I8Type = F->getArg(2)->getType();
319   EXPECT_TRUE(I8Type->isIntegerTy());
320   EXPECT_TRUE(sandboxir::VectorType::isValidElementType(I8Type));
321   EXPECT_FALSE(sandboxir::VectorType::isValidElementType(FVecTy));
322 }
323 
324 TEST_F(SandboxTypeTest, FixedVectorType) {
325   parseIR(C, R"IR(
326 define void @foo(<4 x i16> %vi0, <4 x float> %vf1, i8 %i0) {
327   ret void
328 }
329 )IR");
330   llvm::Function *LLVMF = &*M->getFunction("foo");
331   sandboxir::Context Ctx(C);
332   auto *F = Ctx.createFunction(LLVMF);
333   // Check classof(), creation, accessors
334   auto *Vec4i16Ty = cast<sandboxir::FixedVectorType>(F->getArg(0)->getType());
335   EXPECT_TRUE(Vec4i16Ty->getElementType()->isIntegerTy(16));
336   EXPECT_EQ(Vec4i16Ty->getElementCount(), ElementCount::getFixed(4));
337 
338   // get(ElementType, NumElements)
339   EXPECT_EQ(
340       sandboxir::FixedVectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4),
341       F->getArg(0)->getType());
342   // get(ElementType, Other)
343   EXPECT_EQ(sandboxir::FixedVectorType::get(
344                 sandboxir::Type::getInt16Ty(Ctx),
345                 cast<sandboxir::FixedVectorType>(F->getArg(0)->getType())),
346             F->getArg(0)->getType());
347   auto *Vec4FTy = cast<sandboxir::FixedVectorType>(F->getArg(1)->getType());
348   EXPECT_TRUE(Vec4FTy->getElementType()->isFloatTy());
349   // getInteger
350   auto *Vec4i32Ty = sandboxir::FixedVectorType::getInteger(Vec4FTy);
351   EXPECT_TRUE(Vec4i32Ty->getElementType()->isIntegerTy(32));
352   EXPECT_EQ(Vec4i32Ty->getElementCount(), Vec4FTy->getElementCount());
353   // getExtendedElementCountVectorType
354   auto *Vec4i64Ty =
355       sandboxir::FixedVectorType::getExtendedElementVectorType(Vec4i16Ty);
356   EXPECT_TRUE(Vec4i64Ty->getElementType()->isIntegerTy(32));
357   EXPECT_EQ(Vec4i64Ty->getElementCount(), Vec4i16Ty->getElementCount());
358   // getTruncatedElementVectorType
359   auto *Vec4i8Ty =
360       sandboxir::FixedVectorType::getTruncatedElementVectorType(Vec4i16Ty);
361   EXPECT_TRUE(Vec4i8Ty->getElementType()->isIntegerTy(8));
362   EXPECT_EQ(Vec4i8Ty->getElementCount(), Vec4i8Ty->getElementCount());
363   // getSubdividedVectorType
364   auto *Vec8i8Ty =
365       sandboxir::FixedVectorType::getSubdividedVectorType(Vec4i16Ty, 1);
366   EXPECT_TRUE(Vec8i8Ty->getElementType()->isIntegerTy(8));
367   EXPECT_EQ(Vec8i8Ty->getElementCount(), ElementCount::getFixed(8));
368   // getNumElements
369   EXPECT_EQ(Vec8i8Ty->getNumElements(), 8u);
370   // getHalfElementsVectorType
371   auto *Vec2i16Ty =
372       sandboxir::FixedVectorType::getHalfElementsVectorType(Vec4i16Ty);
373   EXPECT_TRUE(Vec2i16Ty->getElementType()->isIntegerTy(16));
374   EXPECT_EQ(Vec2i16Ty->getElementCount(), ElementCount::getFixed(2));
375   // getDoubleElementsVectorType
376   auto *Vec8i16Ty =
377       sandboxir::FixedVectorType::getDoubleElementsVectorType(Vec4i16Ty);
378   EXPECT_TRUE(Vec8i16Ty->getElementType()->isIntegerTy(16));
379   EXPECT_EQ(Vec8i16Ty->getElementCount(), ElementCount::getFixed(8));
380 }
381 
382 TEST_F(SandboxTypeTest, ScalableVectorType) {
383   parseIR(C, R"IR(
384 define void @foo(<vscale x 4 x i16> %vi0, <vscale x 4 x float> %vf1, i8 %i0) {
385   ret void
386 }
387 )IR");
388   llvm::Function *LLVMF = &*M->getFunction("foo");
389   sandboxir::Context Ctx(C);
390   auto *F = Ctx.createFunction(LLVMF);
391   // Check classof(), creation, accessors
392   auto *Vec4i16Ty =
393       cast<sandboxir::ScalableVectorType>(F->getArg(0)->getType());
394   EXPECT_TRUE(Vec4i16Ty->getElementType()->isIntegerTy(16));
395   EXPECT_EQ(Vec4i16Ty->getMinNumElements(), 4u);
396 
397   // get(ElementType, NumElements)
398   EXPECT_EQ(
399       sandboxir::ScalableVectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4),
400       F->getArg(0)->getType());
401   // get(ElementType, Other)
402   EXPECT_EQ(sandboxir::ScalableVectorType::get(
403                 sandboxir::Type::getInt16Ty(Ctx),
404                 cast<sandboxir::ScalableVectorType>(F->getArg(0)->getType())),
405             F->getArg(0)->getType());
406   auto *Vec4FTy = cast<sandboxir::ScalableVectorType>(F->getArg(1)->getType());
407   EXPECT_TRUE(Vec4FTy->getElementType()->isFloatTy());
408   // getInteger
409   auto *Vec4i32Ty = sandboxir::ScalableVectorType::getInteger(Vec4FTy);
410   EXPECT_TRUE(Vec4i32Ty->getElementType()->isIntegerTy(32));
411   EXPECT_EQ(Vec4i32Ty->getMinNumElements(), Vec4FTy->getMinNumElements());
412   // getExtendedElementCountVectorType
413   auto *Vec4i64Ty =
414       sandboxir::ScalableVectorType::getExtendedElementVectorType(Vec4i16Ty);
415   EXPECT_TRUE(Vec4i64Ty->getElementType()->isIntegerTy(32));
416   EXPECT_EQ(Vec4i64Ty->getMinNumElements(), Vec4i16Ty->getMinNumElements());
417   // getTruncatedElementVectorType
418   auto *Vec4i8Ty =
419       sandboxir::ScalableVectorType::getTruncatedElementVectorType(Vec4i16Ty);
420   EXPECT_TRUE(Vec4i8Ty->getElementType()->isIntegerTy(8));
421   EXPECT_EQ(Vec4i8Ty->getMinNumElements(), Vec4i8Ty->getMinNumElements());
422   // getSubdividedVectorType
423   auto *Vec8i8Ty =
424       sandboxir::ScalableVectorType::getSubdividedVectorType(Vec4i16Ty, 1);
425   EXPECT_TRUE(Vec8i8Ty->getElementType()->isIntegerTy(8));
426   EXPECT_EQ(Vec8i8Ty->getMinNumElements(), 8u);
427   // getMinNumElements
428   EXPECT_EQ(Vec8i8Ty->getMinNumElements(), 8u);
429   // getHalfElementsVectorType
430   auto *Vec2i16Ty =
431       sandboxir::ScalableVectorType::getHalfElementsVectorType(Vec4i16Ty);
432   EXPECT_TRUE(Vec2i16Ty->getElementType()->isIntegerTy(16));
433   EXPECT_EQ(Vec2i16Ty->getMinNumElements(), 2u);
434   // getDoubleElementsVectorType
435   auto *Vec8i16Ty =
436       sandboxir::ScalableVectorType::getDoubleElementsVectorType(Vec4i16Ty);
437   EXPECT_TRUE(Vec8i16Ty->getElementType()->isIntegerTy(16));
438   EXPECT_EQ(Vec8i16Ty->getMinNumElements(), 8u);
439 }
440 
441 TEST_F(SandboxTypeTest, FunctionType) {
442   parseIR(C, R"IR(
443 define void @foo() {
444   ret void
445 }
446 )IR");
447   llvm::Function *LLVMF = &*M->getFunction("foo");
448   sandboxir::Context Ctx(C);
449   auto *F = Ctx.createFunction(LLVMF);
450   // Check classof(), creation.
451   [[maybe_unused]] auto *FTy =
452       cast<sandboxir::FunctionType>(F->getFunctionType());
453 }
454 
455 TEST_F(SandboxTypeTest, IntegerType) {
456   parseIR(C, R"IR(
457 define void @foo(i32 %v0) {
458   ret void
459 }
460 )IR");
461   llvm::Function *LLVMF = &*M->getFunction("foo");
462   sandboxir::Context Ctx(C);
463   auto *F = Ctx.createFunction(LLVMF);
464   // Check classof(), creation.
465   auto *Int32Ty = cast<sandboxir::IntegerType>(F->getArg(0)->getType());
466   // Check get().
467   auto *NewInt32Ty = sandboxir::IntegerType::get(Ctx, 32u);
468   EXPECT_EQ(NewInt32Ty, Int32Ty);
469 }
470