[llvm] [LangRef] Clarify to exclude norecurse attribute when any call paths through external functions is present (PR #157087)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 5 05:32:58 PDT 2025


================
@@ -2256,9 +2256,12 @@ For example:
     behavior at runtime if the function ever does dynamically return. Annotated
     functions may still raise an exception, i.a., ``nounwind`` is not implied.
 ``norecurse``
-    This function attribute indicates that the function does not call itself
-    either directly or indirectly down any possible call path. This produces
-    undefined behavior at runtime if the function ever does recurse.
+    This function attribute indicates that the function does not participate in
+    recursion, either directly or through mutual recursion. At runtime it is
+    undefined behavior if any dynamic call stack contains this function more
+    than once at the same time. A function must not be marked ``norecurse`` if,
+    along any call path starting from its body, control may reach an external
+    function whose definition is not available.
----------------
nikic wrote:

I don't think we should be saying anything about external functions -- they are not really the core of the problem, just the way the problem can be exposed given how the SCC-based attribute inference works.

I believe the definition we need is something along these lines:

> This function attribute indicates that the function is not recursive and does not participate in recursion. This means that the function never occurs inside a cycle in the dynamic call graph. For example:
>
> ```
> fn -> other_fn -> fn       ; fn is not norecurse
> other_fn -> fn -> other_fn ; fn is not norecurse
> fn -> other_fn -> other_fn ; fn is norecurse
> ```

https://github.com/llvm/llvm-project/pull/157087


More information about the llvm-commits mailing list