diff --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp --- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp +++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp @@ -438,6 +438,14 @@ return true; } +static bool isRecursive(Function *F) { + return any_of(F->users(), [F](User *U) { + if (auto *CS = dyn_cast(U)) + return CS->getFunction() == F; + return false; + }); +} + void FunctionSpecializer::specializeFunction(Function *F, SpecializationInfo &S, FuncList &WorkList) { ValueToValueMapTy Mappings; @@ -451,6 +459,15 @@ // with the given value. Solver.markArgInFuncSpecialization(Clone, S.Args); + if (isRecursive(F) && FuncSpecializationMaxIters > 1) { + // Initialize the state of the newly created functions, marking them + // argument-tracked and executable. + if (F->hasExactDefinition() && !F->hasFnAttribute(Attribute::Naked)) + Solver.addTrackedFunction(Clone); + Solver.addArgumentTrackedFunction(Clone); + Solver.markBlockExecutable(&Clone->front()); + } + // Mark all the specialized functions WorkList.push_back(Clone); NbFunctionsSpecialized++; @@ -736,15 +753,7 @@ FuncList &WorkList) { for (auto *F : WorkList) { SpecializedFuncs.insert(F); - - // Initialize the state of the newly created functions, marking them - // argument-tracked and executable. - if (F->hasExactDefinition() && !F->hasFnAttribute(Attribute::Naked)) - Solver.addTrackedFunction(F); - - Solver.addArgumentTrackedFunction(F); Candidates.push_back(F); - Solver.markBlockExecutable(&F->front()); // Replace the function arguments for the specialized functions. for (Argument &Arg : F->args())