620 lines · cpp
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-exception6//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 "gmock/gmock.h"24#include "gtest/gtest.h"25 26using namespace llvm;27 28struct VecUtilsTest : public testing::Test {29 LLVMContext C;30 std::unique_ptr<Module> M;31 std::unique_ptr<AssumptionCache> AC;32 std::unique_ptr<TargetLibraryInfoImpl> TLII;33 std::unique_ptr<TargetLibraryInfo> TLI;34 std::unique_ptr<DominatorTree> DT;35 std::unique_ptr<LoopInfo> LI;36 std::unique_ptr<ScalarEvolution> SE;37 void parseIR(const char *IR) {38 SMDiagnostic Err;39 M = parseAssemblyString(IR, Err, C);40 if (!M) {41 Err.print("VecUtilsTest", errs());42 return;43 }44 45 TLII = std::make_unique<TargetLibraryInfoImpl>(M->getTargetTriple());46 TLI = std::make_unique<TargetLibraryInfo>(*TLII);47 }48 49 ScalarEvolution &getSE(llvm::Function &LLVMF) {50 AC = std::make_unique<AssumptionCache>(LLVMF);51 DT = std::make_unique<DominatorTree>(LLVMF);52 LI = std::make_unique<LoopInfo>(*DT);53 SE = std::make_unique<ScalarEvolution>(LLVMF, *TLI, *AC, *DT, *LI);54 return *SE;55 }56};57 58sandboxir::BasicBlock &getBasicBlockByName(sandboxir::Function &F,59 StringRef Name) {60 for (sandboxir::BasicBlock &BB : F)61 if (BB.getName() == Name)62 return BB;63 llvm_unreachable("Expected to find basic block!");64}65 66TEST_F(VecUtilsTest, GetNumElements) {67 sandboxir::Context Ctx(C);68 auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx);69 EXPECT_EQ(sandboxir::VecUtils::getNumElements(ElemTy), 1);70 auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2);71 EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy), 2);72 auto *VTy1 = sandboxir::FixedVectorType::get(ElemTy, 1);73 EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy1), 1);74}75 76TEST_F(VecUtilsTest, GetElementType) {77 sandboxir::Context Ctx(C);78 auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx);79 EXPECT_EQ(sandboxir::VecUtils::getElementType(ElemTy), ElemTy);80 auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2);81 EXPECT_EQ(sandboxir::VecUtils::getElementType(VTy), ElemTy);82}83 84TEST_F(VecUtilsTest, AreConsecutive_gep_float) {85 parseIR(R"IR(86define void @foo(ptr %ptr) {87 %gep0 = getelementptr inbounds float, ptr %ptr, i64 088 %gep1 = getelementptr inbounds float, ptr %ptr, i64 189 %gep2 = getelementptr inbounds float, ptr %ptr, i64 290 %gep3 = getelementptr inbounds float, ptr %ptr, i64 391 92 %ld0 = load float, ptr %gep093 %ld1 = load float, ptr %gep194 %ld2 = load float, ptr %gep295 %ld3 = load float, ptr %gep396 97 %v2ld0 = load <2 x float>, ptr %gep098 %v2ld1 = load <2 x float>, ptr %gep199 %v2ld2 = load <2 x float>, ptr %gep2100 %v2ld3 = load <2 x float>, ptr %gep3101 102 %v3ld0 = load <3 x float>, ptr %gep0103 %v3ld1 = load <3 x float>, ptr %gep1104 %v3ld2 = load <3 x float>, ptr %gep2105 %v3ld3 = load <3 x float>, ptr %gep3106 ret void107}108)IR");109 Function &LLVMF = *M->getFunction("foo");110 const DataLayout &DL = M->getDataLayout();111 auto &SE = getSE(LLVMF);112 113 sandboxir::Context Ctx(C);114 auto &F = *Ctx.createFunction(&LLVMF);115 116 auto &BB = *F.begin();117 auto It = std::next(BB.begin(), 4);118 auto *L0 = cast<sandboxir::LoadInst>(&*It++);119 auto *L1 = cast<sandboxir::LoadInst>(&*It++);120 auto *L2 = cast<sandboxir::LoadInst>(&*It++);121 auto *L3 = cast<sandboxir::LoadInst>(&*It++);122 123 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);124 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);125 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);126 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);127 128 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);129 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);130 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);131 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);132 133 // Scalar134 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));135 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));136 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));137 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));138 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));139 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));140 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));141 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));142 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));143 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));144 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));145 146 // Check 2-wide loads147 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));148 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));149 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));150 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));151 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));152 153 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));154 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));155 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));156 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));157 158 // Check 3-wide loads159 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));160 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));161 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));162 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));163 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));164 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));165 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));166 167 // Check mixes of vectors and scalar168 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));169 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));170 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));171 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));172 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));173 174 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));175 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));176 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));177 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));178 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));179 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));180 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));181 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));182 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));183}184 185TEST_F(VecUtilsTest, AreConsecutive_gep_i8) {186 parseIR(R"IR(187define void @foo(ptr %ptr) {188 %gep0 = getelementptr inbounds i8, ptr %ptr, i64 0189 %gep1 = getelementptr inbounds i8, ptr %ptr, i64 4190 %gep2 = getelementptr inbounds i8, ptr %ptr, i64 8191 %gep3 = getelementptr inbounds i8, ptr %ptr, i64 12192 193 %ld0 = load float, ptr %gep0194 %ld1 = load float, ptr %gep1195 %ld2 = load float, ptr %gep2196 %ld3 = load float, ptr %gep3197 198 %v2ld0 = load <2 x float>, ptr %gep0199 %v2ld1 = load <2 x float>, ptr %gep1200 %v2ld2 = load <2 x float>, ptr %gep2201 %v2ld3 = load <2 x float>, ptr %gep3202 203 %v3ld0 = load <3 x float>, ptr %gep0204 %v3ld1 = load <3 x float>, ptr %gep1205 %v3ld2 = load <3 x float>, ptr %gep2206 %v3ld3 = load <3 x float>, ptr %gep3207 ret void208}209)IR");210 Function &LLVMF = *M->getFunction("foo");211 const DataLayout &DL = M->getDataLayout();212 auto &SE = getSE(LLVMF);213 214 sandboxir::Context Ctx(C);215 auto &F = *Ctx.createFunction(&LLVMF);216 auto &BB = *F.begin();217 auto It = std::next(BB.begin(), 4);218 auto *L0 = cast<sandboxir::LoadInst>(&*It++);219 auto *L1 = cast<sandboxir::LoadInst>(&*It++);220 auto *L2 = cast<sandboxir::LoadInst>(&*It++);221 auto *L3 = cast<sandboxir::LoadInst>(&*It++);222 223 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);224 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);225 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);226 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);227 228 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);229 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);230 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);231 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);232 233 // Scalar234 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));235 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));236 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));237 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));238 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));239 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));240 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));241 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));242 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));243 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));244 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));245 246 // Check 2-wide loads247 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));248 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));249 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));250 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));251 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));252 253 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));254 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));255 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));256 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));257 258 // Check 3-wide loads259 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));260 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));261 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));262 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));263 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));264 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));265 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));266 267 // Check mixes of vectors and scalar268 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));269 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));270 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));271 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));272 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));273 274 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));275 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));276 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));277 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));278 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));279 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));280 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));281 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));282 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));283}284 285TEST_F(VecUtilsTest, AreConsecutive_gep_i1) {286 parseIR(R"IR(287define void @foo(ptr %ptr) {288 %gep0 = getelementptr inbounds i1, ptr %ptr, i64 0289 %gep1 = getelementptr inbounds i2, ptr %ptr, i64 4290 %gep2 = getelementptr inbounds i3, ptr %ptr, i64 8291 %gep3 = getelementptr inbounds i7, ptr %ptr, i64 12292 293 %ld0 = load float, ptr %gep0294 %ld1 = load float, ptr %gep1295 %ld2 = load float, ptr %gep2296 %ld3 = load float, ptr %gep3297 298 %v2ld0 = load <2 x float>, ptr %gep0299 %v2ld1 = load <2 x float>, ptr %gep1300 %v2ld2 = load <2 x float>, ptr %gep2301 %v2ld3 = load <2 x float>, ptr %gep3302 303 %v3ld0 = load <3 x float>, ptr %gep0304 %v3ld1 = load <3 x float>, ptr %gep1305 %v3ld2 = load <3 x float>, ptr %gep2306 %v3ld3 = load <3 x float>, ptr %gep3307 ret void308}309)IR");310 Function &LLVMF = *M->getFunction("foo");311 const DataLayout &DL = M->getDataLayout();312 auto &SE = getSE(LLVMF);313 314 sandboxir::Context Ctx(C);315 auto &F = *Ctx.createFunction(&LLVMF);316 auto &BB = *F.begin();317 auto It = std::next(BB.begin(), 4);318 auto *L0 = cast<sandboxir::LoadInst>(&*It++);319 auto *L1 = cast<sandboxir::LoadInst>(&*It++);320 auto *L2 = cast<sandboxir::LoadInst>(&*It++);321 auto *L3 = cast<sandboxir::LoadInst>(&*It++);322 323 auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);324 auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);325 auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);326 auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);327 328 auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);329 auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);330 auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);331 auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);332 333 // Scalar334 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));335 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));336 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));337 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));338 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));339 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));340 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));341 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));342 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));343 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));344 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));345 346 // Check 2-wide loads347 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));348 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));349 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));350 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));351 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));352 353 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));354 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));355 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));356 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));357 358 // Check 3-wide loads359 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));360 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));361 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));362 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));363 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));364 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));365 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));366 367 // Check mixes of vectors and scalar368 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));369 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));370 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));371 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));372 EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));373 374 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));375 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));376 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));377 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));378 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));379 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));380 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));381 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));382 EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));383}384 385TEST_F(VecUtilsTest, GetNumLanes) {386 parseIR(R"IR(387define <4 x float> @foo(float %v, <2 x float> %v2, <4 x float> %ret, ptr %ptr) {388 store float %v, ptr %ptr389 store <2 x float> %v2, ptr %ptr390 ret <4 x float> %ret391}392)IR");393 Function &LLVMF = *M->getFunction("foo");394 395 sandboxir::Context Ctx(C);396 auto &F = *Ctx.createFunction(&LLVMF);397 auto &BB = *F.begin();398 399 auto It = BB.begin();400 auto *S0 = cast<sandboxir::StoreInst>(&*It++);401 auto *S1 = cast<sandboxir::StoreInst>(&*It++);402 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);403 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0->getValueOperand()->getType()),404 1u);405 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0), 1u);406 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1->getValueOperand()->getType()),407 2u);408 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1), 2u);409 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret->getReturnValue()->getType()),410 4u);411 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret), 4u);412 413 SmallVector<sandboxir::Value *> Bndl({S0, S1, Ret});414 EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Bndl), 7u);415}416 417TEST_F(VecUtilsTest, GetWideType) {418 sandboxir::Context Ctx(C);419 420 auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);421 auto *Int32X4Ty = sandboxir::FixedVectorType::get(Int32Ty, 4);422 EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32Ty, 4), Int32X4Ty);423 auto *Int32X8Ty = sandboxir::FixedVectorType::get(Int32Ty, 8);424 EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32X4Ty, 2), Int32X8Ty);425}426 427TEST_F(VecUtilsTest, GetLowest) {428 parseIR(R"IR(429define void @foo(i8 %v) {430bb0:431 br label %bb1432bb1:433 %A = add i8 %v, 1434 %B = add i8 %v, 2435 %C = add i8 %v, 3436 ret void437}438)IR");439 Function &LLVMF = *M->getFunction("foo");440 441 sandboxir::Context Ctx(C);442 auto &F = *Ctx.createFunction(&LLVMF);443 auto &BB0 = getBasicBlockByName(F, "bb0");444 auto It = BB0.begin();445 auto *BB0I = cast<sandboxir::BranchInst>(&*It++);446 447 auto &BB = getBasicBlockByName(F, "bb1");448 It = BB.begin();449 auto *IA = cast<sandboxir::Instruction>(&*It++);450 auto *C1 = cast<sandboxir::Constant>(IA->getOperand(1));451 auto *IB = cast<sandboxir::Instruction>(&*It++);452 auto *C2 = cast<sandboxir::Constant>(IB->getOperand(1));453 auto *IC = cast<sandboxir::Instruction>(&*It++);454 auto *C3 = cast<sandboxir::Constant>(IC->getOperand(1));455 // Check getLowest(ArrayRef<Instruction *>)456 SmallVector<sandboxir::Instruction *> A({IA});457 EXPECT_EQ(sandboxir::VecUtils::getLowest(A), IA);458 SmallVector<sandboxir::Instruction *> ABC({IA, IB, IC});459 EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC), IC);460 SmallVector<sandboxir::Instruction *> ACB({IA, IC, IB});461 EXPECT_EQ(sandboxir::VecUtils::getLowest(ACB), IC);462 SmallVector<sandboxir::Instruction *> CAB({IC, IA, IB});463 EXPECT_EQ(sandboxir::VecUtils::getLowest(CAB), IC);464 SmallVector<sandboxir::Instruction *> CBA({IC, IB, IA});465 EXPECT_EQ(sandboxir::VecUtils::getLowest(CBA), IC);466 467 // Check getLowest(ArrayRef<Value *>)468 SmallVector<sandboxir::Value *> C1Only({C1});469 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1Only, &BB), nullptr);470 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1Only, &BB0), nullptr);471 SmallVector<sandboxir::Value *> AOnly({IA});472 EXPECT_EQ(sandboxir::VecUtils::getLowest(AOnly, &BB), IA);473 EXPECT_EQ(sandboxir::VecUtils::getLowest(AOnly, &BB0), nullptr);474 SmallVector<sandboxir::Value *> AC1({IA, C1});475 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1, &BB), IA);476 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1, &BB0), nullptr);477 SmallVector<sandboxir::Value *> C1A({C1, IA});478 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1A, &BB), IA);479 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1A, &BB0), nullptr);480 SmallVector<sandboxir::Value *> AC1B({IA, C1, IB});481 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1B, &BB), IB);482 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1B, &BB0), nullptr);483 SmallVector<sandboxir::Value *> ABC1({IA, IB, C1});484 EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC1, &BB), IB);485 EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC1, &BB0), nullptr);486 SmallVector<sandboxir::Value *> AC1C2({IA, C1, C2});487 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1C2, &BB), IA);488 EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1C2, &BB0), nullptr);489 SmallVector<sandboxir::Value *> C1C2C3({C1, C2, C3});490 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1C2C3, &BB), nullptr);491 EXPECT_EQ(sandboxir::VecUtils::getLowest(C1C2C3, &BB0), nullptr);492 493 SmallVector<sandboxir::Value *> DiffBBs({BB0I, IA});494 EXPECT_EQ(sandboxir::VecUtils::getLowest(DiffBBs, &BB0), BB0I);495 EXPECT_EQ(sandboxir::VecUtils::getLowest(DiffBBs, &BB), IA);496}497 498TEST_F(VecUtilsTest, GetLastPHIOrSelf) {499 parseIR(R"IR(500define void @foo(i8 %v) {501entry:502 br label %bb1503 504bb1:505 %phi1 = phi i8 [0, %entry], [1, %bb1]506 %phi2 = phi i8 [0, %entry], [1, %bb1]507 br label %bb1508 509bb2:510 ret void511}512)IR");513 Function &LLVMF = *M->getFunction("foo");514 515 sandboxir::Context Ctx(C);516 auto &F = *Ctx.createFunction(&LLVMF);517 auto &BB = getBasicBlockByName(F, "bb1");518 auto It = BB.begin();519 auto *PHI1 = cast<sandboxir::PHINode>(&*It++);520 auto *PHI2 = cast<sandboxir::PHINode>(&*It++);521 auto *Br = cast<sandboxir::BranchInst>(&*It++);522 EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI1), PHI2);523 EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI2), PHI2);524 EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(Br), Br);525 EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(nullptr), nullptr);526}527 528TEST_F(VecUtilsTest, GetCommonScalarType) {529 parseIR(R"IR(530define void @foo(i8 %v, ptr %ptr) {531bb0:532 %add0 = add i8 %v, %v533 store i8 %v, ptr %ptr534 ret void535}536)IR");537 Function &LLVMF = *M->getFunction("foo");538 539 sandboxir::Context Ctx(C);540 auto &F = *Ctx.createFunction(&LLVMF);541 auto &BB = *F.begin();542 auto It = BB.begin();543 auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);544 auto *Store = cast<sandboxir::StoreInst>(&*It++);545 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);546 {547 SmallVector<sandboxir::Value *> Vec = {Add0, Store};548 EXPECT_EQ(sandboxir::VecUtils::tryGetCommonScalarType(Vec),549 Add0->getType());550 EXPECT_EQ(sandboxir::VecUtils::getCommonScalarType(Vec), Add0->getType());551 }552 {553 SmallVector<sandboxir::Value *> Vec = {Add0, Ret};554 EXPECT_EQ(sandboxir::VecUtils::tryGetCommonScalarType(Vec), nullptr);555#ifndef NDEBUG556 EXPECT_DEATH(sandboxir::VecUtils::getCommonScalarType(Vec), ".*common.*");557#endif // NDEBUG558 }559}560 561TEST_F(VecUtilsTest, FloorPowerOf2) {562 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(0), 0u);563 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(1 << 0), 1u << 0);564 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(3), 2u);565 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(4), 4u);566 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(5), 4u);567 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(7), 4u);568 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(8), 8u);569 EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(9), 8u);570}571 572TEST_F(VecUtilsTest, MatchPackScalar) {573 parseIR(R"IR(574define void @foo(i8 %v0, i8 %v1) {575bb0:576 %NotPack = insertelement <2 x i8> poison, i8 %v0, i64 0577 br label %bb1578 579bb1:580 %Pack0 = insertelement <2 x i8> poison, i8 %v0, i64 0581 %Pack1 = insertelement <2 x i8> %Pack0, i8 %v1, i64 1582 583 %NotPack0 = insertelement <2 x i8> poison, i8 %v0, i64 0584 %NotPack1 = insertelement <2 x i8> %NotPack0, i8 %v1, i64 0585 %NotPack2 = insertelement <2 x i8> %NotPack1, i8 %v1, i64 1586 587 %NotPackBB = insertelement <2 x i8> %NotPack, i8 %v1, i64 1588 589 ret void590}591)IR");592 Function &LLVMF = *M->getFunction("foo");593 594 sandboxir::Context Ctx(C);595 auto &F = *Ctx.createFunction(&LLVMF);596 auto &BB = getBasicBlockByName(F, "bb1");597 auto It = BB.begin();598 auto *Pack0 = cast<sandboxir::InsertElementInst>(&*It++);599 auto *Pack1 = cast<sandboxir::InsertElementInst>(&*It++);600 auto *NotPack0 = cast<sandboxir::InsertElementInst>(&*It++);601 auto *NotPack1 = cast<sandboxir::InsertElementInst>(&*It++);602 auto *NotPack2 = cast<sandboxir::InsertElementInst>(&*It++);603 auto *NotPackBB = cast<sandboxir::InsertElementInst>(&*It++);604 auto *Ret = cast<sandboxir::ReturnInst>(&*It++);605 auto *Arg0 = F.getArg(0);606 auto *Arg1 = F.getArg(1);607 EXPECT_FALSE(sandboxir::VecUtils::matchPack(Pack0));608 EXPECT_FALSE(sandboxir::VecUtils::matchPack(Ret));609 {610 auto PackOpt = sandboxir::VecUtils::matchPack(Pack1);611 EXPECT_TRUE(PackOpt);612 EXPECT_THAT(PackOpt->Instrs, testing::ElementsAre(Pack1, Pack0));613 EXPECT_THAT(PackOpt->Operands, testing::ElementsAre(Arg0, Arg1));614 }615 {616 for (auto *NotPack : {NotPack0, NotPack1, NotPack2, NotPackBB})617 EXPECT_FALSE(sandboxir::VecUtils::matchPack(NotPack));618 }619}620