[clang] da5fb42 - [Clang][SPIR-V] Fix convergence tokens for dtor (#133469)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 1 02:03:34 PDT 2025
Author: Nathan Gauër
Date: 2025-04-01T11:03:30+02:00
New Revision: da5fb4213ff210f0d49c4ec837b72997cb9e69f5
URL: https://github.com/llvm/llvm-project/commit/da5fb4213ff210f0d49c4ec837b72997cb9e69f5
DIFF: https://github.com/llvm/llvm-project/commit/da5fb4213ff210f0d49c4ec837b72997cb9e69f5.diff
LOG: [Clang][SPIR-V] Fix convergence tokens for dtor (#133469)
Destructor calls were emitted without convergence intrinsics when building for SPIR-V, which means invalid IR since we
mixed controlled and non-controlled convergence.
Added:
Modified:
clang/lib/CodeGen/CGDeclCXX.cpp
clang/test/CodeGenHLSL/GlobalDestructors.hlsl
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index a01fa157c2b26..33c048b48795c 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -1150,7 +1150,7 @@ void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(
llvm::Constant *Arg;
std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
- llvm::CallInst *CI = nullptr;
+ llvm::CallBase *CI = nullptr;
if (Arg == nullptr) {
assert(
CGM.getCXXABI().useSinitAndSterm() &&
@@ -1162,6 +1162,9 @@ void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(
// Make sure the call and the callee agree on calling convention.
if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
CI->setCallingConv(F->getCallingConv());
+
+ if (CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
+ CI = addConvergenceControlToken(CI);
}
}
diff --git a/clang/test/CodeGenHLSL/GlobalDestructors.hlsl b/clang/test/CodeGenHLSL/GlobalDestructors.hlsl
index f98318601134b..9f90971bafd05 100644
--- a/clang/test/CodeGenHLSL/GlobalDestructors.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalDestructors.hlsl
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CS,NOINLINE,CHECK
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=LIB,NOINLINE,CHECK
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan1.3-compute -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CS,NOINLINE-SPIRV,CHECK
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CS,NOINLINE-DXIL,CHECK
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=LIB,NOINLINE-DXIL,CHECK
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -O0 %s -o - | FileCheck %s --check-prefixes=INLINE,CHECK
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -O0 %s -o - | FileCheck %s --check-prefixes=INLINE,CHECK
@@ -57,11 +58,19 @@ void main(unsigned GI : SV_GroupIndex) {
// CHECK: define void @main()
// CHECK-NEXT: entry:
// Verify destructor is emitted
-// NOINLINE-NEXT: call void @_GLOBAL__sub_I_GlobalDestructors.hlsl()
-// NOINLINE-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
-// NOINLINE-NEXT: call void @_Z4mainj(i32 %0)
-// NOINLINE-NEXT: call void @_GLOBAL__D_a()
-// NOINLINE-NEXT: ret void
+// NOINLINE-DXIL-NEXT: call void @_GLOBAL__sub_I_GlobalDestructors.hlsl()
+// NOINLINE-DXIL-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group()
+// NOINLINE-DXIL-NEXT: call void @_Z4mainj(i32 %0)
+// NOINLINE-DXIL-NEXT: call void @_GLOBAL__D_a()
+// NOINLINE-DXIL-NEXT: ret void
+
+// NOINLINE-SPIRV-NEXT: %0 = call token @llvm.experimental.convergence.entry()
+// NOINLINE-SPIRV-NEXT: call spir_func void @_GLOBAL__sub_I_GlobalDestructors.hlsl() [ "convergencectrl"(token %0) ]
+// NOINLINE-SPIRV-NEXT: %1 = call i32 @llvm.spv.flattened.thread.id.in.group()
+// NOINLINE-SPIRV-NEXT: call spir_func void @_Z4mainj(i32 %1) [ "convergencectrl"(token %0) ]
+// NOINLINE-SPIRV-NEXT: call spir_func void @_GLOBAL__D_a() [ "convergencectrl"(token %0) ]
+// NOINLINE-SPIRV-NEXT: ret void
+
// Verify inlining leaves only calls to "llvm." intrinsics
// INLINE-NOT: call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
// INLINE: ret void
@@ -69,10 +78,17 @@ void main(unsigned GI : SV_GroupIndex) {
// This is really just a sanity check I needed for myself to verify that
// function scope static variables also get destroyed properly.
-// NOINLINE: define internal void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]]
-// NOINLINE-NEXT: entry:
-// NOINLINE-NEXT: call void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T)
-// NOINLINE-NEXT: call void @_ZN6PupperD1Ev(ptr @GlobalPup)
-// NOINLINE-NEXT: ret void
+// NOINLINE-DXIL: define internal void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]]
+// NOINLINE-DXIL-NEXT: entry:
+// NOINLINE-DXIL-NEXT: call void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T)
+// NOINLINE-DXIL-NEXT: call void @_ZN6PupperD1Ev(ptr @GlobalPup)
+// NOINLINE-DXIL-NEXT: ret void
+
+// NOINLINE-SPIRV: define internal spir_func void @_GLOBAL__D_a() [[IntAttr:\#[0-9]+]]
+// NOINLINE-SPIRV-NEXT: entry:
+// NOINLINE-SPIRV-NEXT: %0 = call token @llvm.experimental.convergence.entry()
+// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN4TailD1Ev(ptr @_ZZ3WagvE1T) [ "convergencectrl"(token %0) ]
+// NOINLINE-SPIRV-NEXT: call spir_func void @_ZN6PupperD1Ev(ptr @GlobalPup) [ "convergencectrl"(token %0) ]
+// NOINLINE-SPIRV-NEXT: ret void
// NOINLINE: attributes [[IntAttr]] = {{.*}} alwaysinline
More information about the cfe-commits
mailing list