mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
fbe4879842
Since SCEV can cache information about location of an instruction, it should be invalidated when the instruction is moved. There should be similar bug in code sinking part of LICM, it will be fixed in a follow-up change. Patch Author: Daniil Suchkov Reviewers: asbirlea, mkazantsev, reames Reviewed By: asbirlea Subscribers: hiraditya, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D69370
94 lines
3.1 KiB
C++
94 lines
3.1 KiB
C++
//===- LICMTest.cpp - LICM unit tests -------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/ScalarEvolution.h"
|
|
#include "llvm/AsmParser/Parser.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Passes/PassBuilder.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "llvm/Testing/Support/Error.h"
|
|
#include "llvm/Transforms/Scalar/LICM.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace llvm {
|
|
|
|
TEST(LICMTest, TestSCEVInvalidationOnHoisting) {
|
|
LLVMContext Ctx;
|
|
ModulePassManager MPM;
|
|
PassBuilder PB;
|
|
LoopAnalysisManager LAM;
|
|
FunctionAnalysisManager FAM;
|
|
CGSCCAnalysisManager CGAM;
|
|
ModuleAnalysisManager MAM;
|
|
|
|
PB.registerModuleAnalyses(MAM);
|
|
PB.registerCGSCCAnalyses(CGAM);
|
|
PB.registerFunctionAnalyses(FAM);
|
|
PB.registerLoopAnalyses(LAM);
|
|
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
|
|
|
StringRef PipelineStr = "require<opt-remark-emit>,loop(licm)";
|
|
ASSERT_THAT_ERROR(PB.parsePassPipeline(MPM, PipelineStr), Succeeded());
|
|
|
|
SMDiagnostic Error;
|
|
StringRef Text = R"(
|
|
define void @foo(i64* %ptr) {
|
|
entry:
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ 0, %entry ], [ %iv.inc, %loop ]
|
|
%n = load i64, i64* %ptr, !invariant.load !0
|
|
%iv.inc = add i64 %iv, 1
|
|
%cmp = icmp ult i64 %iv.inc, %n
|
|
br i1 %cmp, label %loop, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
!0 = !{}
|
|
)";
|
|
|
|
std::unique_ptr<Module> M = parseAssemblyString(Text, Error, Ctx);
|
|
ASSERT_TRUE(M);
|
|
Function *F = M->getFunction("foo");
|
|
ScalarEvolution &SE = FAM.getResult<ScalarEvolutionAnalysis>(*F);
|
|
BasicBlock &EntryBB = F->getEntryBlock();
|
|
BasicBlock *LoopBB = EntryBB.getUniqueSuccessor();
|
|
|
|
// Select `load i64, i64* %ptr`.
|
|
Instruction *IBefore = LoopBB->getFirstNonPHI();
|
|
// Make sure the right instruction was selected.
|
|
ASSERT_TRUE(isa<LoadInst>(IBefore));
|
|
// Upon this query SCEV caches disposition of <load i64, i64* %ptr> SCEV.
|
|
ASSERT_EQ(SE.getBlockDisposition(SE.getSCEV(IBefore), LoopBB),
|
|
ScalarEvolution::BlockDisposition::DominatesBlock);
|
|
|
|
MPM.run(*M, MAM);
|
|
|
|
// Select `load i64, i64* %ptr` after it was hoisted.
|
|
Instruction *IAfter = EntryBB.getFirstNonPHI();
|
|
// Make sure the right instruction was selected.
|
|
ASSERT_TRUE(isa<LoadInst>(IAfter));
|
|
|
|
ScalarEvolution::BlockDisposition DispositionBeforeInvalidation =
|
|
SE.getBlockDisposition(SE.getSCEV(IAfter), LoopBB);
|
|
SE.forgetValue(IAfter);
|
|
ScalarEvolution::BlockDisposition DispositionAfterInvalidation =
|
|
SE.getBlockDisposition(SE.getSCEV(IAfter), LoopBB);
|
|
|
|
// If LICM have properly invalidated SCEV,
|
|
// 1. SCEV of <load i64, i64* %ptr> should properly dominate the "loop" BB,
|
|
// 2. extra invalidation shouldn't change result of the query.
|
|
EXPECT_EQ(DispositionBeforeInvalidation,
|
|
ScalarEvolution::BlockDisposition::ProperlyDominatesBlock);
|
|
EXPECT_EQ(DispositionBeforeInvalidation, DispositionAfterInvalidation);
|
|
}
|
|
}
|