[llvm] [NVPTX] Add syncscope support for cmpxchg (PR #140812)
Akshay Deodhar via llvm-commits
llvm-commits at lists.llvm.org
Fri May 30 16:42:02 PDT 2025
================
@@ -41,6 +41,27 @@ def AS_match {
}];
}
+multiclass nvvm_ternary_atomic_op_scoped<SDPatternOperator frag> {
+ defvar frag_pat = (frag node:$ptr, node:$cmp, node:$val);
+ def NAME#_cta: PatFrag<!setdagop(frag_pat, ops),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
+ return Scopes[cast<MemSDNode>(N)->getSyncScopeID()] == NVPTX::Scope::Block;
+ }]>;
+ def NAME#_cluster : PatFrag<!setdagop(frag_pat, ops),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
+ return Scopes[cast<MemSDNode>(N)->getSyncScopeID()] == NVPTX::Scope::Cluster;
+ }]>;
+ def NAME#_gpu: PatFrag<!setdagop(frag_pat, ops),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
+ return Scopes[cast<MemSDNode>(N)->getSyncScopeID()] == NVPTX::Scope::Device;
+ }]>;
+ def NAME#_sys: PatFrag<!setdagop(frag_pat, ops),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
+ return Scopes[cast<MemSDNode>(N)->getSyncScopeID()] == NVPTX::Scope::System;
+ }]>;
+}
----------------
akshayrdeodhar wrote:
There isn't a general mechanism, and I gave a lot of thought to creating one before creating this PR. The idea that I came up with was something like the following- an integer parameter to binary_atomic_op, and ternary_atomic_op called "scope".
Then either instantiate ternary_atomic_op<op, max_scopeid_across_backends> in TargetSelectionDAG, or have individual targets instantiate this multiclass based on the highest ID that they want to support.
The first idea would require backends to mutually ensure that max(syncscope_id) across backends is maintained.
```
multiclass ternary_atomic_op<SDNode atomic_op, int scopes = 2> { # default, singlethread and system
foreach vt = [ i8, i16, i32, i64 ] in {
def _#vt : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
(atomic_op node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = true;
let MemoryVT = vt;
}
foreach scope = !range(scopes) in {
defvar scope_str = !cast<string>(scope);
defvar frag_pat = (!cast<SDPatternOperator>(NAME_#_vt) node:$a node:$b node:$c)
def _#vt_#scope_#scope_str : PatFrag<!setdagop(frag_pat, ops), frag_pat>;
defm NAME#_#vt#_#scope_#scope_str : ternary_atomic_op_ord
}
defm NAME#_#vt : ternary_atomic_op_ord;
}
}
```
https://github.com/llvm/llvm-project/pull/140812
More information about the llvm-commits
mailing list