diff options
author | Arthur Eubanks <aeubanks@google.com> | 2024-07-10 09:54:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-10 09:54:56 -0700 |
commit | 8d800e6c9014e55ff729f0237efeba246750b12c (patch) | |
tree | 1a02cb4adf809aa233a6d02f37421e162aedb077 /llvm/unittests/Analysis/CGSCCPassManagerTest.cpp | |
parent | 953c669b6e0948292455cd65c7e2d6748255039f (diff) | |
download | llvm-8d800e6c9014e55ff729f0237efeba246750b12c.zip llvm-8d800e6c9014e55ff729f0237efeba246750b12c.tar.gz llvm-8d800e6c9014e55ff729f0237efeba246750b12c.tar.bz2 |
[CGSCC] Remove CGSCCUpdateResult::InvalidatedRefSCCs (#98213)
The RefSCC that a function marked dead is in may still contain valid
SCCs that we want to visit. We rely on InvalidatedSCCs to skip SCCs
containing dead functions.
The addition of RefSCCs in CallGraphUpdater to InvalidatedRefSCCs was
causing asserts as reported in #94815. Fix some more CallGraphUpdater
function deletion methods as well.
Diffstat (limited to 'llvm/unittests/Analysis/CGSCCPassManagerTest.cpp')
-rw-r--r-- | llvm/unittests/Analysis/CGSCCPassManagerTest.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp index 1532379..9fd782d 100644 --- a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp +++ b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp @@ -1878,6 +1878,61 @@ TEST_F(CGSCCPassManagerTest, TestInsertionOfNewFunctions2) { ASSERT_TRUE(Ran); } +TEST_F(CGSCCPassManagerTest, TestDeletionOfFunctionInNonTrivialRefSCC) { + std::unique_ptr<Module> M = parseIR("define void @f1() {\n" + "entry:\n" + " call void @f2()\n" + " ret void\n" + "}\n" + "define void @f2() {\n" + "entry:\n" + " call void @f1()\n" + " ret void\n" + "}\n"); + + bool Ran = false; + CGSCCPassManager CGPM; + CGPM.addPass(LambdaSCCPassNoPreserve( + [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, + CGSCCUpdateResult &UR) { + if (Ran) + return; + + LazyCallGraph::Node *N1 = nullptr; + + for (LazyCallGraph::Node *N : SCCNodes(C)) { + Function &F = N->getFunction(); + if (F.getName() != "f1") + continue; + N1 = N; + + Function &F2 = *F.getParent()->getFunction("f2"); + + // Remove f1 <-> f2 references + F.getEntryBlock().front().eraseFromParent(); + F2.getEntryBlock().front().eraseFromParent(); + + CallGraphUpdater CGU; + CGU.initialize(CG, C, AM, UR); + CGU.removeFunction(F2); + CGU.reanalyzeFunction(F); + + Ran = true; + } + + // Check that updateCGAndAnalysisManagerForCGSCCPass() after + // CallGraphUpdater::removeFunction() succeeds. + updateCGAndAnalysisManagerForCGSCCPass(CG, *CG.lookupSCC(*N1), *N1, AM, + UR, FAM); + })); + + ModulePassManager MPM; + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + MPM.run(*M, MAM); + + ASSERT_TRUE(Ran); +} + TEST_F(CGSCCPassManagerTest, TestInsertionOfNewNonTrivialCallEdge) { std::unique_ptr<Module> M = parseIR("define void @f1() {\n" "entry:\n" |