xref: /llvm-project/llvm/unittests/IR/VectorTypeUtilsTest.cpp (revision 1ee740a79620aa680f68d873d6a7b5cfa1df7b19)
1 //===------- VectorTypeUtilsTest.cpp - Vector utils tests -----------------===//
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/IR/VectorTypeUtils.h"
10 #include "llvm/IR/DerivedTypes.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "gtest/gtest.h"
13 
14 using namespace llvm;
15 
16 namespace {
17 
18 class VectorTypeUtilsTest : public ::testing::Test {};
19 
20 TEST(VectorTypeUtilsTest, TestToVectorizedTy) {
21   LLVMContext C;
22 
23   Type *ITy = Type::getInt32Ty(C);
24   Type *FTy = Type::getFloatTy(C);
25   Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
26   Type *MixedStructTy = StructType::get(FTy, ITy);
27   Type *VoidTy = Type::getVoidTy(C);
28 
29   for (ElementCount VF :
30        {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
31     Type *IntVec = toVectorizedTy(ITy, VF);
32     EXPECT_TRUE(isa<VectorType>(IntVec));
33     EXPECT_EQ(IntVec, VectorType::get(ITy, VF));
34 
35     Type *FloatVec = toVectorizedTy(FTy, VF);
36     EXPECT_TRUE(isa<VectorType>(FloatVec));
37     EXPECT_EQ(FloatVec, VectorType::get(FTy, VF));
38 
39     Type *WideHomogeneousStructTy = toVectorizedTy(HomogeneousStructTy, VF);
40     EXPECT_TRUE(isa<StructType>(WideHomogeneousStructTy));
41     EXPECT_TRUE(
42         cast<StructType>(WideHomogeneousStructTy)->containsHomogeneousTypes());
43     EXPECT_TRUE(cast<StructType>(WideHomogeneousStructTy)->getNumElements() ==
44                 3);
45     EXPECT_TRUE(cast<StructType>(WideHomogeneousStructTy)->getElementType(0) ==
46                 VectorType::get(FTy, VF));
47 
48     Type *WideMixedStructTy = toVectorizedTy(MixedStructTy, VF);
49     EXPECT_TRUE(isa<StructType>(WideMixedStructTy));
50     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getNumElements() == 2);
51     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(0) ==
52                 VectorType::get(FTy, VF));
53     EXPECT_TRUE(cast<StructType>(WideMixedStructTy)->getElementType(1) ==
54                 VectorType::get(ITy, VF));
55 
56     EXPECT_EQ(toVectorizedTy(VoidTy, VF), VoidTy);
57   }
58 
59   ElementCount ScalarVF = ElementCount::getFixed(1);
60   for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
61     EXPECT_EQ(toVectorizedTy(Ty, ScalarVF), Ty);
62   }
63 }
64 
65 TEST(VectorTypeUtilsTest, TestToScalarizedTy) {
66   LLVMContext C;
67 
68   Type *ITy = Type::getInt32Ty(C);
69   Type *FTy = Type::getFloatTy(C);
70   Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
71   Type *MixedStructTy = StructType::get(FTy, ITy);
72   Type *VoidTy = Type::getVoidTy(C);
73 
74   for (ElementCount VF : {ElementCount::getFixed(1), ElementCount::getFixed(4),
75                           ElementCount::getScalable(2)}) {
76     for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy, VoidTy}) {
77       // toScalarizedTy should be the inverse of toVectorizedTy.
78       EXPECT_EQ(toScalarizedTy(toVectorizedTy(Ty, VF)), Ty);
79     };
80   }
81 }
82 
83 TEST(VectorTypeUtilsTest, TestGetContainedTypes) {
84   LLVMContext C;
85 
86   Type *ITy = Type::getInt32Ty(C);
87   Type *FTy = Type::getFloatTy(C);
88   Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
89   Type *MixedStructTy = StructType::get(FTy, ITy);
90   Type *VoidTy = Type::getVoidTy(C);
91 
92   EXPECT_EQ(getContainedTypes(ITy), ArrayRef<Type *>({ITy}));
93   EXPECT_EQ(getContainedTypes(FTy), ArrayRef<Type *>({FTy}));
94   EXPECT_EQ(getContainedTypes(VoidTy), ArrayRef<Type *>({VoidTy}));
95   EXPECT_EQ(getContainedTypes(HomogeneousStructTy),
96             ArrayRef<Type *>({FTy, FTy, FTy}));
97   EXPECT_EQ(getContainedTypes(MixedStructTy), ArrayRef<Type *>({FTy, ITy}));
98 }
99 
100 TEST(VectorTypeUtilsTest, TestIsVectorizedTy) {
101   LLVMContext C;
102 
103   Type *ITy = Type::getInt32Ty(C);
104   Type *FTy = Type::getFloatTy(C);
105   Type *NarrowStruct = StructType::get(FTy, ITy);
106   Type *VoidTy = Type::getVoidTy(C);
107 
108   EXPECT_FALSE(isVectorizedTy(ITy));
109   EXPECT_FALSE(isVectorizedTy(NarrowStruct));
110   EXPECT_FALSE(isVectorizedTy(VoidTy));
111 
112   ElementCount VF = ElementCount::getFixed(4);
113   EXPECT_TRUE(isVectorizedTy(toVectorizedTy(ITy, VF)));
114   EXPECT_TRUE(isVectorizedTy(toVectorizedTy(NarrowStruct, VF)));
115 
116   Type *MixedVFStruct =
117       StructType::get(VectorType::get(ITy, ElementCount::getFixed(2)),
118                       VectorType::get(ITy, ElementCount::getFixed(4)));
119   EXPECT_FALSE(isVectorizedTy(MixedVFStruct));
120 
121   // Currently only literals types are considered wide.
122   Type *NamedWideStruct = StructType::create("Named", VectorType::get(ITy, VF),
123                                              VectorType::get(ITy, VF));
124   EXPECT_FALSE(isVectorizedTy(NamedWideStruct));
125 
126   // Currently only unpacked types are considered wide.
127   Type *PackedWideStruct = StructType::get(
128       C, ArrayRef<Type *>{VectorType::get(ITy, VF), VectorType::get(ITy, VF)},
129       /*isPacked=*/true);
130   EXPECT_FALSE(isVectorizedTy(PackedWideStruct));
131 }
132 
133 TEST(VectorTypeUtilsTest, TestGetVectorizedTypeVF) {
134   LLVMContext C;
135 
136   Type *ITy = Type::getInt32Ty(C);
137   Type *FTy = Type::getFloatTy(C);
138   Type *HomogeneousStructTy = StructType::get(FTy, FTy, FTy);
139   Type *MixedStructTy = StructType::get(FTy, ITy);
140 
141   for (ElementCount VF :
142        {ElementCount::getFixed(4), ElementCount::getScalable(2)}) {
143     for (Type *Ty : {ITy, FTy, HomogeneousStructTy, MixedStructTy}) {
144       EXPECT_EQ(getVectorizedTypeVF(toVectorizedTy(Ty, VF)), VF);
145     };
146   }
147 }
148 
149 } // namespace
150