[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