-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Conversation
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``.
@llvm/pr-subscribers-clang Author: Sameer Sahasrabuddhe (ssahasra) ChangesWhen placed on a function, the Full diff: https://github.com/llvm/llvm-project/pull/132701.diff 1 Files Affected:
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
}
}];
|
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 | |||
} |
There was a problem hiding this comment.
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
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. Onlyconvergent
is an attribute in LLVM IR, and there is no equivalent ofclang::noconvergent
.