1 //===- VecUtilsTest.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/Transforms/Vectorize/SandboxVectorizer/VecUtils.h" 10 #include "llvm/Analysis/AliasAnalysis.h" 11 #include "llvm/Analysis/AssumptionCache.h" 12 #include "llvm/Analysis/BasicAliasAnalysis.h" 13 #include "llvm/Analysis/LoopInfo.h" 14 #include "llvm/Analysis/ScalarEvolution.h" 15 #include "llvm/Analysis/TargetLibraryInfo.h" 16 #include "llvm/AsmParser/Parser.h" 17 #include "llvm/IR/DataLayout.h" 18 #include "llvm/IR/Dominators.h" 19 #include "llvm/SandboxIR/Context.h" 20 #include "llvm/SandboxIR/Function.h" 21 #include "llvm/SandboxIR/Type.h" 22 #include "llvm/Support/SourceMgr.h" 23 #include "gtest/gtest.h" 24 25 using namespace llvm; 26 27 struct VecUtilsTest : public testing::Test { 28 LLVMContext C; 29 std::unique_ptr<Module> M; 30 std::unique_ptr<AssumptionCache> AC; 31 std::unique_ptr<TargetLibraryInfoImpl> TLII; 32 std::unique_ptr<TargetLibraryInfo> TLI; 33 std::unique_ptr<DominatorTree> DT; 34 std::unique_ptr<LoopInfo> LI; 35 std::unique_ptr<ScalarEvolution> SE; 36 void parseIR(const char *IR) { 37 SMDiagnostic Err; 38 M = parseAssemblyString(IR, Err, C); 39 if (!M) 40 Err.print("VecUtilsTest", errs()); 41 } 42 ScalarEvolution &getSE(llvm::Function &LLVMF) { 43 TLII = std::make_unique<TargetLibraryInfoImpl>(); 44 TLI = std::make_unique<TargetLibraryInfo>(*TLII); 45 AC = std::make_unique<AssumptionCache>(LLVMF); 46 DT = std::make_unique<DominatorTree>(LLVMF); 47 LI = std::make_unique<LoopInfo>(*DT); 48 SE = std::make_unique<ScalarEvolution>(LLVMF, *TLI, *AC, *DT, *LI); 49 return *SE; 50 } 51 }; 52 53 TEST_F(VecUtilsTest, GetNumElements) { 54 sandboxir::Context Ctx(C); 55 auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx); 56 EXPECT_EQ(sandboxir::VecUtils::getNumElements(ElemTy), 1); 57 auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2); 58 EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy), 2); 59 auto *VTy1 = sandboxir::FixedVectorType::get(ElemTy, 1); 60 EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy1), 1); 61 } 62 63 TEST_F(VecUtilsTest, GetElementType) { 64 sandboxir::Context Ctx(C); 65 auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx); 66 EXPECT_EQ(sandboxir::VecUtils::getElementType(ElemTy), ElemTy); 67 auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2); 68 EXPECT_EQ(sandboxir::VecUtils::getElementType(VTy), ElemTy); 69 } 70 71 TEST_F(VecUtilsTest, AreConsecutive_gep_float) { 72 parseIR(R"IR( 73 define void @foo(ptr %ptr) { 74 %gep0 = getelementptr inbounds float, ptr %ptr, i64 0 75 %gep1 = getelementptr inbounds float, ptr %ptr, i64 1 76 %gep2 = getelementptr inbounds float, ptr %ptr, i64 2 77 %gep3 = getelementptr inbounds float, ptr %ptr, i64 3 78 79 %ld0 = load float, ptr %gep0 80 %ld1 = load float, ptr %gep1 81 %ld2 = load float, ptr %gep2 82 %ld3 = load float, ptr %gep3 83 84 %v2ld0 = load <2 x float>, ptr %gep0 85 %v2ld1 = load <2 x float>, ptr %gep1 86 %v2ld2 = load <2 x float>, ptr %gep2 87 %v2ld3 = load <2 x float>, ptr %gep3 88 89 %v3ld0 = load <3 x float>, ptr %gep0 90 %v3ld1 = load <3 x float>, ptr %gep1 91 %v3ld2 = load <3 x float>, ptr %gep2 92 %v3ld3 = load <3 x float>, ptr %gep3 93 ret void 94 } 95 )IR"); 96 Function &LLVMF = *M->getFunction("foo"); 97 const DataLayout &DL = M->getDataLayout(); 98 auto &SE = getSE(LLVMF); 99 100 sandboxir::Context Ctx(C); 101 auto &F = *Ctx.createFunction(&LLVMF); 102 103 auto &BB = *F.begin(); 104 auto It = std::next(BB.begin(), 4); 105 auto *L0 = cast<sandboxir::LoadInst>(&*It++); 106 auto *L1 = cast<sandboxir::LoadInst>(&*It++); 107 auto *L2 = cast<sandboxir::LoadInst>(&*It++); 108 auto *L3 = cast<sandboxir::LoadInst>(&*It++); 109 110 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++); 111 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++); 112 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++); 113 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++); 114 115 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++); 116 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++); 117 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++); 118 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++); 119 120 // Scalar 121 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL)); 122 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL)); 123 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL)); 124 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL)); 125 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL)); 126 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL)); 127 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL)); 128 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL)); 129 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL)); 130 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL)); 131 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL)); 132 133 // Check 2-wide loads 134 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL)); 135 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL)); 136 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL)); 137 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL)); 138 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL)); 139 140 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 141 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 142 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 143 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 144 145 // Check 3-wide loads 146 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL)); 147 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL)); 148 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL)); 149 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL)); 150 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL)); 151 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL)); 152 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL)); 153 154 // Check mixes of vectors and scalar 155 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL)); 156 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL)); 157 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL)); 158 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL)); 159 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL)); 160 161 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL)); 162 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL)); 163 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL)); 164 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL)); 165 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL)); 166 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL)); 167 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL)); 168 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL)); 169 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL)); 170 } 171 172 TEST_F(VecUtilsTest, AreConsecutive_gep_i8) { 173 parseIR(R"IR( 174 define void @foo(ptr %ptr) { 175 %gep0 = getelementptr inbounds i8, ptr %ptr, i64 0 176 %gep1 = getelementptr inbounds i8, ptr %ptr, i64 4 177 %gep2 = getelementptr inbounds i8, ptr %ptr, i64 8 178 %gep3 = getelementptr inbounds i8, ptr %ptr, i64 12 179 180 %ld0 = load float, ptr %gep0 181 %ld1 = load float, ptr %gep1 182 %ld2 = load float, ptr %gep2 183 %ld3 = load float, ptr %gep3 184 185 %v2ld0 = load <2 x float>, ptr %gep0 186 %v2ld1 = load <2 x float>, ptr %gep1 187 %v2ld2 = load <2 x float>, ptr %gep2 188 %v2ld3 = load <2 x float>, ptr %gep3 189 190 %v3ld0 = load <3 x float>, ptr %gep0 191 %v3ld1 = load <3 x float>, ptr %gep1 192 %v3ld2 = load <3 x float>, ptr %gep2 193 %v3ld3 = load <3 x float>, ptr %gep3 194 ret void 195 } 196 )IR"); 197 Function &LLVMF = *M->getFunction("foo"); 198 const DataLayout &DL = M->getDataLayout(); 199 auto &SE = getSE(LLVMF); 200 201 sandboxir::Context Ctx(C); 202 auto &F = *Ctx.createFunction(&LLVMF); 203 auto &BB = *F.begin(); 204 auto It = std::next(BB.begin(), 4); 205 auto *L0 = cast<sandboxir::LoadInst>(&*It++); 206 auto *L1 = cast<sandboxir::LoadInst>(&*It++); 207 auto *L2 = cast<sandboxir::LoadInst>(&*It++); 208 auto *L3 = cast<sandboxir::LoadInst>(&*It++); 209 210 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++); 211 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++); 212 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++); 213 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++); 214 215 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++); 216 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++); 217 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++); 218 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++); 219 220 // Scalar 221 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL)); 222 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL)); 223 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL)); 224 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL)); 225 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL)); 226 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL)); 227 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL)); 228 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL)); 229 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL)); 230 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL)); 231 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL)); 232 233 // Check 2-wide loads 234 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL)); 235 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL)); 236 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL)); 237 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL)); 238 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL)); 239 240 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 241 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 242 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 243 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 244 245 // Check 3-wide loads 246 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL)); 247 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL)); 248 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL)); 249 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL)); 250 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL)); 251 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL)); 252 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL)); 253 254 // Check mixes of vectors and scalar 255 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL)); 256 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL)); 257 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL)); 258 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL)); 259 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL)); 260 261 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL)); 262 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL)); 263 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL)); 264 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL)); 265 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL)); 266 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL)); 267 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL)); 268 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL)); 269 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL)); 270 } 271 272 TEST_F(VecUtilsTest, AreConsecutive_gep_i1) { 273 parseIR(R"IR( 274 define void @foo(ptr %ptr) { 275 %gep0 = getelementptr inbounds i1, ptr %ptr, i64 0 276 %gep1 = getelementptr inbounds i2, ptr %ptr, i64 4 277 %gep2 = getelementptr inbounds i3, ptr %ptr, i64 8 278 %gep3 = getelementptr inbounds i7, ptr %ptr, i64 12 279 280 %ld0 = load float, ptr %gep0 281 %ld1 = load float, ptr %gep1 282 %ld2 = load float, ptr %gep2 283 %ld3 = load float, ptr %gep3 284 285 %v2ld0 = load <2 x float>, ptr %gep0 286 %v2ld1 = load <2 x float>, ptr %gep1 287 %v2ld2 = load <2 x float>, ptr %gep2 288 %v2ld3 = load <2 x float>, ptr %gep3 289 290 %v3ld0 = load <3 x float>, ptr %gep0 291 %v3ld1 = load <3 x float>, ptr %gep1 292 %v3ld2 = load <3 x float>, ptr %gep2 293 %v3ld3 = load <3 x float>, ptr %gep3 294 ret void 295 } 296 )IR"); 297 Function &LLVMF = *M->getFunction("foo"); 298 const DataLayout &DL = M->getDataLayout(); 299 auto &SE = getSE(LLVMF); 300 301 sandboxir::Context Ctx(C); 302 auto &F = *Ctx.createFunction(&LLVMF); 303 auto &BB = *F.begin(); 304 auto It = std::next(BB.begin(), 4); 305 auto *L0 = cast<sandboxir::LoadInst>(&*It++); 306 auto *L1 = cast<sandboxir::LoadInst>(&*It++); 307 auto *L2 = cast<sandboxir::LoadInst>(&*It++); 308 auto *L3 = cast<sandboxir::LoadInst>(&*It++); 309 310 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++); 311 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++); 312 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++); 313 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++); 314 315 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++); 316 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++); 317 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++); 318 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++); 319 320 // Scalar 321 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL)); 322 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL)); 323 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL)); 324 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL)); 325 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL)); 326 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL)); 327 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL)); 328 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL)); 329 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL)); 330 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL)); 331 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL)); 332 333 // Check 2-wide loads 334 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL)); 335 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL)); 336 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL)); 337 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL)); 338 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL)); 339 340 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 341 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 342 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 343 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL)); 344 345 // Check 3-wide loads 346 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL)); 347 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL)); 348 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL)); 349 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL)); 350 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL)); 351 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL)); 352 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL)); 353 354 // Check mixes of vectors and scalar 355 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL)); 356 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL)); 357 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL)); 358 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL)); 359 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL)); 360 361 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL)); 362 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL)); 363 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL)); 364 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL)); 365 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL)); 366 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL)); 367 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL)); 368 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL)); 369 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL)); 370 } 371 372 TEST_F(VecUtilsTest, GetNumLanes) { 373 parseIR(R"IR( 374 define <4 x float> @foo(float %v, <2 x float> %v2, <4 x float> %ret, ptr %ptr) { 375 store float %v, ptr %ptr 376 store <2 x float> %v2, ptr %ptr 377 ret <4 x float> %ret 378 } 379 )IR"); 380 Function &LLVMF = *M->getFunction("foo"); 381 382 sandboxir::Context Ctx(C); 383 auto &F = *Ctx.createFunction(&LLVMF); 384 auto &BB = *F.begin(); 385 386 auto It = BB.begin(); 387 auto *S0 = cast<sandboxir::StoreInst>(&*It++); 388 auto *S1 = cast<sandboxir::StoreInst>(&*It++); 389 auto *Ret = cast<sandboxir::ReturnInst>(&*It++); 390 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0->getValueOperand()->getType()), 391 1u); 392 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0), 1); 393 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1->getValueOperand()->getType()), 394 2u); 395 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1), 2); 396 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret->getReturnValue()->getType()), 397 4u); 398 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret), 4); 399 400 SmallVector<sandboxir::Value *> Bndl({S0, S1, Ret}); 401 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Bndl), 7u); 402 } 403 404 TEST_F(VecUtilsTest, GetWideType) { 405 sandboxir::Context Ctx(C); 406 407 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx); 408 auto *Int32X4Ty = sandboxir::FixedVectorType::get(Int32Ty, 4); 409 EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32Ty, 4), Int32X4Ty); 410 auto *Int32X8Ty = sandboxir::FixedVectorType::get(Int32Ty, 8); 411 EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32X4Ty, 2), Int32X8Ty); 412 } 413