[llvm] [FuncAttrs] Relax norecurse attribute inference (PR #139943)
    David Sherwood via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Thu Jun 12 08:09:12 PDT 2025
    
    
  
================
@@ -2071,24 +2073,50 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
   if (!F || !F->hasExactDefinition() || F->doesNotRecurse())
     return;
 
-  // If all of the calls in F are identifiable and are to norecurse functions, F
-  // is norecurse. This check also detects self-recursion as F is not currently
-  // marked norecurse, so any called from F to F will not be marked norecurse.
-  for (auto &BB : *F)
-    for (auto &I : BB.instructionsWithoutDebug())
+  if (F->hasAddressTaken())
+    return;
+
+  Module *M = F->getParent();
+  llvm::TargetLibraryInfoImpl TLII(llvm::Triple(M->getTargetTriple()));
+  llvm::TargetLibraryInfo TLI(TLII);
+  // If all of the calls in F are identifiable and can be proven to not
+  // callback F, F is norecurse. This check also detects self-recursion
+  // as F is not currently marked norecurse, so any call from F to F
+  // will not be marked norecurse.
+  for (auto &BB : *F) {
+    for (auto &I : BB.instructionsWithoutDebug()) {
       if (auto *CB = dyn_cast<CallBase>(&I)) {
         Function *Callee = CB->getCalledFunction();
-        if (!Callee || Callee == F ||
-            (!Callee->doesNotRecurse() &&
-             !(Callee->isDeclaration() &&
-               Callee->hasFnAttribute(Attribute::NoCallback))))
-          // Function calls a potentially recursive function.
+
+        if (!Callee || Callee == F)
           return;
+
+        if (Callee->doesNotRecurse())
+          continue;
+
+        LibFunc LF;
+        if (Callee->isDeclaration()) {
+          // External call with NoCallback attribute.
+          if (Callee->hasFnAttribute(Attribute::NoCallback))
+            continue;
+          // We rely on this only in post link stage when all functions in the
+          // program are known.
+          if (IsLTOPostLink && !AnyFunctionsAddressIsTaken &&
----------------
david-arm wrote:
I think a lot of this logic could be simplified to a couple of lines
```
  if (Callee->hasFnAttribute(Attribute::NoCallback) || (NoFunctionAddressIsTaken && TLI.getLibFunc(Callee->getName(), LF)))
```
by inverting the AnyFunctionsAddressIsTaken argument to be NoFunctionAddressIsTaken. I think this allows you to remove the IsLTOPostLink argument because pre-LTO NoFunctionAddressIsTaken=false anyway, and post-LTO is only set to true after scanning all the functions in the module.
https://github.com/llvm/llvm-project/pull/139943
    
    
More information about the llvm-commits
mailing list