[llvm] [AMDGPU] s_monitor_sleep shall not use sleep_forever on gfx1250 (PR #220366)

Stanislav Mekhanoshin via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 1 13:53:07 PDT 2026


https://github.com/rampitec updated https://github.com/llvm/llvm-project/pull/220366

>From 9c6f8de38e2da45f879bef6468c26de00f79c577 Mon Sep 17 00:00:00 2001
From: Stanislav Mekhanoshin <Stanislav.Mekhanoshin at amd.com>
Date: Tue, 1 Sep 2026 13:15:17 -0700
Subject: [PATCH] [AMDGPU] s_monitor_sleep shall not use sleep_forever on
 gfx1250

Fixes: SWDEV-542848
---
 llvm/lib/Target/AMDGPU/AMDGPU.td              |  7 +++
 .../Target/AMDGPU/AMDGPULowerIntrinsics.cpp   | 23 +++++++
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp      | 21 +++++++
 .../AMDGPU/llvm.amdgcn.s.monitor.sleep.ll     |  9 ++-
 llvm/test/MC/AMDGPU/gfx1250_asm_sopp.s        | 63 ++++++++++---------
 llvm/test/MC/AMDGPU/gfx1250_asm_sopp_err.s    |  3 +
 6 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index dff41c7794a3d..dc559a4523a9c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -1603,6 +1603,11 @@ defm NeedsAligned2addrDS : AMDGPUSubtargetFeature<"needs-aligned-2addr-lds",
   /*GenPredicate=*/1
 >;
 
+defm NoSleepForever : AMDGPUSubtargetFeature<"no-sleep-forever",
+  "s_monitor_sleep should not use sleep_forever",
+  /*GenPredicate=*/1
+>;
+
 //===----------------------------------------------------------------------===//
 
 class GCNSubtargetFeatureGeneration <string Value,
@@ -2472,6 +2477,7 @@ def FeatureISAVersion12_50_STRICT : FeatureSet<
    FeatureRequiresInitialUnclausedVmem,
    FeatureNeedsTDMDrain,
    FeatureNeedsAligned2addrDS,
+   FeatureNoSleepForever,
    ])>;
 
 def FeatureISAVersion12_50 : FeatureSet<
@@ -2497,6 +2503,7 @@ def FeatureISAVersion12_50 : FeatureSet<
    FeatureDataCacheLineSize128,
    FeatureRequiresInitialUnclausedVmem,
    FeatureNeedsTDMDrain,
+   FeatureNoSleepForever,
    ])>;
 
 def FeatureISAVersion12_51 : FeatureSet<
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
index 123d9930fc49e..1fe9b1dc88a23 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerIntrinsics.cpp
@@ -39,6 +39,7 @@ class AMDGPULowerIntrinsicsImpl {
 private:
   bool visitBarrier(IntrinsicInst &I);
   bool visitPtrSBufferLoad(IntrinsicInst &I);
+  bool visitMonitorSleep(IntrinsicInst &I);
 };
 
 class AMDGPULowerIntrinsicsLegacy : public ModulePass {
@@ -81,6 +82,10 @@ bool AMDGPULowerIntrinsicsImpl::run() {
       forEachCall(
           F, [&](IntrinsicInst *II) { Changed |= visitPtrSBufferLoad(*II); });
       break;
+    case Intrinsic::amdgcn_s_monitor_sleep:
+      forEachCall(
+          F, [&](IntrinsicInst *II) { Changed |= visitMonitorSleep(*II); });
+      break;
     }
   }
 
@@ -209,6 +214,24 @@ bool AMDGPULowerIntrinsicsImpl::visitPtrSBufferLoad(IntrinsicInst &I) {
   return true;
 }
 
