[llvm-branch-commits] [llvm] [AMDGPU] Validate barrier ID in S_BARRIER_SIGNAL_ISFIRST (PR #220101)
Stanislav Mekhanoshin via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Sep 2 12:54:13 PDT 2026
https://github.com/rampitec updated https://github.com/llvm/llvm-project/pull/220101
>From 7ce724db552099e3047bf6e874acc81191089bcc Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin <Stanislav.Mekhanoshin at amd.com>
Date: Mon, 31 Aug 2026 14:54:06 -0700
Subject: [PATCH] [AMDGPU] Validate barrier ID in S_BARRIER_SIGNAL_ISFIRST
Value user_cluster_barrier_id is not supported.
---
.../Target/AMDGPU/AMDGPULowerIntrinsics.cpp | 8 ++++
.../AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 23 +++++++++++
....barrier.signal.isfirst.invalid_barrier.ll | 9 +++++
.../lower-intrinsics-cluster-barrier.ll | 39 ++-----------------
llvm/test/MC/AMDGPU/gfx12_err.s | 3 ++
llvm/test/MC/AMDGPU/gfx13_err.s | 5 +++
6 files changed, 51 insertions(+), 36 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.barrier.signal.isfirst.invalid_barrier.ll
create mode 100644 llvm/test/MC/AMDGPU/gfx13_err.s
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
index 1fe9b1dc88a23..194461605ba87 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
@@ -14,6 +14,7 @@
#include "AMDGPU.h"
#include "AMDGPUTargetMachine.h"
#include "GCNSubtarget.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
@@ -164,6 +165,13 @@ bool AMDGPULowerIntrinsicsImpl::visitBarrier(IntrinsicInst &I) {
(BarrierID >= AMDGPU::Barrier::NAMED_BARRIER_FIRST &&
BarrierID <= AMDGPU::Barrier::NAMED_BARRIER_LAST))
IsWorkgroupScope = true;
+ else if (I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier_signal_isfirst &&
+ BarrierID == AMDGPU::Barrier::CLUSTER)
+ I.getContext().diagnose(
+ DiagnosticInfoUnsupported(*I.getFunction(),
+ "s_barrier_signal_isfirst does not support "
+ "user_cluster_barrier_id (-3)",
+ I.getDebugLoc()));
} else {
assert(I.getIntrinsicID() == Intrinsic::amdgcn_s_barrier);
IsWorkgroupScope = true;
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 0eab7c7be254b..93ad92237fe0e 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -1865,6 +1865,8 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
bool validateLdsDirect(const MCInst &Inst, const OperandVector &Operands);
bool validateWMMA(const MCInst &Inst, const OperandVector &Operands);
bool validateMonitorSleep(const MCInst &Inst, const OperandVector &Operands);
+ bool validateClusterBarrierIsFirst(const MCInst &Inst,
+ const OperandVector &Operands);
unsigned getConstantBusLimit(unsigned Opcode) const;
bool usesConstantBus(const MCInst &Inst, unsigned OpIdx);
bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
@@ -5603,6 +5605,24 @@ bool AMDGPUAsmParser::validateMonitorSleep(const MCInst &Inst,
return true;
}
+bool AMDGPUAsmParser::validateClusterBarrierIsFirst(
+ const MCInst &Inst, const OperandVector &Operands) {
+ unsigned Opc = Inst.getOpcode();
+ if (Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx12 &&
+ Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx13)
+ return true;
+
+ int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
+ int BarrierID = Inst.getOperand(Src0Idx).getImm();
+ if (BarrierID != AMDGPU::Barrier::CLUSTER)
+ return true;
+
+ Error(
+ getOperandLoc(Operands, Src0Idx),
+ "s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)");
+ return false;
+}
+
bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, SMLoc IDLoc,
const OperandVector &Operands) {
if (!validateLdsDirect(Inst, Operands))
@@ -5737,6 +5757,9 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, SMLoc IDLoc,
if (!validateMonitorSleep(Inst, Operands)) {
return false;
}
+ if (!validateClusterBarrierIsFirst(Inst, Operands)) {
+ return false;
+ }
return true;
}
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.barrier.signal.isfirst.invalid_barrier.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.barrier.signal.isfirst.invalid_barrier.ll
new file mode 100644
index 0000000000000..1257bcbe8c3dd
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.barrier.signal.isfirst.invalid_barrier.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple=amdgpu12.50 -filetype=null < %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: <unknown>:0:0: in function invalid_barrier_id i1 (): s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)
+
+define i1 @invalid_barrier_id() {
+ %r = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -3)
+ ret i1 %r
+}
+
diff --git a/llvm/test/CodeGen/AMDGPU/lower-intrinsics-cluster-barrier.ll b/llvm/test/CodeGen/AMDGPU/lower-intrinsics-cluster-barrier.ll
index 2f1eb6a63f519..4db05e14e8c34 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-intrinsics-cluster-barrier.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-intrinsics-cluster-barrier.ll
@@ -5,39 +5,6 @@
declare void @foo(i1)
-; Verify that the explicit use of a split cluster barrier isn't optimized away.
-define amdgpu_kernel void @split_barriers() "amdgpu-flat-work-group-size"="32,32" {
-; NOOPT-LABEL: define amdgpu_kernel void @split_barriers(
-; NOOPT-SAME: ) #[[ATTR0:[0-9]+]] {
-; NOOPT-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -3)
-; NOOPT-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -3)
-; NOOPT-NEXT: [[ISFIRST:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -3)
-; NOOPT-NEXT: call void @foo(i1 [[ISFIRST]])
-; NOOPT-NEXT: ret void
-;
-; OPT-WAVE32-LABEL: define amdgpu_kernel void @split_barriers(
-; OPT-WAVE32-SAME: ) #[[ATTR1:[0-9]+]] {
-; OPT-WAVE32-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -3)
-; OPT-WAVE32-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -3)
-; OPT-WAVE32-NEXT: [[ISFIRST:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -3)
-; OPT-WAVE32-NEXT: call void @foo(i1 [[ISFIRST]])
-; OPT-WAVE32-NEXT: ret void
-;
-; OPT-WAVE64-LABEL: define amdgpu_kernel void @split_barriers(
-; OPT-WAVE64-SAME: ) #[[ATTR1:[0-9]+]] {
-; OPT-WAVE64-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -3)
-; OPT-WAVE64-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -3)
-; OPT-WAVE64-NEXT: [[ISFIRST:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -3)
-; OPT-WAVE64-NEXT: call void @foo(i1 [[ISFIRST]])
-; OPT-WAVE64-NEXT: ret void
-;
- call void @llvm.amdgcn.s.barrier.signal(i32 -3)
- call void @llvm.amdgcn.s.barrier.wait(i16 -3)
- %isfirst = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -3)
- call void @foo(i1 %isfirst)
- ret void
-}
-
define amdgpu_kernel void @s_cluster_barrier() {
; NOOPT-LABEL: define amdgpu_kernel void @s_cluster_barrier() {
; NOOPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -1)
@@ -80,7 +47,7 @@ define amdgpu_kernel void @s_cluster_barrier() {
define amdgpu_kernel void @s_cluster_barrier_wg32() "amdgpu-flat-work-group-size"="32,32" {
; NOOPT-LABEL: define amdgpu_kernel void @s_cluster_barrier_wg32(
-; NOOPT-SAME: ) #[[ATTR0]] {
+; NOOPT-SAME: ) #[[ATTR0:[0-9]+]] {
; NOOPT-NEXT: [[TMP1:%.*]] = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 -1)
; NOOPT-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -1)
; NOOPT-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB3:.*]]
@@ -92,14 +59,14 @@ define amdgpu_kernel void @s_cluster_barrier_wg32() "amdgpu-flat-work-group-size
; NOOPT-NEXT: ret void
;
; OPT-WAVE32-LABEL: define amdgpu_kernel void @s_cluster_barrier_wg32(
-; OPT-WAVE32-SAME: ) #[[ATTR1]] {
+; OPT-WAVE32-SAME: ) #[[ATTR1:[0-9]+]] {
; OPT-WAVE32-NEXT: call void @llvm.amdgcn.wave.barrier()
; OPT-WAVE32-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -3)
; OPT-WAVE32-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -3)
; OPT-WAVE32-NEXT: ret void
;
; OPT-WAVE64-LABEL: define amdgpu_kernel void @s_cluster_barrier_wg32(
-; OPT-WAVE64-SAME: ) #[[ATTR1]] {
+; OPT-WAVE64-SAME: ) #[[ATTR1:[0-9]+]] {
; OPT-WAVE64-NEXT: call void @llvm.amdgcn.wave.barrier()
; OPT-WAVE64-NEXT: call void @llvm.amdgcn.s.barrier.signal(i32 -3)
; OPT-WAVE64-NEXT: call void @llvm.amdgcn.s.barrier.wait(i16 -3)
diff --git a/llvm/test/MC/AMDGPU/gfx12_err.s b/llvm/test/MC/AMDGPU/gfx12_err.s
index 500fe0bf0d8d9..b4b08dbf677d1 100644
--- a/llvm/test/MC/AMDGPU/gfx12_err.s
+++ b/llvm/test/MC/AMDGPU/gfx12_err.s
@@ -683,3 +683,6 @@ s_wait_event { dont_wait_export_ready: 1 }
s_wait_event { dont_wait_export_ready: 0 }
// GFX12-ERR: :[[@LINE-1]]:16: error: unknown field
+
+s_barrier_signal_isfirst -3
+// GFX12-ERR: :[[@LINE-1]]:26: error: s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)
diff --git a/llvm/test/MC/AMDGPU/gfx13_err.s b/llvm/test/MC/AMDGPU/gfx13_err.s
new file mode 100644
index 0000000000000..5062f996a1584
--- /dev/null
+++ b/llvm/test/MC/AMDGPU/gfx13_err.s
@@ -0,0 +1,5 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 6
+// RUN: not llvm-mc -triple=amdgpu13.10 -filetype=null %s 2>&1 | FileCheck --check-prefixes=GFX12-ERR --implicit-check-not=error: -strict-whitespace %s
+
+s_barrier_signal_isfirst -3
+// GFX12-ERR: :[[@LINE-1]]:26: error: s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)
More information about the llvm-branch-commits
mailing list