Skip to content

[clang] noconvergent does not affect calls to convergent functions #132701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2025

Conversation

ssahasra
Copy link
Collaborator

When placed on a function, the clang::noconvergent attribute ensures that the function is not assumed to be convergent. But the same attribute has no effect on function calls. A call is convergent if the callee is convergent. This is based on the fact that in LLVM, a call always inherits all the attributes of the callee. Only convergent is an attribute in LLVM IR, and there is no equivalent of clang::noconvergent.

When placed on a function, the ``clang::noconvergent`` attribute ensures that
the function is not assumed to be convergent. But the same attribute has no
effect on function calls. A call is convergent if the callee is convergent. This
is based on the fact that in LLVM, a call always inherits all the attributes of
the callee. Only ``convergent`` is an attribute in LLVM IR, and there is no
equivalent of ``clang::noconvergent``.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Mar 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 24, 2025

@llvm/pr-subscribers-clang

Author: Sameer Sahasrabuddhe (ssahasra)

Changes

When placed on a function, the clang::noconvergent attribute ensures that the function is not assumed to be convergent. But the same attribute has no effect on function calls. A call is convergent if the callee is convergent. This is based on the fact that in LLVM, a call always inherits all the attributes of the callee. Only convergent is an attribute in LLVM IR, and there is no equivalent of clang::noconvergent.


Full diff: https://github.com/llvm/llvm-project/pull/132701.diff

1 Files Affected:

  • (modified) clang/include/clang/Basic/AttrDocs.td (+10-10)
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index a8b588169725a..98d29838dce42 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1658,17 +1658,16 @@ Sample usage:
 def NoConvergentDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
-This attribute prevents a function from being treated as convergent, which
-means that optimizations can only move calls to that function to
-control-equivalent blocks. If a statement is marked as ``noconvergent`` and
-contains calls, it also prevents those calls from being treated as convergent.
-In other words, those calls are not restricted to only being moved to
-control-equivalent blocks.
+This attribute prevents a function from being treated as convergent; when a
+function is marked ``noconvergent``, calls to that function are not
+automatically assumed to be convergent, unless such calls are explicitly marked
+as ``convergent``. If a statement is marked as ``noconvergent``, any calls to
+inline ``asm`` in that statement are no longer treated as convergent.
 
 In languages following SPMD/SIMT programming model, e.g., CUDA/HIP, function
-declarations and calls are treated as convergent by default for correctness.
-This ``noconvergent`` attribute is helpful for developers to prevent them from
-being treated as convergent when it's safe.
+declarations and inline asm calls are treated as convergent by default for
+correctness. This ``noconvergent`` attribute is helpful for developers to
+prevent them from being treated as convergent when it's safe.
 
 .. code-block:: c
 
@@ -1677,7 +1676,8 @@ being treated as convergent when it's safe.
 
   __device__ int example(void) {
     float x;
-    [[clang::noconvergent]] x = bar(x);
+    [[clang::noconvergent]] x = bar(x); // no effect on convergence
+    [[clang::noconvergent]] { asm volatile ("nop"); } // the asm call is non-convergent
   }
 
   }];

@arsenm
Copy link
Contributor

arsenm commented Mar 24, 2025

Only convergent is an attribute in LLVM IR, and there is no equivalent of clang::noconvergent.

There should be (and I still have a patch somewhere to add it)

@@ -1677,7 +1676,8 @@ being treated as convergent when it's safe.

__device__ int example(void) {
float x;
[[clang::noconvergent]] x = bar(x);
[[clang::noconvergent]] x = bar(x); // no effect on convergence
[[clang::noconvergent]] { asm volatile ("nop"); } // the asm call is non-convergent
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe should have an example of an undefined usage

@ssahasra ssahasra merged commit f6a3cd5 into main Mar 25, 2025
16 checks passed
@ssahasra ssahasra deleted the users/ssahasra/clarify-noconvergent branch March 25, 2025 05:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants