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