brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · 2bef486 Raw
250 lines · cpp
1//===- UtilsTest.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/SandboxIR/Utils.h"10#include "llvm/Analysis/AssumptionCache.h"11#include "llvm/Analysis/BasicAliasAnalysis.h"12#include "llvm/Analysis/LoopInfo.h"13#include "llvm/Analysis/TargetLibraryInfo.h"14#include "llvm/AsmParser/Parser.h"15#include "llvm/IR/BasicBlock.h"16#include "llvm/IR/DataLayout.h"17#include "llvm/IR/Dominators.h"18#include "llvm/IR/Function.h"19#include "llvm/IR/Instruction.h"20#include "llvm/IR/Module.h"21#include "llvm/SandboxIR/Constant.h"22#include "llvm/SandboxIR/Context.h"23#include "llvm/SandboxIR/Function.h"24#include "llvm/Support/SourceMgr.h"25#include "gtest/gtest.h"26 27using namespace llvm;28 29struct UtilsTest : public testing::Test {30  LLVMContext C;31  std::unique_ptr<Module> M;32 33  void parseIR(LLVMContext &C, const char *IR) {34    SMDiagnostic Err;35    M = parseAssemblyString(IR, Err, C);36    if (!M)37      Err.print("UtilsTest", errs());38  }39  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {40    for (BasicBlock &BB : F)41      if (BB.getName() == Name)42        return &BB;43    llvm_unreachable("Expected to find basic block!");44  }45};46 47TEST_F(UtilsTest, getMemoryLocation) {48  parseIR(C, R"IR(49define void @foo(ptr %arg0) {50  %ld = load i8, ptr %arg051  ret void52}53)IR");54  llvm::Function *LLVMF = &*M->getFunction("foo");55  auto *LLVMBB = &*LLVMF->begin();56  auto *LLVMLd = cast<llvm::LoadInst>(&*LLVMBB->begin());57  sandboxir::Context Ctx(C);58  sandboxir::Function *F = Ctx.createFunction(LLVMF);59  auto *BB = &*F->begin();60  auto *Ld = cast<sandboxir::LoadInst>(&*BB->begin());61  EXPECT_EQ(sandboxir::Utils::memoryLocationGetOrNone(Ld),62            MemoryLocation::getOrNone(LLVMLd));63}64 65TEST_F(UtilsTest, GetPointerDiffInBytes) {66  parseIR(C, R"IR(67define void @foo(ptr %ptr) {68  %gep0 = getelementptr inbounds float, ptr %ptr, i64 069  %gep1 = getelementptr inbounds float, ptr %ptr, i64 170  %gep2 = getelementptr inbounds float, ptr %ptr, i64 271  %gep3 = getelementptr inbounds float, ptr %ptr, i64 372 73  %ld0 = load float, ptr %gep074  %ld1 = load float, ptr %gep175  %ld2 = load float, ptr %gep276  %ld3 = load float, ptr %gep377 78  %v2ld0 = load <2 x float>, ptr %gep079  %v2ld1 = load <2 x float>, ptr %gep180  %v2ld2 = load <2 x float>, ptr %gep281  %v2ld3 = load <2 x float>, ptr %gep382 83  %v3ld0 = load <3 x float>, ptr %gep084  %v3ld1 = load <3 x float>, ptr %gep185  %v3ld2 = load <3 x float>, ptr %gep286  %v3ld3 = load <3 x float>, ptr %gep387  ret void88}89)IR");90  llvm::Function &LLVMF = *M->getFunction("foo");91  DominatorTree DT(LLVMF);92  TargetLibraryInfoImpl TLII(M->getTargetTriple());93  TargetLibraryInfo TLI(TLII);94  DataLayout DL(M->getDataLayout());95  AssumptionCache AC(LLVMF);96  BasicAAResult BAA(DL, LLVMF, TLI, AC, &DT);97  AAResults AA(TLI);98  AA.addAAResult(BAA);99  LoopInfo LI(DT);100  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);101  sandboxir::Context Ctx(C);102 103  auto &F = *Ctx.createFunction(&LLVMF);104  auto &BB = *F.begin();105  auto It = std::next(BB.begin(), 4);106  auto *L0 = cast<sandboxir::LoadInst>(&*It++);107  auto *L1 = cast<sandboxir::LoadInst>(&*It++);108  auto *L2 = cast<sandboxir::LoadInst>(&*It++);109  [[maybe_unused]] auto *L3 = cast<sandboxir::LoadInst>(&*It++);110 111  auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);112  auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);113  auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);114  auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);115 116  [[maybe_unused]] auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);117  auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);118  [[maybe_unused]] auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);119  [[maybe_unused]] auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);120 121  // getPointerDiffInBytes122  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L1, SE), 4);123  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L2, SE), 8);124  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L1, L0, SE), -4);125  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L0, SE), 0);126 127  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L1, SE), 4);128  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V3L1, SE), 4);129  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L2, SE), 8);130  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L3, SE), 12);131  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L3, V2L0, SE), -12);132 133  // atLowerAddress134  EXPECT_TRUE(sandboxir::Utils::atLowerAddress(L0, L1, SE));135  EXPECT_FALSE(sandboxir::Utils::atLowerAddress(L1, L0, SE));136  EXPECT_FALSE(sandboxir::Utils::atLowerAddress(L3, V3L3, SE));137}138 139TEST_F(UtilsTest, GetExpected) {140  parseIR(C, R"IR(141define float @foo(float %v, ptr %ptr) {142  %add = fadd float %v, %v143  store float %v, ptr %ptr144  ret float %v145}146define void @bar(float %v, ptr %ptr) {147  ret void148}149)IR");150  llvm::Function &Foo = *M->getFunction("foo");151  sandboxir::Context Ctx(C);152 153  Ctx.createFunction(&Foo);154  auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin()));155  auto FooIt = FooBB->begin();156  auto Add = cast<sandboxir::Instruction>(&*FooIt++);157  auto *S0 = cast<sandboxir::Instruction>(&*FooIt++);158  auto *RetF = cast<sandboxir::Instruction>(&*FooIt++);159  // getExpectedValue160  EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add);161  EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0),162            cast<sandboxir::StoreInst>(S0)->getValueOperand());163  EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF),164            cast<sandboxir::ReturnInst>(RetF)->getReturnValue());165  // getExpectedType166  EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType());167  EXPECT_EQ(sandboxir::Utils::getExpectedType(S0),168            cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType());169  EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF),170            cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType());171 172  // getExpectedValue for void returns173  llvm::Function &Bar = *M->getFunction("bar");174  Ctx.createFunction(&Bar);175  auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin()));176  auto BarIt = BarBB->begin();177  auto *RetV = cast<sandboxir::Instruction>(&*BarIt++);178  EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr);179}180 181TEST_F(UtilsTest, GetNumBits) {182  parseIR(C, R"IR(183define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3, ptr %arg4) {184bb0:185  %ld0 = load float, ptr %arg4186  %ld1 = load double, ptr %arg4187  %ld2 = load i8, ptr %arg4188  %ld3 = load i64, ptr %arg4189  ret void190}191)IR");192  llvm::Function &Foo = *M->getFunction("foo");193  sandboxir::Context Ctx(C);194  sandboxir::Function *F = Ctx.createFunction(&Foo);195  const DataLayout &DL = M->getDataLayout();196  // getNumBits for scalars via the Value overload197  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL),198            DL.getTypeSizeInBits(Type::getFloatTy(C)));199  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL),200            DL.getTypeSizeInBits(Type::getDoubleTy(C)));201  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u);202  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u);203 204  auto &BB = *F->begin();205  auto It = BB.begin();206  auto *L0 = cast<sandboxir::LoadInst>(&*It++);207  auto *L1 = cast<sandboxir::LoadInst>(&*It++);208  auto *L2 = cast<sandboxir::LoadInst>(&*It++);209  auto *L3 = cast<sandboxir::LoadInst>(&*It++);210  // getNumBits for scalars via the Instruction overload211  EXPECT_EQ(sandboxir::Utils::getNumBits(L0),212            DL.getTypeSizeInBits(Type::getFloatTy(C)));213  EXPECT_EQ(sandboxir::Utils::getNumBits(L1),214            DL.getTypeSizeInBits(Type::getDoubleTy(C)));215  EXPECT_EQ(sandboxir::Utils::getNumBits(L2), 8u);216  EXPECT_EQ(sandboxir::Utils::getNumBits(L3), 64u);217}218 219TEST_F(UtilsTest, GetMemBase) {220  parseIR(C, R"IR(221define void @foo(ptr %ptrA, float %val, ptr %ptrB) {222bb:223  %gepA0 = getelementptr float, ptr %ptrA, i32 0224  %gepA1 = getelementptr float, ptr %ptrA, i32 1225  %gepB0 = getelementptr float, ptr %ptrB, i32 0226  %gepB1 = getelementptr float, ptr %ptrB, i32 1227  store float %val, ptr %gepA0228  store float %val, ptr %gepA1229  store float %val, ptr %gepB0230  store float %val, ptr %gepB1231  ret void232}233)IR");234  llvm::Function &Foo = *M->getFunction("foo");235  sandboxir::Context Ctx(C);236  sandboxir::Function *F = Ctx.createFunction(&Foo);237 238  auto It = std::next(F->begin()->begin(), 4);239  auto *St0 = cast<sandboxir::StoreInst>(&*It++);240  auto *St1 = cast<sandboxir::StoreInst>(&*It++);241  auto *St2 = cast<sandboxir::StoreInst>(&*It++);242  auto *St3 = cast<sandboxir::StoreInst>(&*It++);243  EXPECT_EQ(sandboxir::Utils::getMemInstructionBase(St0),244            sandboxir::Utils::getMemInstructionBase(St1));245  EXPECT_EQ(sandboxir::Utils::getMemInstructionBase(St2),246            sandboxir::Utils::getMemInstructionBase(St3));247  EXPECT_NE(sandboxir::Utils::getMemInstructionBase(St0),248            sandboxir::Utils::getMemInstructionBase(St3));249}250