[llvm] [NVPTX] Load/Store/Fence syncscope support (PR #106101)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 19 06:52:28 PDT 2024
================
@@ -4064,3 +4158,43 @@ unsigned NVPTXDAGToDAGISel::GetConvertOpcode(MVT DestTy, MVT SrcTy,
}
}
}
+
+bool NVPTXDAGToDAGISel::tryFence(SDNode *N) {
+ SDLoc DL(N);
+ assert(N->getOpcode() == ISD::ATOMIC_FENCE);
+ unsigned int FenceOp =
+ getFenceOp(NVPTX::Ordering(N->getConstantOperandVal(1)),
+ Scopes[N->getConstantOperandVal(2)], Subtarget);
+ SDValue Chain = N->getOperand(0);
+ SDNode *FenceNode = CurDAG->getMachineNode(FenceOp, DL, MVT::Other, Chain);
+ ReplaceNode(N, FenceNode);
+ return true;
+}
+
+NVPTXScopes::NVPTXScopes(LLVMContext &C) : CTX(&C) {
+ Scopes[C.getOrInsertSyncScopeID("singlethread")] = NVPTX::Scope::Thread;
+ Scopes[C.getOrInsertSyncScopeID("")] = NVPTX::Scope::System;
+ Scopes[C.getOrInsertSyncScopeID("block")] = NVPTX::Scope::Block;
+ Scopes[C.getOrInsertSyncScopeID("cluster")] = NVPTX::Scope::Cluster;
+ Scopes[C.getOrInsertSyncScopeID("device")] = NVPTX::Scope::Device;
+}
+
+NVPTX::Scope NVPTXScopes::operator[](SyncScope::ID ID) const {
+ if (Scopes.empty())
+ report_fatal_error("NVPTX Scopes must be initialized before calling "
+ "NVPTXScopes::operator[]");
+
+ auto S = Scopes.find(ID);
+ if (S == Scopes.end()) {
+ SmallVector<StringRef, 8> ScopeNames;
+ assert(CTX != nullptr && "CTX is nullptr");
+ CTX->getSyncScopeNames(ScopeNames);
+ StringRef Unknown{"unknown"};
+ auto Name = ID < ScopeNames.size() ? ScopeNames[ID] : Unknown;
+ report_fatal_error(
+ formatv("Could not find scope ID={} with name \"{}\".", int(ID), Name));
----------------
gonzalobg wrote:
I see what you mean now.
Yes, if the LLVM IR `SyncScope::ID` (in the LLVM syncscope order) is out of bounds of our cached map, we can't get the `NVPTX::Scope` id, so we error.
This may be, because there is a bug somewhere and either the `LLVM SyncScope` was incorrectly updated after we cached it, or an `ID` in the dag was incorrectly modified such that it triggered an out of bounds.
In this error path, we are currently asking LLVM to give us all the SyncScope names. We are not copying the names themselves (i.e. the Strings), but references to the names into a `SmallVector<StringRef>`, and then we are checking if the `ID` actually is in bounds of that. If it is, we can print a name for it (and this may mean that the mapping was updated after we cached it), and if it is not in bounds, the ID was most likely messed up with.
A `getScopeName(ID)` API to the context would avoid the creation of the vector of string references.
Since this only impacts the path before we crash, would it be ok for me to add that API to context in a separate PR and as part of that PR update this to use it? (More people may have an opinion on the Context API than just the backend, and I don't want to block this change on that).
https://github.com/llvm/llvm-project/pull/106101
More information about the llvm-commits
mailing list