[llvm] e7ed43c - [FuncSpec] Invalidate analyses when deleting a fully specialised function
Momchil Velikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 30 10:58:13 PST 2022
Author: Momchil Velikov
Date: 2022-11-30T18:56:23Z
New Revision: e7ed43c7530d5277bb3ea5f3a0ef18e20ca464db
URL: https://github.com/llvm/llvm-project/commit/e7ed43c7530d5277bb3ea5f3a0ef18e20ca464db
DIFF: https://github.com/llvm/llvm-project/commit/e7ed43c7530d5277bb3ea5f3a0ef18e20ca464db.diff
LOG: [FuncSpec] Invalidate analyses when deleting a fully specialised function
Deleting a fully specialised function left dangling pointers in
`FunctionAnalysisManager`, which causes an internal compiler error
when the function's storage was reused.
Fixes bug #58759.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D138909
Change-Id: Ifed378c748af35e8fe7dcbdddb0f41b8777cbe87
Added:
llvm/test/Transforms/FunctionSpecialization/compiler-crash-58759.ll
Modified:
llvm/include/llvm/Transforms/Scalar/SCCP.h
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
llvm/lib/Transforms/IPO/SCCP.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Scalar/SCCP.h b/llvm/include/llvm/Transforms/Scalar/SCCP.h
index 032a9b15fc465..2e6e431a313b0 100644
--- a/llvm/include/llvm/Transforms/Scalar/SCCP.h
+++ b/llvm/include/llvm/Transforms/Scalar/SCCP.h
@@ -45,7 +45,7 @@ bool runIPSCCP(Module &M, const DataLayout &DL,
function_ref<AnalysisResultsForFn(Function &)> getAnalysis);
bool runFunctionSpecialization(
- Module &M, const DataLayout &DL,
+ Module &M, FunctionAnalysisManager *FAM, const DataLayout &DL,
std::function<TargetLibraryInfo &(Function &)> GetTLI,
std::function<TargetTransformInfo &(Function &)> GetTTI,
std::function<AssumptionCache &(Function &)> GetAC,
diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 997e74855b88b..97608ca00eb07 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -271,6 +271,9 @@ class FunctionSpecializer {
/// The IPSCCP Solver.
SCCPSolver &Solver;
+ /// Analysis manager, needed to invalidate analyses.
+ FunctionAnalysisManager *FAM;
+
/// Analyses used to help determine if a function should be specialized.
std::function<AssumptionCache &(Function &)> GetAC;
std::function<TargetTransformInfo &(Function &)> GetTTI;
@@ -282,11 +285,12 @@ class FunctionSpecializer {
DenseMap<Function *, CodeMetrics> FunctionMetrics;
public:
- FunctionSpecializer(SCCPSolver &Solver,
+ FunctionSpecializer(SCCPSolver &Solver, FunctionAnalysisManager *FAM,
std::function<AssumptionCache &(Function &)> GetAC,
std::function<TargetTransformInfo &(Function &)> GetTTI,
std::function<TargetLibraryInfo &(Function &)> GetTLI)
- : Solver(Solver), GetAC(GetAC), GetTTI(GetTTI), GetTLI(GetTLI) {}
+ : Solver(Solver), FAM(FAM), GetAC(GetAC), GetTTI(GetTTI), GetTLI(GetTLI) {
+ }
~FunctionSpecializer() {
// Eliminate dead code.
@@ -344,6 +348,8 @@ class FunctionSpecializer {
for (auto *F : FullySpecialized) {
LLVM_DEBUG(dbgs() << "FnSpecialization: Removing dead function "
<< F->getName() << "\n");
+ if (FAM)
+ FAM->clear(*F, F->getName());
F->eraseFromParent();
}
FullySpecialized.clear();
@@ -819,13 +825,13 @@ class FunctionSpecializer {
} // namespace
bool llvm::runFunctionSpecialization(
- Module &M, const DataLayout &DL,
+ Module &M, FunctionAnalysisManager *FAM, const DataLayout &DL,
std::function<TargetLibraryInfo &(Function &)> GetTLI,
std::function<TargetTransformInfo &(Function &)> GetTTI,
std::function<AssumptionCache &(Function &)> GetAC,
function_ref<AnalysisResultsForFn(Function &)> GetAnalysis) {
SCCPSolver Solver(DL, GetTLI, M.getContext());
- FunctionSpecializer FS(Solver, GetAC, GetTTI, GetTLI);
+ FunctionSpecializer FS(Solver, FAM, GetAC, GetTTI, GetTLI);
bool Changed = false;
// Loop over all functions, marking arguments to those with their addresses
diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index 673bb230834b3..d5f3b605f2bca 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -130,7 +130,7 @@ PreservedAnalyses FunctionSpecializationPass::run(Module &M,
&FAM.getResult<LoopAnalysis>(F)};
};
- if (!runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis))
+ if (!runFunctionSpecialization(M, &FAM, DL, GetTLI, GetTTI, GetAC, GetAnalysis))
return PreservedAnalyses::all();
PreservedAnalyses PA;
@@ -179,7 +179,7 @@ struct FunctionSpecializationLegacyPass : public ModulePass {
nullptr, // manager, so set them to nullptr.
nullptr};
};
- return runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis);
+ return runFunctionSpecialization(M, nullptr, DL, GetTLI, GetTTI, GetAC, GetAnalysis);
}
};
} // namespace
diff --git a/llvm/test/Transforms/FunctionSpecialization/compiler-crash-58759.ll b/llvm/test/Transforms/FunctionSpecialization/compiler-crash-58759.ll
new file mode 100644
index 0000000000000..5cf3f42e508ed
--- /dev/null
+++ b/llvm/test/Transforms/FunctionSpecialization/compiler-crash-58759.ll
@@ -0,0 +1,27 @@
+; RUN: opt -S --passes='default<O3>' -enable-function-specialization < %s | FileCheck %s
+
+define dso_local i32 @g0(i32 noundef %x) local_unnamed_addr {
+entry:
+ %call = tail call fastcc i32 @f(i32 noundef %x, ptr noundef nonnull @p0)
+ ret i32 %call
+}
+
+define internal fastcc i32 @f(i32 noundef %x, ptr nocapture noundef readonly %p) noinline {
+entry:
+ %call = tail call i32 %p(i32 noundef %x)
+ %add = add nsw i32 %call, %x
+ ret i32 %add
+}
+
+define dso_local i32 @g1(i32 noundef %x) {
+entry:
+ %call = tail call fastcc i32 @f(i32 noundef %x, ptr noundef nonnull @p1)
+ ret i32 %call
+}
+
+declare i32 @p0(i32 noundef)
+declare i32 @p1(i32 noundef)
+
+;; Tests that `f` has been fully specialize and it didn't cause compiler crash.
+;; CHECK-DAG: f.1
+;; CHECK-DAG: f.2
More information about the llvm-commits
mailing list