mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-05-15 03:25:58 +00:00

to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
124 lines
4.2 KiB
C++
124 lines
4.2 KiB
C++
//===- BasicAliasAnalysisTest.cpp - Unit tests for BasicAA ----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Targeted tests that are hard/convoluted to make happen with just `opt`.
|
|
//
|
|
|
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
|
#include "llvm/AsmParser/Parser.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
|
|
// FIXME: This is duplicated between this file and MemorySSATest. Refactor.
|
|
const static char DLString[] = "e-i64:64-f80:128-n8:16:32:64-S128";
|
|
|
|
/// There's a lot of common setup between these tests. This fixture helps reduce
|
|
/// that. Tests should mock up a function, store it in F, and then call
|
|
/// setupAnalyses().
|
|
class BasicAATest : public testing::Test {
|
|
protected:
|
|
// N.B. Many of these members depend on each other (e.g. the Module depends on
|
|
// the Context, etc.). So, order matters here (and in TestAnalyses).
|
|
LLVMContext C;
|
|
Module M;
|
|
IRBuilder<> B;
|
|
DataLayout DL;
|
|
TargetLibraryInfoImpl TLII;
|
|
TargetLibraryInfo TLI;
|
|
Function *F;
|
|
|
|
// Things that we need to build after the function is created.
|
|
struct TestAnalyses {
|
|
DominatorTree DT;
|
|
AssumptionCache AC;
|
|
BasicAAResult BAA;
|
|
|
|
TestAnalyses(BasicAATest &Test)
|
|
: DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {}
|
|
};
|
|
|
|
llvm::Optional<TestAnalyses> Analyses;
|
|
|
|
BasicAAResult &setupAnalyses() {
|
|
assert(F);
|
|
Analyses.emplace(*this);
|
|
return Analyses->BAA;
|
|
}
|
|
|
|
public:
|
|
BasicAATest()
|
|
: M("BasicAATest", C), B(C), DL(DLString), TLI(TLII), F(nullptr) {}
|
|
};
|
|
|
|
// Check that a function arg can't trivially alias a global when we're accessing
|
|
// >sizeof(global) bytes through that arg, unless the access size is just an
|
|
// upper-bound.
|
|
TEST_F(BasicAATest, AliasInstWithObjectOfImpreciseSize) {
|
|
F = Function::Create(
|
|
FunctionType::get(B.getVoidTy(), {B.getInt32Ty()->getPointerTo()}, false),
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
|
|
|
BasicBlock *Entry(BasicBlock::Create(C, "", F));
|
|
B.SetInsertPoint(Entry);
|
|
|
|
Value *IncomingI32Ptr = F->arg_begin();
|
|
|
|
auto *GlobalPtr =
|
|
cast<GlobalVariable>(M.getOrInsertGlobal("some_global", B.getInt8Ty()));
|
|
|
|
// Without sufficiently restricted linkage/an init, some of the object size
|
|
// checking bits get more conservative.
|
|
GlobalPtr->setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
|
|
GlobalPtr->setInitializer(B.getInt8(0));
|
|
|
|
BasicAAResult &BasicAA = setupAnalyses();
|
|
ASSERT_EQ(
|
|
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
|
|
MemoryLocation(GlobalPtr, LocationSize::precise(1))),
|
|
AliasResult::NoAlias);
|
|
|
|
ASSERT_EQ(
|
|
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
|
|
MemoryLocation(GlobalPtr, LocationSize::precise(1))),
|
|
AliasResult::MayAlias);
|
|
}
|
|
|
|
// Check that we fall back to MayAlias if we see an access of an entire object
|
|
// that's just an upper-bound.
|
|
TEST_F(BasicAATest, AliasInstWithFullObjectOfImpreciseSize) {
|
|
F = Function::Create(
|
|
FunctionType::get(B.getVoidTy(), {B.getInt64Ty()}, false),
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
|
|
|
BasicBlock *Entry(BasicBlock::Create(C, "", F));
|
|
B.SetInsertPoint(Entry);
|
|
|
|
Value *ArbitraryI32 = F->arg_begin();
|
|
AllocaInst *I8 = B.CreateAlloca(B.getInt8Ty(), B.getInt32(2));
|
|
auto *I8AtUncertainOffset =
|
|
cast<GetElementPtrInst>(B.CreateGEP(I8, ArbitraryI32));
|
|
|
|
BasicAAResult &BasicAA = setupAnalyses();
|
|
ASSERT_EQ(BasicAA.alias(
|
|
MemoryLocation(I8, LocationSize::precise(2)),
|
|
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
|
|
AliasResult::PartialAlias);
|
|
|
|
ASSERT_EQ(BasicAA.alias(
|
|
MemoryLocation(I8, LocationSize::upperBound(2)),
|
|
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
|
|
AliasResult::MayAlias);
|
|
}
|