[clang] [HLSL][SPIRV] Add convergence tokens to entry point wrapper (PR #112757)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 17 11:13:34 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Steven Perron (s-perron)
<details>
<summary>Changes</summary>
Inlining currently assumes that either all function use controled
convergence or none of them do. This is why we need to have the entry
point wrapper use controled convergence.
https://github.com/llvm/llvm-project/blob/c85611e8583e6392d56075ebdfa60893b6284813/llvm/lib/Transforms/Utils/InlineFunction.cpp#L2431-L2439
---
Full diff: https://github.com/llvm/llvm-project/pull/112757.diff
3 Files Affected:
- (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+37-4)
- (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+1)
- (added) clang/test/CodeGenHLSL/convergence/entry.point.hlsl (+11)
``````````diff
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 3237d93ca31ceb..d006f5d8f3c1cd 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -399,6 +399,17 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
BasicBlock *BB = BasicBlock::Create(Ctx, "entry", EntryFn);
IRBuilder<> B(BB);
llvm::SmallVector<Value *> Args;
+
+ SmallVector<OperandBundleDef, 1> OB;
+ if (CGM.shouldEmitConvergenceTokens()) {
+ assert(EntryFn->isConvergent());
+ llvm::Value *
+ I = B.CreateIntrinsic(llvm::Intrinsic::experimental_convergence_entry, {},
+ {});
+ llvm::Value *bundleArgs[] = {I};
+ OB.emplace_back("convergencectrl", bundleArgs);
+ }
+
// FIXME: support struct parameters where semantics are on members.
// See: https://github.com/llvm/llvm-project/issues/57874
unsigned SRetOffset = 0;
@@ -414,7 +425,7 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD,
Args.push_back(emitInputSemantic(B, *PD, Param.getType()));
}
- CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args);
+ CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB);
CI->setCallingConv(Fn->getCallingConv());
// FIXME: Handle codegen for return type semantics.
// See: https://github.com/llvm/llvm-project/issues/57875
@@ -469,14 +480,21 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() {
for (auto &F : M.functions()) {
if (!F.hasFnAttribute("hlsl.shader"))
continue;
- IRBuilder<> B(&F.getEntryBlock(), F.getEntryBlock().begin());
+ auto* Token = getConvergenceToken(F.getEntryBlock());
+ Instruction* IP = Token ? Token : &*F.getEntryBlock().begin();
+ IRBuilder<> B(IP);
+ std::vector<OperandBundleDef> OB;
+ if (Token) {
+ llvm::Value *bundleArgs[] = {Token};
+ OB.emplace_back("convergencectrl", bundleArgs);
+ }
for (auto *Fn : CtorFns)
- B.CreateCall(FunctionCallee(Fn));
+ B.CreateCall(FunctionCallee(Fn), {}, OB);
// Insert global dtors before the terminator of the last instruction
B.SetInsertPoint(F.back().getTerminator());
for (auto *Fn : DtorFns)
- B.CreateCall(FunctionCallee(Fn));
+ B.CreateCall(FunctionCallee(Fn), {}, OB);
}
// No need to keep global ctors/dtors for non-lib profile after call to
@@ -489,3 +507,18 @@ void CGHLSLRuntime::generateGlobalCtorDtorCalls() {
GV->eraseFromParent();
}
}
+
+llvm::Instruction *CGHLSLRuntime::getConvergenceToken(BasicBlock &BB) {
+ if (!CGM.shouldEmitConvergenceTokens())
+ return nullptr;
+
+ auto E = BB.end();
+ for(auto I = BB.begin(); I != E; ++I) {
+ auto *II = dyn_cast<llvm::IntrinsicInst>(&*I);
+ if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) {
+ return II;
+ }
+ }
+ llvm_unreachable("Convergence token should have been emitted.");
+ return nullptr;
+}
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index f7621ee20b1243..3eb56cd5449704 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -137,6 +137,7 @@ class CGHLSLRuntime {
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn);
void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn);
+ llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB);
private:
void addBufferResourceAnnotation(llvm::GlobalVariable *GV,
diff --git a/clang/test/CodeGenHLSL/convergence/entry.point.hlsl b/clang/test/CodeGenHLSL/convergence/entry.point.hlsl
new file mode 100644
index 00000000000000..a848c834da3535
--- /dev/null
+++ b/clang/test/CodeGenHLSL/convergence/entry.point.hlsl
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple spirv-pc-vulkan-compute -finclude-default-header -fnative-half-type -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @main()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[token:%[0-9]+]] = call token @llvm.experimental.convergence.entry()
+// CHECK-NEXT: call spir_func void @_Z4mainv() [ "convergencectrl"(token [[token]]) ]
+
+[numthreads(1,1,1)]
+void main() {
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/112757
More information about the cfe-commits
mailing list