brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.9 KiB · 2bfea69 Raw
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