Skip to content

Conversation

@inbelic
Copy link
Contributor

@inbelic inbelic commented Sep 22, 2025

GroupMemoryBarrierWithGroupSync is required to be marked as convergent so that it can't generate duplicate calls or be moved to identical control flow.

Without it, we generate undefined behaviour during optimization. For instance: https://godbolt.org/z/9j3vsq1h3.

Testing that the convergent attribute is added is sufficient. There already exists testing, here, that it will not be moved as described in the above link.

@inbelic inbelic marked this pull request as ready for review September 22, 2025 18:50
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics backend:DirectX HLSL HLSL Language Support llvm:ir labels Sep 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 22, 2025

@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-directx

@llvm/pr-subscribers-hlsl

Author: Finn Plummer (inbelic)

Changes

GroupMemoryBarrierWithGroupSync is required to be marked as convergent so that it can't generate duplicate calls or be moved to identical control flow.

Without it, we generate undefined behaviour during optimization. For instance: https://godbolt.org/z/9j3vsq1h3.

Testing that the convergent attribute is added is sufficient. There already exists testing, here, that it will not be moved as described in the above link.


Full diff: https://github.com/llvm/llvm-project/pull/160175.diff

4 Files Affected:

  • (modified) clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h (+1-1)
  • (modified) clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl (+1-1)
  • (modified) llvm/include/llvm/IR/IntrinsicsDirectX.td (+2-1)
  • (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+2-1)
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 21a9c30d9f445..cd1ffc8c23298 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -2805,7 +2805,7 @@ float4 radians(float4);
 /// call.
 
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_group_memory_barrier_with_group_sync)
-void GroupMemoryBarrierWithGroupSync(void);
+__attribute__((convergent)) void GroupMemoryBarrierWithGroupSync(void);
 
 } // namespace hlsl
 #endif //_HLSL_HLSL_ALIAS_INTRINSICS_H_
diff --git a/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl b/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl
index 114230d38ba54..e709ed3616f0d 100644
--- a/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/GroupMemoryBarrierWithGroupSync.hlsl
@@ -17,4 +17,4 @@ void test_GroupMemoryBarrierWithGroupSync() {
 
 // CHECK: declare void @llvm.[[TARGET]].group.memory.barrier.with.group.sync() #[[ATTRS:[0-9]+]]
 // CHECK-NOT: attributes #[[ATTRS]] = {{.+}}memory(none){{.+}}
-// CHECK: attributes #[[ATTRS]] = {
+// CHECK: attributes #[[ATTRS]] = {{.+}}convergent{{.+}}
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 5d76c3f8df89d..e60e07801455f 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -160,5 +160,6 @@ def int_dx_firstbituhigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0,
 def int_dx_firstbitshigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem]>;
 def int_dx_firstbitlow : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem]>;
 
-def int_dx_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
+def int_dx_group_memory_barrier_with_group_sync
+    : DefaultAttrsIntrinsic<[], [], [IntrConvergent]>;
 }
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index bc026fa33c769..0b0c2b137e55b 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -127,7 +127,8 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]
       : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent]>;
   def int_spv_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
   def int_spv_radians : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
-  def int_spv_group_memory_barrier_with_group_sync : DefaultAttrsIntrinsic<[], [], []>;
+  def int_spv_group_memory_barrier_with_group_sync
+      : DefaultAttrsIntrinsic<[], [], [IntrConvergent]>;
   def int_spv_discard : DefaultAttrsIntrinsic<[], [], []>;
   def int_spv_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
   def int_spv_sclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;

@inbelic inbelic enabled auto-merge (squash) September 22, 2025 18:54
@inbelic inbelic merged commit 87e1da3 into llvm:main Sep 22, 2025
18 checks passed
@inbelic inbelic deleted the inbelic/gmb-convergent branch October 29, 2025 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:DirectX backend:X86 clang:headers Headers provided by Clang, e.g. for intrinsics clang Clang issues not falling into any other category HLSL HLSL Language Support llvm:ir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants