[llvm] AMDGPU: Improve barrier id allocation (PR #199997)

via llvm-commits llvm-commits at lists.llvm.org
Sun May 31 18:51:20 PDT 2026


https://github.com/ruiling updated https://github.com/llvm/llvm-project/pull/199997

>From 0e28f141d8415119a2123f58ff4b284de46bafce Mon Sep 17 00:00:00 2001
From: Ruiling Song <ruiling.song at amd.com>
Date: Wed, 27 May 2026 10:37:41 +0800
Subject: [PATCH 1/3] Precommit test

---
 .../CodeGen/AMDGPU/s-barrier-id-allocation.ll | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100644 llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll

diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll b/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll
new file mode 100644
index 0000000000000..23b5559cce95d
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll
@@ -0,0 +1,87 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
+; RUN: opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-exec-sync < %s 2>&1 | FileCheck %s
+
+ at bar = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison
+ at bar2 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison
+
+;.
+; CHECK: @bar = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META0:![0-9]+]]
+; CHECK: @bar2 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META1:![0-9]+]]
+;.
+define void @func1() {
+; CHECK-LABEL: define void @func1() {
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar, i32 7)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.wait(i16 1)
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar)
+  call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar, i32 7)
+  call void @llvm.amdgcn.s.barrier.wait(i16 1)
+  ret void
+}
+
+define void @func2() {
+; CHECK-LABEL: define void @func2() {
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar2)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar2, i32 7)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.wait(i16 1)
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar2)
+  call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar2, i32 7)
+  call void @llvm.amdgcn.s.barrier.wait(i16 1)
+  ret void
+}
+
+define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in) {
+; CHECK-LABEL: define amdgpu_kernel void @kernel1(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], ptr addrspace(3) [[IN:%.*]]) {
+; CHECK-NEXT:    call void @func1()
+; CHECK-NEXT:    [[STATE3:%.*]] = call i32 @llvm.amdgcn.s.get.barrier.state(i32 -1)
+; CHECK-NEXT:    ret void
+;
+  call void @func1()
+  %state3 = call i32 @llvm.amdgcn.s.get.barrier.state(i32 -1)
+  ret void
+}
+
+define amdgpu_kernel void @kernel2(ptr addrspace(1) %out, ptr addrspace(3) %in) {
+; CHECK-LABEL: define amdgpu_kernel void @kernel2(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], ptr addrspace(3) [[IN:%.*]]) {
+; CHECK-NEXT:    call void @func1()
+; CHECK-NEXT:    ret void
+;
+  call void @func1()
+  ret void
+}
+
+define amdgpu_kernel void @kernel3(ptr addrspace(1) %out, ptr addrspace(3) %in) {
+; CHECK-LABEL: define amdgpu_kernel void @kernel3(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], ptr addrspace(3) [[IN:%.*]]) {
+; CHECK-NEXT:    call void @func2()
+; CHECK-NEXT:    [[STATE3:%.*]] = call i32 @llvm.amdgcn.s.get.barrier.state(i32 -1)
+; CHECK-NEXT:    ret void
+;
+  call void @func2()
+  %state3 = call i32 @llvm.amdgcn.s.get.barrier.state(i32 -1)
+  ret void
+}
+
+define amdgpu_kernel void @kernel4(ptr addrspace(1) %out, ptr addrspace(3) %in) {
+; CHECK-LABEL: define amdgpu_kernel void @kernel4(
+; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], ptr addrspace(3) [[IN:%.*]]) {
+; CHECK-NEXT:    call void @func2()
+; CHECK-NEXT:    ret void
+;
+  call void @func2()
+  ret void
+}
+
+
+;.
+; CHECK: attributes #[[ATTR0:[0-9]+]] = { convergent nocallback nofree nounwind willreturn }
+;.
+; CHECK: [[META0]] = !{i32 8396816, i32 8396817}
+; CHECK: [[META1]] = !{i32 8396832, i32 8396833}
+;.

>From 961d88a5ad5ea6dafda19b1c92a1430e451a371c Mon Sep 17 00:00:00 2001
From: Ruiling Song <ruiling.song at amd.com>
Date: Wed, 27 May 2026 22:17:32 +0800
Subject: [PATCH 2/3] AMDGPU: Improve barrier id allocation

The existing barrier ID allocation is over-conservative when a barrier
object was indirectly accessed by several kernels. Instead of the
existing allocate barrier ID for such case per-module basis, we track
the ID allocation per kernel. This would be able to reuse the same
barrier ID for different objects which are accessed (indirectly/directly)
by non-overlapping kernels. See the case: s-barrier-id-allocation.ll.

The motivation comes from downstream use-cases which are handled using
exactly the same mechanism.

I have removed the uniquifyGVPerKernel() since it is less useful in the
new way. And I think there are correctness issues in it. For
non-kernel functions, it just did the replacement without ensuring it is
really called by the kernel (`if (!isKernel(*F) || F == KF)`). This is
problematic if the non-kernel functions was called by other kernels. We
can bring it back carefully if we really need it in the future.
---
 .../lib/Target/AMDGPU/AMDGPULowerExecSync.cpp | 204 ++++++++----------
 .../amdgpu-lower-exec-sync-and-module-lds.ll  |  11 +-
 .../CodeGen/AMDGPU/amdgpu-lower-exec-sync.ll  |  11 +-
 .../CodeGen/AMDGPU/s-barrier-id-allocation.ll |   3 +-
 .../test/CodeGen/AMDGPU/s-barrier-lowering.ll |  13 +-
 llvm/test/CodeGen/AMDGPU/s-barrier.ll         |  30 +--
 6 files changed, 118 insertions(+), 154 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
index 72d7fd0651946..3ff63f969f9f9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
@@ -37,39 +37,6 @@ using namespace AMDGPU;
 
 namespace {
 
-// If GV is also used directly by other kernels, create a new GV
-// used only by this kernel and its function.
-static GlobalVariable *uniquifyGVPerKernel(Module &M, GlobalVariable *GV,
-                                           Function *KF) {
-  bool NeedsReplacement = false;
-  for (Use &U : GV->uses()) {
-    if (auto *I = dyn_cast<Instruction>(U.getUser())) {
-      Function *F = I->getFunction();
-      if (isKernel(*F) && F != KF) {
-        NeedsReplacement = true;
-        break;
-      }
-    }
-  }
-  if (!NeedsReplacement)
-    return GV;
-  // Create a new GV used only by this kernel and its function
-  GlobalVariable *NewGV = new GlobalVariable(
-      M, GV->getValueType(), GV->isConstant(), GV->getLinkage(),
-      GV->getInitializer(), GV->getName() + "." + KF->getName(), nullptr,
-      GV->getThreadLocalMode(), GV->getType()->getAddressSpace());
-  NewGV->copyAttributesFrom(GV);
-  for (Use &U : make_early_inc_range(GV->uses())) {
-    if (auto *I = dyn_cast<Instruction>(U.getUser())) {
-      Function *F = I->getFunction();
-      if (!isKernel(*F) || F == KF) {
-        U.getUser()->replaceUsesOfWith(GV, NewGV);
-      }
-    }
-  }
-  return NewGV;
-}
-
 // Write the specified address into metadata where it can be retrieved by
 // the assembler. Format is a half open range, [Address Address+1)
 static void recordLDSAbsoluteAddress(Module *M, GlobalVariable *GV,
@@ -82,92 +49,104 @@ static void recordLDSAbsoluteAddress(Module *M, GlobalVariable *GV,
                   MDNode::get(Ctx, {MinC, MaxC}));
 }
 
-template <typename T> SmallVector<T> sortByName(SmallVector<T> &&V) {
-  sort(V, [](const auto *L, const auto *R) {
-    return L->getName() < R->getName();
-  });
-  return {std::move(V)};
+/// Get next available ID for sync object. The ID allocation is tracked in \p
+/// MaxNumGroup groups by \p NextAvailableIDTracker. Each call of the function
+/// will ask for \p IDCnt against all the \p Kernels, it will return the
+/// maximum of the available ones and update the ID tracker.
+template <typename T>
+unsigned allocateExecSyncID(T &NextAvailableIDTracker,
+                            ArrayRef<Function *> Kernels, unsigned GroupID,
+                            unsigned MaxNumGroup, unsigned IDCnt) {
+  constexpr unsigned InitialVal = 1;
+  unsigned NextID = InitialVal;
+  for (Function *F : Kernels) {
+    const SmallVectorImpl<unsigned> &NextAvailableID =
+        NextAvailableIDTracker.lookup(F);
+    unsigned ID = InitialVal;
+    if (!NextAvailableID.empty())
+      ID = NextAvailableID[GroupID];
+
+    if (ID > NextID)
+      NextID = ID;
+  }
+
+  // Bump the next available id for the kernels.
+  for (Function *F : Kernels) {
+    auto Inserted = NextAvailableIDTracker.try_emplace(F);
+    // Initialize on first insertion.
+    if (Inserted.second)
+      Inserted.first->second.assign(MaxNumGroup, InitialVal);
+    // Update the available ID.
+    Inserted.first->second[GroupID] = NextID + IDCnt;
+  }
+  return NextID;
 }
 
 // Main utility function for special LDS variables lowering.
-static bool lowerExecSyncGlobalVariables(
-    Module &M, LDSUsesInfoTy &LDSUsesInfo,
-    VariableFunctionMap &LDSToKernelsThatNeedToAccessItIndirectly) {
+static bool lowerExecSyncGlobalVariables(Module &M,
+                                         LDSUsesInfoTy &LDSUsesInfo) {
   bool Changed = false;
   const DataLayout &DL = M.getDataLayout();
-  // The 1st round: give module-absolute assignments
-  int NumAbsolutes = 0;
-  SmallVector<GlobalVariable *> OrderedGVs;
-  LDSToKernelsThatNeedToAccessItIndirectly.remove_if([&](auto &K) {
-    GlobalVariable *GV = K.first;
-    if (!isNamedBarrier(*GV))
-      return false;
-    // give a module-absolute assignment if it is indirectly accessed by
-    // multiple kernels. This is not precise, but we don't want to duplicate
-    // a function when it is called by multiple kernels.
-    if (K.second.size() > 1) {
-      OrderedGVs.push_back(GV);
-    } else {
-      // leave it to the 2nd round, which will give a kernel-relative
-      // assignment if it is only indirectly accessed by one kernel
-      LDSUsesInfo.direct_access[*K.second.begin()].insert(GV);
-    }
-    return true;
-  });
-  OrderedGVs = sortByName(std::move(OrderedGVs));
-  for (GlobalVariable *GV : OrderedGVs) {
-    unsigned BarrierScope = AMDGPU::Barrier::BARRIER_SCOPE_WORKGROUP;
-    unsigned BarId = NumAbsolutes + 1;
-    unsigned BarCnt = GV->getGlobalSize(DL) / 16;
-    NumAbsolutes += BarCnt;
-
-    // 4 bits for alignment, 5 bits for the barrier num,
-    // 3 bits for the barrier scope
-    unsigned Offset = 0x802000u | BarrierScope << 9 | BarId << 4;
-    recordLDSAbsoluteAddress(&M, GV, Offset);
-  }
-  OrderedGVs.clear();
-
-  // The 2nd round: give a kernel-relative assignment for GV that
-  // either only indirectly accessed by single kernel or only directly
-  // accessed by multiple kernels.
-  SmallVector<Function *> OrderedKernels;
-  for (auto &K : LDSUsesInfo.direct_access) {
-    Function *F = K.first;
-    assert(isKernel(*F));
-    OrderedKernels.push_back(F);
-  }
-  OrderedKernels = sortByName(std::move(OrderedKernels));
 
-  DenseMap<Function *, uint32_t> Kernel2BarId;
-  for (Function *F : OrderedKernels) {
-    for (GlobalVariable *GV : llvm::to_vector(LDSUsesInfo.direct_access[F])) {
-      if (!isNamedBarrier(*GV))
+  constexpr unsigned NumBarScopes = 1;
+  MapVector<GlobalVariable *, SmallVector<Function *>> AllocationQ;
+  DenseMap<Function *, SmallVector<unsigned, NumBarScopes>> KernelBarrierIDs;
+
+  for (auto &[F, GVs] : LDSUsesInfo.indirect_access) {
+    for (auto *GV : GVs) {
+      if (!isNamedBarrier(*GV) || GV->isAbsoluteSymbolRef())
         continue;
+      auto Iter = AllocationQ.find(GV);
+      if (Iter == AllocationQ.end())
+        AllocationQ.insert({GV, {F}});
+      else
+        Iter->second.push_back(F);
+    }
+  }
 
-      LDSUsesInfo.direct_access[F].erase(GV);
-      if (GV->isAbsoluteSymbolRef()) {
-        // already assigned
+  for (auto &[F, GVs] : LDSUsesInfo.direct_access) {
+    for (auto *GV : GVs) {
+      if (!isNamedBarrier(*GV) || GV->isAbsoluteSymbolRef())
         continue;
-      }
-      OrderedGVs.push_back(GV);
+      auto Iter = AllocationQ.find(GV);
+      if (Iter == AllocationQ.end())
+        AllocationQ.insert({GV, {F}});
+      else
+        Iter->second.push_back(F);
     }
-    OrderedGVs = sortByName(std::move(OrderedGVs));
-    for (GlobalVariable *GV : OrderedGVs) {
-      // GV could also be used directly by other kernels. If so, we need to
-      // create a new GV used only by this kernel and its function.
-      auto NewGV = uniquifyGVPerKernel(M, GV, F);
-      Changed |= (NewGV != GV);
-      unsigned BarrierScope = AMDGPU::Barrier::BARRIER_SCOPE_WORKGROUP;
-      unsigned BarId = Kernel2BarId[F];
-      BarId += NumAbsolutes + 1;
+  }
+
+  sort(AllocationQ, [](std::pair<GlobalVariable *, SmallVector<Function *>> A,
+                       std::pair<GlobalVariable *, SmallVector<Function *>> B) {
+    // First order by number of kernels that access the GlobalVariable.
+    if (A.second.size() != B.second.size())
+      return A.second.size() > B.second.size();
+
+    // Then order by their names so we always get a deterministic order.
+    return A.first->getName() < B.first->getName();
+  });
+
+  for (auto &[GV, Kernels] : AllocationQ) {
+    unsigned Offset;
+    if (TargetExtType *ExtTy = isNamedBarrier(*GV)) {
+      unsigned BarrierScope = ExtTy->getIntParameter(0);
       unsigned BarCnt = GV->getGlobalSize(DL) / 16;
-      Kernel2BarId[F] += BarCnt;
-      unsigned Offset = 0x802000u | BarrierScope << 9 | BarId << 4;
-      recordLDSAbsoluteAddress(&M, NewGV, Offset);
+
+      unsigned BarID = allocateExecSyncID(KernelBarrierIDs, Kernels,
+                                          BarrierScope, NumBarScopes, BarCnt);
+
+      LLVM_DEBUG(dbgs() << "barrier: @" << GV->getName() << " id: " << BarID
+                        << " id-count: " << BarCnt << "\n");
+      // 4 bits for alignment, 5 bits for the barrier num,
+      // 3 bits for the barrier scope
+      Offset = 0x802000u | BarrierScope << 9 | BarID << 4;
+    } else {
+      llvm_unreachable("Unhandled special variable type.");
     }
-    OrderedGVs.clear();
+
+    recordLDSAbsoluteAddress(&M, GV, Offset);
   }
+
   // Also erase those special LDS variables from indirect_access.
   for (auto &K : LDSUsesInfo.indirect_access) {
     assert(isKernel(*K.first));
@@ -228,20 +207,9 @@ static bool runLowerExecSyncGlobals(Module &M) {
   // callees
   LDSUsesInfoTy LDSUsesInfo = getTransitiveUsesOfLDS(CG, M);
 
-  // For each variable accessed through callees, which kernels access it
-  VariableFunctionMap LDSToKernelsThatNeedToAccessItIndirectly;
-  for (auto &K : LDSUsesInfo.indirect_access) {
-    Function *F = K.first;
-    assert(isKernel(*F));
-    for (GlobalVariable *GV : K.second) {
-      LDSToKernelsThatNeedToAccessItIndirectly[GV].insert(F);
-    }
-  }
-
   if (LDSUsesInfo.HasSpecialGVs) {
     // Special LDS variables need special address assignment
-    Changed |= lowerExecSyncGlobalVariables(
-        M, LDSUsesInfo, LDSToKernelsThatNeedToAccessItIndirectly);
+    Changed |= lowerExecSyncGlobalVariables(M, LDSUsesInfo);
   }
   return Changed;
 }
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync-and-module-lds.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync-and-module-lds.ll
index 8a3fa1288ca82..0f9cfb48b577d 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync-and-module-lds.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync-and-module-lds.ll
@@ -15,7 +15,6 @@
 ; CHECK: @bar2 = internal addrspace(3) global [2 x target("amdgcn.named.barrier", 0)] poison, !absolute_symbol [[META0:![0-9]+]]
 ; CHECK: @bar3 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META1:![0-9]+]]
 ; CHECK: @bar1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol [[META2:![0-9]+]]
-; CHECK: @bar1.kernel1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol [[META2]]
 ; CHECK: @llvm.amdgcn.module.lds = internal addrspace(3) global %llvm.amdgcn.module.lds.t poison, align 4, !absolute_symbol [[META3:![0-9]+]]
 ; CHECK: @llvm.compiler.used = appending addrspace(1) global [1 x ptr] [ptr addrspacecast (ptr addrspace(3) @llvm.amdgcn.module.lds to ptr)], section "llvm.metadata"
 ;.
@@ -53,10 +52,10 @@ define amdgpu_kernel void @kernel1() #0 {
 ; CHECK-LABEL: define amdgpu_kernel void @kernel1(
 ; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
 ; CHECK-NEXT:    call void @llvm.donothing() [ "ExplicitUse"(ptr addrspace(3) @llvm.amdgcn.module.lds) ]
-; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1.kernel1)
-; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1.kernel1, i32 11)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1, i32 11)
 ; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.wait(i16 1)
-; CHECK-NEXT:    [[STATE:%.*]] = call i32 @llvm.amdgcn.s.get.named.barrier.state(ptr addrspace(3) @bar1.kernel1)
+; CHECK-NEXT:    [[STATE:%.*]] = call i32 @llvm.amdgcn.s.get.named.barrier.state(ptr addrspace(3) @bar1)
 ; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier()
 ; CHECK-NEXT:    call void @func1()
 ; CHECK-NEXT:    call void @func2()
@@ -114,8 +113,8 @@ attributes #2 = { nounwind readnone }
 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { convergent nocallback nofree nounwind willreturn }
 ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(none) }
 ;.
-; CHECK: [[META0]] = !{i32 8396816, i32 8396817}
+; CHECK: [[META0]] = !{i32 8396880, i32 8396881}
 ; CHECK: [[META1]] = !{i32 8396912, i32 8396913}
-; CHECK: [[META2]] = !{i32 8396848, i32 8396849}
+; CHECK: [[META2]] = !{i32 8396816, i32 8396817}
 ; CHECK: [[META3]] = !{i32 0, i32 1}
 ;.
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync.ll
index b76a80811b2d5..ddf58900518b5 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-lower-exec-sync.ll
@@ -12,7 +12,6 @@
 ; CHECK: @bar2 = internal addrspace(3) global [2 x target("amdgcn.named.barrier", 0)] poison, !absolute_symbol [[META0:![0-9]+]]
 ; CHECK: @bar3 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META1:![0-9]+]]
 ; CHECK: @bar1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol [[META2:![0-9]+]]
-; CHECK: @bar1.kernel1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol [[META2]]
 ;.
 define void @func1() {
 ; CHECK-LABEL: define void @func1() {
@@ -43,10 +42,10 @@ define void @func2() {
 define amdgpu_kernel void @kernel1() #0 {
 ; CHECK-LABEL: define amdgpu_kernel void @kernel1(
 ; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1.kernel1)
-; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1.kernel1, i32 11)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1)
+; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1, i32 11)
 ; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier.wait(i16 1)
-; CHECK-NEXT:    [[STATE:%.*]] = call i32 @llvm.amdgcn.s.get.named.barrier.state(ptr addrspace(3) @bar1.kernel1)
+; CHECK-NEXT:    [[STATE:%.*]] = call i32 @llvm.amdgcn.s.get.named.barrier.state(ptr addrspace(3) @bar1)
 ; CHECK-NEXT:    call void @llvm.amdgcn.s.barrier()
 ; CHECK-NEXT:    call void @func1()
 ; CHECK-NEXT:    call void @func2()
@@ -97,7 +96,7 @@ attributes #2 = { nounwind readnone }
 ; CHECK: attributes #[[ATTR0]] = { nounwind }
 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { convergent nocallback nofree nounwind willreturn }
 ;.
-; CHECK: [[META0]] = !{i32 8396816, i32 8396817}
+; CHECK: [[META0]] = !{i32 8396880, i32 8396881}
 ; CHECK: [[META1]] = !{i32 8396912, i32 8396913}
-; CHECK: [[META2]] = !{i32 8396848, i32 8396849}
+; CHECK: [[META2]] = !{i32 8396816, i32 8396817}
 ;.
diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll b/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll
index 23b5559cce95d..6df651b033a5f 100644
--- a/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier-id-allocation.ll
@@ -6,7 +6,7 @@
 
 ;.
 ; CHECK: @bar = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META0:![0-9]+]]
-; CHECK: @bar2 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META1:![0-9]+]]
+; CHECK: @bar2 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol [[META0]]
 ;.
 define void @func1() {
 ; CHECK-LABEL: define void @func1() {
@@ -83,5 +83,4 @@ define amdgpu_kernel void @kernel4(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { convergent nocallback nofree nounwind willreturn }
 ;.
 ; CHECK: [[META0]] = !{i32 8396816, i32 8396817}
-; CHECK: [[META1]] = !{i32 8396832, i32 8396833}
 ;.
diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier-lowering.ll b/llvm/test/CodeGen/AMDGPU/s-barrier-lowering.ll
index be1cb6c91f1c3..78c134827be4d 100644
--- a/llvm/test/CodeGen/AMDGPU/s-barrier-lowering.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier-lowering.ll
@@ -10,7 +10,6 @@
 ; CHECK: @bar2 = internal addrspace(3) global [2 x target("amdgcn.named.barrier", 0)] poison, !absolute_symbol !0
 ; CHECK-NEXT: @bar3 = internal addrspace(3) global target("amdgcn.named.barrier", 0) poison, !absolute_symbol !1
 ; CHECK-NEXT: @bar1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol !2
-; CHECK-NEXT: @bar1.kernel1 = internal addrspace(3) global [4 x %class.ExpAmdWorkgroupWaveBarrier] poison, !absolute_symbol !2
 
 ; SOUT:        .set .Lfunc1.num_named_barrier, 7
 define void @func1() {
@@ -20,7 +19,7 @@ define void @func1() {
     ret void
 }
 
-; SOUT:        .set .Lfunc2.num_named_barrier, 2
+; SOUT:        .set .Lfunc2.num_named_barrier, 6
 define void @func2() {
     call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar2)
     call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar2, i32 7)
@@ -29,9 +28,9 @@ define void @func2() {
 }
 
 ; SOUT:                .amdhsa_named_barrier_count 2
-; SOUT:        .set .Lkernel1.num_named_barrier, max(6, .Lfunc1.num_named_barrier, .Lfunc2.num_named_barrier)
+; SOUT:        .set .Lkernel1.num_named_barrier, max(4, .Lfunc1.num_named_barrier, .Lfunc2.num_named_barrier)
 define amdgpu_kernel void @kernel1() #0 {
-; CHECK-DAG: call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1.kernel1, i32 11)
+; CHECK-DAG: call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1, i32 11)
     call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1)
     call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1, i32 11)
     call void @llvm.amdgcn.s.barrier.wait(i16 1)
@@ -43,7 +42,7 @@ define amdgpu_kernel void @kernel1() #0 {
 }
 
 ; SOUT:                .amdhsa_named_barrier_count 2
-; SOUT:        .set .Lkernel2.num_named_barrier, max(6, .Lfunc2.num_named_barrier)
+; SOUT:        .set .Lkernel2.num_named_barrier, max(4, .Lfunc2.num_named_barrier)
 define amdgpu_kernel void @kernel2() #0 {
 ; CHECK-DAG: call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar1, i32 9)
     call void @llvm.amdgcn.s.barrier.join(ptr addrspace(3) @bar1)
@@ -69,6 +68,6 @@ attributes #0 = { nounwind }
 attributes #1 = { convergent nounwind }
 attributes #2 = { nounwind readnone }
 
-; CHECK: !0 = !{i32 8396816, i32 8396817}
+; CHECK: !0 = !{i32 8396880, i32 8396881}
 ; CHECK-NEXT: !1 = !{i32 8396912, i32 8396913}
-; CHECK-NEXT: !2 = !{i32 8396848, i32 8396849}
+; CHECK-NEXT: !2 = !{i32 8396816, i32 8396817}
diff --git a/llvm/test/CodeGen/AMDGPU/s-barrier.ll b/llvm/test/CodeGen/AMDGPU/s-barrier.ll
index 248d6a7a5f1d2..495b7b02223e5 100644
--- a/llvm/test/CodeGen/AMDGPU/s-barrier.ll
+++ b/llvm/test/CodeGen/AMDGPU/s-barrier.ll
@@ -47,9 +47,9 @@ define void @func2() {
 ; GFX12-SDAG-NEXT:    s_wait_samplecnt 0x0
 ; GFX12-SDAG-NEXT:    s_wait_bvhcnt 0x0
 ; GFX12-SDAG-NEXT:    s_wait_kmcnt 0x0
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 1
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 2
 ; GFX12-SDAG-NEXT:    s_barrier_join m0
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0x70001
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0x70002
 ; GFX12-SDAG-NEXT:    s_barrier_signal m0
 ; GFX12-SDAG-NEXT:    s_barrier_wait 1
 ; GFX12-SDAG-NEXT:    s_setpc_b64 s[30:31]
@@ -61,8 +61,8 @@ define void @func2() {
 ; GFX12-GISEL-NEXT:    s_wait_samplecnt 0x0
 ; GFX12-GISEL-NEXT:    s_wait_bvhcnt 0x0
 ; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
-; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0x70001
-; GFX12-GISEL-NEXT:    s_barrier_join 1
+; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0x70002
+; GFX12-GISEL-NEXT:    s_barrier_join 2
 ; GFX12-GISEL-NEXT:    s_barrier_signal m0
 ; GFX12-GISEL-NEXT:    s_barrier_wait 1
 ; GFX12-GISEL-NEXT:    s_setpc_b64 s[30:31]
@@ -78,7 +78,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-SDAG-NEXT:    s_mov_b64 s[10:11], s[6:7]
 ; GFX12-SDAG-NEXT:    s_mov_b64 s[6:7], s[2:3]
 ; GFX12-SDAG-NEXT:    s_load_b32 s2, s[4:5], 0x2c
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0xc0002
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0xc0001
 ; GFX12-SDAG-NEXT:    v_mov_b32_e32 v31, v0
 ; GFX12-SDAG-NEXT:    s_barrier_init m0
 ; GFX12-SDAG-NEXT:    s_add_nc_u64 s[8:9], s[4:5], 48
@@ -92,7 +92,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-SDAG-NEXT:    s_cmp_eq_u32 0, 0
 ; GFX12-SDAG-NEXT:    s_mov_b32 m0, s3
 ; GFX12-SDAG-NEXT:    s_barrier_init m0
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0xc0002
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0xc0001
 ; GFX12-SDAG-NEXT:    s_barrier_signal m0
 ; GFX12-SDAG-NEXT:    s_mov_b32 m0, s3
 ; GFX12-SDAG-NEXT:    s_barrier_signal m0
@@ -100,7 +100,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-SDAG-NEXT:    s_barrier_signal -1
 ; GFX12-SDAG-NEXT:    s_barrier_join m0
 ; GFX12-SDAG-NEXT:    s_barrier_signal_isfirst -1
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 2
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 1
 ; GFX12-SDAG-NEXT:    s_barrier_wait 1
 ; GFX12-SDAG-NEXT:    s_wait_kmcnt 0x0
 ; GFX12-SDAG-NEXT:    s_barrier_leave
@@ -134,7 +134,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[12:13], s[4:5]
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[4:5], s[0:1]
 ; GFX12-GISEL-NEXT:    s_load_b32 s0, s[12:13], 0x2c
-; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0xc0002
+; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0xc0001
 ; GFX12-GISEL-NEXT:    v_mov_b32_e32 v31, v0
 ; GFX12-GISEL-NEXT:    s_barrier_init m0
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[10:11], s[6:7]
@@ -148,7 +148,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-GISEL-NEXT:    s_cmp_eq_u32 0, 0
 ; GFX12-GISEL-NEXT:    s_mov_b32 m0, s1
 ; GFX12-GISEL-NEXT:    s_barrier_init m0
-; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0xc0002
+; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0xc0001
 ; GFX12-GISEL-NEXT:    s_barrier_signal m0
 ; GFX12-GISEL-NEXT:    s_mov_b32 m0, s1
 ; GFX12-GISEL-NEXT:    s_barrier_signal m0
@@ -161,7 +161,7 @@ define amdgpu_kernel void @kernel1(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-GISEL-NEXT:    s_barrier_leave
 ; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
 ; GFX12-GISEL-NEXT:    s_add_co_u32 s8, s12, 48
-; GFX12-GISEL-NEXT:    s_get_barrier_state s0, 2
+; GFX12-GISEL-NEXT:    s_get_barrier_state s0, 1
 ; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
 ; GFX12-GISEL-NEXT:    s_get_barrier_state s0, m0
 ; GFX12-GISEL-NEXT:    s_add_co_ci_u32 s9, s13, 0
@@ -216,10 +216,10 @@ define amdgpu_kernel void @kernel2(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-SDAG-NEXT:    s_add_co_ci_u32 s7, s7, func2 at gotpcrel32@hi+16
 ; GFX12-SDAG-NEXT:    v_mov_b32_e32 v31, v0
 ; GFX12-SDAG-NEXT:    s_load_b64 s[12:13], s[6:7], 0x0
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0x70002
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 0x70001
 ; GFX12-SDAG-NEXT:    s_add_nc_u64 s[8:9], s[4:5], 48
 ; GFX12-SDAG-NEXT:    s_barrier_signal m0
-; GFX12-SDAG-NEXT:    s_mov_b32 m0, 2
+; GFX12-SDAG-NEXT:    s_mov_b32 m0, 1
 ; GFX12-SDAG-NEXT:    s_mov_b64 s[4:5], s[0:1]
 ; GFX12-SDAG-NEXT:    s_mov_b64 s[6:7], s[2:3]
 ; GFX12-SDAG-NEXT:    s_mov_b32 s32, 0
@@ -240,12 +240,12 @@ define amdgpu_kernel void @kernel2(ptr addrspace(1) %out, ptr addrspace(3) %in)
 ; GFX12-GISEL-NEXT:    v_mov_b32_e32 v31, v0
 ; GFX12-GISEL-NEXT:    s_load_b64 s[12:13], s[4:5], 0x0
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[10:11], s[6:7]
-; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0x70002
+; GFX12-GISEL-NEXT:    s_mov_b32 m0, 0x70001
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[4:5], s[0:1]
 ; GFX12-GISEL-NEXT:    s_mov_b64 s[6:7], s[2:3]
 ; GFX12-GISEL-NEXT:    s_mov_b32 s32, 0
 ; GFX12-GISEL-NEXT:    s_barrier_signal m0
-; GFX12-GISEL-NEXT:    s_barrier_join 2
+; GFX12-GISEL-NEXT:    s_barrier_join 1
 ; GFX12-GISEL-NEXT:    s_barrier_wait 1
 ; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
 ; GFX12-GISEL-NEXT:    s_swappc_b64 s[30:31], s[12:13]
@@ -266,7 +266,7 @@ define void @signal_var_cnt0_const_bar() {
 ; GFX12-NEXT:    s_wait_samplecnt 0x0
 ; GFX12-NEXT:    s_wait_bvhcnt 0x0
 ; GFX12-NEXT:    s_wait_kmcnt 0x0
-; GFX12-NEXT:    s_barrier_signal 2
+; GFX12-NEXT:    s_barrier_signal 1
 ; GFX12-NEXT:    s_setpc_b64 s[30:31]
     call void @llvm.amdgcn.s.barrier.signal.var(ptr addrspace(3) @bar, i32 0)
     ret void

>From ca7015f06ab954f6bb1b26261aafa9abdbf5695d Mon Sep 17 00:00:00 2001
From: Ruiling Song <ruiling.song at amd.com>
Date: Mon, 1 Jun 2026 09:41:55 +0800
Subject: [PATCH 3/3] switch to printAsOperand()

---
 llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
index 3ff63f969f9f9..007c9635b56eb 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerExecSync.cpp
@@ -135,7 +135,8 @@ static bool lowerExecSyncGlobalVariables(Module &M,
       unsigned BarID = allocateExecSyncID(KernelBarrierIDs, Kernels,
                                           BarrierScope, NumBarScopes, BarCnt);
 
-      LLVM_DEBUG(dbgs() << "barrier: @" << GV->getName() << " id: " << BarID
+      LLVM_DEBUG(GV->printAsOperand(dbgs(), false);
+                 dbgs() << " was assigned barrier id: " << BarID
                         << " id-count: " << BarCnt << "\n");
       // 4 bits for alignment, 5 bits for the barrier num,
       // 3 bits for the barrier scope



More information about the llvm-commits mailing list