diff options
-rw-r--r-- | llvm/lib/Analysis/CGSCCPassManager.cpp | 13 | ||||
-rw-r--r-- | llvm/test/Other/cgscc-libcall-update.ll | 17 |
2 files changed, 26 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp index cb6d139c88c..b81069559c7 100644 --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -421,7 +421,9 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( assert(E && "No function transformations should introduce *new* " "call edges! Any new calls should be modeled as " "promoted existing ref edges!"); - RetainedEdges.insert(&CalleeN); + bool Inserted = RetainedEdges.insert(&CalleeN).second; + (void)Inserted; + assert(Inserted && "We should never visit a function twice."); if (!E->isCall()) PromotedRefTargets.insert(&CalleeN); } @@ -441,7 +443,9 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( assert(E && "No function transformations should introduce *new* ref " "edges! Any new ref edges would require IPO which " "function passes aren't allowed to do!"); - RetainedEdges.insert(&RefereeN); + bool Inserted = RetainedEdges.insert(&RefereeN).second; + (void)Inserted; + assert(Inserted && "We should never visit a function twice."); if (E->isCall()) DemotedCallTargets.insert(&RefereeN); }; @@ -449,7 +453,10 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass( // Include synthetic reference edges to known, defined lib functions. for (auto *F : G.getLibFunctions()) - VisitRef(*F); + // While the list of lib functions doesn't have repeats, don't re-visit + // anything handled above. + if (!Visited.count(F)) + VisitRef(*F); // First remove all of the edges that are no longer present in this function. // We have to build a list of dead targets first and then remove them as the diff --git a/llvm/test/Other/cgscc-libcall-update.ll b/llvm/test/Other/cgscc-libcall-update.ll index e0833ca0926..072eec428f2 100644 --- a/llvm/test/Other/cgscc-libcall-update.ll +++ b/llvm/test/Other/cgscc-libcall-update.ll @@ -3,7 +3,10 @@ ; ; Also check that it can handle inlining *removing* a libcall entirely. ; -; RUN: opt -passes='cgscc(inline,function(instcombine))' -S < %s | FileCheck %s +; Finally, we include some recursive patterns and forced analysis invaliadtion +; that can trigger infinite CGSCC refinement if not handled correctly. +; +; RUN: opt -passes='cgscc(inline,function(instcombine,invalidate<all>))' -S < %s | FileCheck %s define i8* @wibble(i8* %arg1, i8* %arg2) { ; CHECK-LABEL: define i8* @wibble( @@ -59,3 +62,15 @@ entry: %shr = and i32 %and2, 65280 ret i32 %shr } + +define i64 @write(i32 %i, i8* %p, i64 %j) { +entry: + %val = call i64 @write_wrapper(i32 %i, i8* %p, i64 %j) noinline + ret i64 %val +} + +define i64 @write_wrapper(i32 %i, i8* %p, i64 %j) { +entry: + %val = call i64 @write(i32 %i, i8* %p, i64 %j) noinline + ret i64 %val +} |