+bool AMDGPULowerIntrinsicsImpl::visitMonitorSleep(IntrinsicInst &I) {
+  assert(I.getIntrinsicID() == Intrinsic::amdgcn_s_monitor_sleep);
+
+  const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(*I.getFunction());
+  if (!ST.hasNoSleepForever())
+    return false;
+
+  int Sleep = cast<ConstantInt>(I.getArgOperand(0))->getSExtValue();
+  if (!(Sleep & 0x8000))
+    return false;
+
+  IRBuilder<> B(&I);
+  Value *NewSleep = B.getInt16(0x2000); // Maximum
+  I.setArgOperand(0, NewSleep);
+
+  return true;
+}
+
 PreservedAnalyses AMDGPULowerIntrinsicsPass::run(Module &M,
                                                  ModuleAnalysisManager &MAM) {
   AMDGPULowerIntrinsicsImpl Impl(M, TM);
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 81bcc4ffaa286..0eab7c7be254b 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -1864,6 +1864,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
   bool validateTFE(const MCInst &Inst, const OperandVector &Operands);
   bool validateLdsDirect(const MCInst &Inst, const OperandVector &Operands);
   bool validateWMMA(const MCInst &Inst, const OperandVector &Operands);
+  bool validateMonitorSleep(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;
@@ -5585,6 +5586,23 @@ bool AMDGPUAsmParser::validateWMMA(const MCInst &Inst,
   return true;
 }
 
+bool AMDGPUAsmParser::validateMonitorSleep(const MCInst &Inst,
+                                           const OperandVector &Operands) {
+  unsigned Opc = Inst.getOpcode();
+  if (Opc != AMDGPU::S_MONITOR_SLEEP_gfx12 ||
+      !getSTI().hasFeature(AMDGPU::FeatureNoSleepForever))
+    return true;
+
+  int ImmIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::simm16);
+  if (Inst.getOperand(ImmIdx).getImm() & 0x8000) {
+    Error(getOperandLoc(Operands, ImmIdx),
+          "sleep forever is unsuported on the target");
+    return false;
+  }
+
+  return true;
+}
+
 bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, SMLoc IDLoc,
                                           const OperandVector &Operands) {
   if (!validateLdsDirect(Inst, Operands))
@@ -5716,6 +5734,9 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, SMLoc IDLoc,
   if (!validateWMMA(Inst, Operands)) {
     return false;
   }
+  if (!validateMonitorSleep(Inst, Operands)) {
+    return false;
+  }
 
   return true;
 }
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.monitor.sleep.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.monitor.sleep.ll
index 703ed25951394..4bddedbbf3582 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.monitor.sleep.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.s.monitor.sleep.ll
@@ -1,5 +1,7 @@
-; RUN: llc -global-isel=0 -mtriple=amdgpu12.50 < %s | FileCheck --check-prefix=GCN %s
-; RUN: llc -global-isel=1 -mtriple=amdgpu12.50 < %s | FileCheck --check-prefix=GCN %s
+; RUN: llc -global-isel=0 -mtriple=amdgpu12.50 < %s | FileCheck --check-prefixes=GCN,GFX1250 %s
+; RUN: llc -global-isel=1 -mtriple=amdgpu12.50 < %s | FileCheck --check-prefixes=GCN,GFX1250 %s
+; RUN: llc -global-isel=0 -mtriple=amdgpu12.51 < %s | FileCheck --check-prefixes=GCN,GFX1251 %s
+; RUN: llc -global-isel=1 -mtriple=amdgpu12.51 < %s | FileCheck --check-prefixes=GCN,GFX1251 %s
 
 declare void @llvm.amdgcn.s.monitor.sleep(i16)
 
