diff options
author | Tyler Nowicki <tyler.nowicki@amd.com> | 2025-02-14 16:55:06 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-14 16:55:06 -0500 |
commit | c662103c6ead3bbfad9bc24d7770552163dbb92b (patch) | |
tree | 9935189d5962f1023c9c64872ccc9ce9ac0b5b62 /llvm/unittests/Analysis/LazyCallGraphTest.cpp | |
parent | dcfc30ca6b19bd8ee9ab9788cb4923a848af3f20 (diff) | |
download | llvm-c662103c6ead3bbfad9bc24d7770552163dbb92b.zip llvm-c662103c6ead3bbfad9bc24d7770552163dbb92b.tar.gz llvm-c662103c6ead3bbfad9bc24d7770552163dbb92b.tar.bz2 |
[Coroutines][LazyCallGraph] addSplitRefRecursiveFunctions allows spurious ref edges between new functions. (#116285)
The addSplitRefRecursiveFunctions LazyCallGraph helper should not
require a reference between every new function. Spurious ref edges
between the new functions are allowed and the new function are
considered to be a RefSCC. This change clarifies that this is the case
in the method's description and its DEBUG mode verifier.
Diffstat (limited to 'llvm/unittests/Analysis/LazyCallGraphTest.cpp')
-rw-r--r-- | llvm/unittests/Analysis/LazyCallGraphTest.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/llvm/unittests/Analysis/LazyCallGraphTest.cpp index 6ca233a..311c5d4 100644 --- a/llvm/unittests/Analysis/LazyCallGraphTest.cpp +++ b/llvm/unittests/Analysis/LazyCallGraphTest.cpp @@ -3027,4 +3027,58 @@ TEST(LazyCallGraphTest, AddSplitFunctions5) { EXPECT_EQ(RC, CG.lookupRefSCC(F2N)); EXPECT_EQ(CG.postorder_ref_scc_end(), I); } + +TEST(LazyCallGraphTest, AddSplitFunctions6) { + LLVMContext Context; + std::unique_ptr<Module> M = parseAssembly(Context, "define void @f() {\n" + " ret void\n" + "}\n"); + LazyCallGraph CG = buildCG(*M); + + Function &F = lookupFunction(*M, "f"); + LazyCallGraph::Node &FN = CG.get(F); + + // Force the graph to be fully expanded. + CG.buildRefSCCs(); + auto I = CG.postorder_ref_scc_begin(); + LazyCallGraph::RefSCC *ORC = &*I++; + EXPECT_EQ(CG.postorder_ref_scc_end(), I); + + auto *G1 = Function::Create(F.getFunctionType(), F.getLinkage(), + F.getAddressSpace(), "g1", F.getParent()); + auto *G2 = Function::Create(F.getFunctionType(), F.getLinkage(), + F.getAddressSpace(), "g2", F.getParent()); + BasicBlock *G1BB = BasicBlock::Create(Context, "", G1); + BasicBlock *G2BB = BasicBlock::Create(Context, "", G2); + // Create g1 -ref-> g2 and g2 has no references. + (void)CastInst::CreatePointerCast(G2, PointerType::getUnqual(Context), "", + G1BB); + (void)ReturnInst::Create(Context, G1BB); + (void)ReturnInst::Create(Context, G2BB); + + // Create f -ref-> g1 and f -ref-> g2. + (void)CastInst::CreatePointerCast(G1, PointerType::getUnqual(Context), "", + F.getEntryBlock().begin()); + (void)CastInst::CreatePointerCast(G2, PointerType::getUnqual(Context), "", + F.getEntryBlock().begin()); + + EXPECT_FALSE(verifyModule(*M, &errs())); + + CG.addSplitRefRecursiveFunctions(F, SmallVector<Function *, 1>({G1, G2})); + + LazyCallGraph::Node *G1N = CG.lookup(*G1); + EXPECT_TRUE(G1N); + LazyCallGraph::Node *G2N = CG.lookup(*G2); + EXPECT_TRUE(G2N); + + I = CG.postorder_ref_scc_begin(); + LazyCallGraph::RefSCC *RC1 = &*I++; + EXPECT_EQ(2, RC1->size()); + EXPECT_EQ(RC1, CG.lookupRefSCC(*G1N)); + EXPECT_EQ(RC1, CG.lookupRefSCC(*G2N)); + LazyCallGraph::RefSCC *RC2 = &*I++; + EXPECT_EQ(RC2, ORC); + EXPECT_EQ(RC2, CG.lookupRefSCC(FN)); + EXPECT_EQ(CG.postorder_ref_scc_end(), I); +} } |