@@ -13,7 +15,8 @@ define amdgpu_ps void @test_monitor_sleep_1() {
 ; FIXME: 0x8000 would look better
 
 ; GCN-LABEL: {{^}}test_monitor_sleep_forever:
-; GCN: s_monitor_sleep 0xffff8000
+; GFX1250: s_monitor_sleep 0x2000
+; GFX1251: s_monitor_sleep 0xffff8000
 define amdgpu_ps void @test_monitor_sleep_forever() {
   call void @llvm.amdgcn.s.monitor.sleep(i16 32768)
   ret void
diff --git a/llvm/test/MC/AMDGPU/gfx1250_asm_sopp.s b/llvm/test/MC/AMDGPU/gfx1250_asm_sopp.s
index b6bb9e761a2fc..4a94d9063b5c0 100644
--- a/llvm/test/MC/AMDGPU/gfx1250_asm_sopp.s
+++ b/llvm/test/MC/AMDGPU/gfx1250_asm_sopp.s
@@ -1,73 +1,74 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 6
 // RUN: llvm-mc -triple=amdgpu12.50 -show-encoding %s | FileCheck --check-prefix=GFX1250 %s
 // RUN: not llvm-mc -triple=amdgpu12.00 -filetype=null %s 2>&1 | FileCheck --check-prefixes=GFX12-ERR --implicit-check-not=error: -strict-whitespace %s
 
 s_wait_asynccnt 0x1234
-// GFX1250: [0x34,0x12,0xca,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_asynccnt
+// GFX1250: s_wait_asynccnt 0x1234                  ; encoding: [0x34,0x12,0xca,0xbf]
 
 s_wait_asynccnt 0xc1d1
-// GFX1250: [0xd1,0xc1,0xca,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_asynccnt
+// GFX1250: s_wait_asynccnt 0xc1d1                  ; encoding: [0xd1,0xc1,0xca,0xbf]
 
 s_wait_tensorcnt 0x0
-// GFX1250: [0x00,0x00,0xcb,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_tensorcnt
+// GFX1250: s_wait_tensorcnt 0x0                    ; encoding: [0x00,0x00,0xcb,0xbf]
 
 s_wait_tensorcnt 0x1
-// GFX1250: [0x01,0x00,0xcb,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_tensorcnt
+// GFX1250: s_wait_tensorcnt 0x1                    ; encoding: [0x01,0x00,0xcb,0xbf]
 
 s_wait_tensorcnt 0x3
-// GFX1250: [0x03,0x00,0xcb,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_tensorcnt
+// GFX1250: s_wait_tensorcnt 0x3                    ; encoding: [0x03,0x00,0xcb,0xbf]
 
 s_wait_xcnt 0x0
-// GFX1250: [0x00,0x00,0xc5,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_xcnt
+// GFX1250: s_wait_xcnt 0x0                         ; encoding: [0x00,0x00,0xc5,0xbf]
 
 s_wait_xcnt 0x7
-// GFX1250: [0x07,0x00,0xc5,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_xcnt
+// GFX1250: s_wait_xcnt 0x7                         ; encoding: [0x07,0x00,0xc5,0xbf]
 
 s_wait_xcnt 0xf
-// GFX1250: [0x0f,0x00,0xc5,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_wait_xcnt
+// GFX1250: s_wait_xcnt 0xf                         ; encoding: [0x0f,0x00,0xc5,0xbf]
 
 s_setprio_inc_wg 100
-// GFX1250: [0x64,0x00,0xbe,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_setprio_inc_wg
+// GFX1250: s_setprio_inc_wg 0x64                   ; encoding: [0x64,0x00,0xbe,0xbf]
 
 s_set_vgpr_msb 10
-// GFX1250: [0x0a,0x00,0x86,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_set_vgpr_msb
+// GFX1250: s_set_vgpr_msb 10                       ; encoding: [0x0a,0x00,0x86,0xbf]
 
 s_set_vgpr_msb 255
-// GFX1250: [0xff,0x00,0x86,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_set_vgpr_msb
+// GFX1250: s_set_vgpr_msb 0xff                     ; encoding: [0xff,0x00,0x86,0xbf]
 
 s_set_vgpr_msb 0xffff
-// GFX1250: [0xff,0xff,0x86,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_set_vgpr_msb
+// GFX1250: s_set_vgpr_msb 0xffff                   ; encoding: [0xff,0xff,0x86,0xbf]
 
 s_monitor_sleep 1
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_monitor_sleep
 // GFX1250: s_monitor_sleep 1                       ; encoding: [0x01,0x00,0x84,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
 
-s_monitor_sleep 32768
-// GFX1250: s_monitor_sleep 0x8000                  ; encoding: [0x00,0x80,0x84,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
+s_monitor_sleep 0x2000
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_monitor_sleep
+// GFX1250: s_monitor_sleep 0x2000                  ; encoding: [0x00,0x20,0x84,0xbf]
 
 s_monitor_sleep 0
+// GFX12-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1200): s_monitor_sleep
 // GFX1250: s_monitor_sleep 0                       ; encoding: [0x00,0x00,0x84,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: instruction not supported on this GPU
 
 s_sendmsg_rtn_b32 s1, sendmsg(MSG_RTN_SAVE_WAVE_HAS_TDM)     ; encoding: [0x0a,0x00,0xb6,0xbf]
+// GFX12-ERR: :[[@LINE-1]]:31: error: specified message id is not supported on this GPU
 // GFX1250: s_sendmsg_rtn_b32 s1, sendmsg(MSG_RTN_SAVE_WAVE_HAS_TDM) ; encoding: [0x98,0x4c,0x81,0xbe]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: specified message id is not supported on this GPU
 
 s_sendmsg sendmsg(MSG_RTN_SAVE_WAVE_HAS_TDM)     ; encoding: [0x0a,0x00,0xb6,0xbf]
+// GFX12-ERR: :[[@LINE-1]]:19: error: specified message id is not supported on this GPU
 // GFX1250: s_sendmsg sendmsg(MSG_RTN_SAVE_WAVE_HAS_TDM) ; encoding: [0x98,0x00,0xb6,0xbf]
-// GFX12-ERR: :[[@LINE-2]]:{{[0-9]+}}: error: specified message id is not supported on this GPU
 
 s_barrier_wait -3
 // GFX1250: s_barrier_wait -3                       ; encoding: [0xfd,0xff,0x94,0xbf]
diff --git a/llvm/test/MC/AMDGPU/gfx1250_asm_sopp_err.s b/llvm/test/MC/AMDGPU/gfx1250_asm_sopp_err.s
index 3a965fdef4323..3c3a749241895 100644
--- a/llvm/test/MC/AMDGPU/gfx1250_asm_sopp_err.s
+++ b/llvm/test/MC/AMDGPU/gfx1250_asm_sopp_err.s
@@ -1,5 +1,8 @@
 // NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --unique --sort --version 6
 // RUN: not llvm-mc -triple=amdgpu12.50 -filetype=null %s 2>&1 | FileCheck --check-prefixes=GFX1250-ERR --implicit-check-not=error: -strict-whitespace %s
 
+s_monitor_sleep 32768
+// GFX1250-ERR: :[[@LINE-1]]:17: error: sleep forever is unsuported on the target
+
 s_setkill 0
 // GFX1250-ERR: :[[@LINE-1]]:1: error: instruction not supported on this GPU (gfx1250): s_setkill



More information about the llvm-commits mailing list