[llvm] [AMDGPU] Handle register variant S_SETREG when fixing VGPR MSB clobbers (PR #218941)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 00:38:41 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/218941
>From 28978216727bce793531a1508cf5c25e01589653 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 26 Aug 2026 16:22:28 +0200
Subject: [PATCH 1/4] [AMDGPU] Handle register variant S_SETREG when fixing
VGPR MSB clobbers
Its value is unknown at compile time, so the clobbered VGPR MSBs must always be restored
---
.../Target/AMDGPU/AMDGPULowerVGPREncoding.cpp | 49 ++++---
.../lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 19 +--
llvm/lib/Target/AMDGPU/SIInstrInfo.h | 13 ++
.../CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll | 27 ++++
.../CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir | 122 ++++++++++++++++++
5 files changed, 199 insertions(+), 31 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
index 75c3dd3b1de09..ccacca66f5fcf 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
@@ -197,20 +197,24 @@ class AMDGPULowerVGPREncoding {
MachineBasicBlock::instr_iterator
handleCoissue(MachineBasicBlock::instr_iterator I);
- /// S_SET_VGPR_MSB immediately after S_SETREG_IMM32_B32 targeting MODE is
+ /// S_SET_VGPR_MSB immediately after an S_SETREG variant targeting MODE is
/// silently dropped on GFX1250. When set, the next S_SET_VGPR_MSB insertion
/// must be preceded by S_NOP to avoid the hazard.
bool needNopBeforeSetVGPRMSB(MachineBasicBlock::instr_iterator I);
- /// Handle S_SETREG_IMM32_B32 targeting MODE register. On certain hardware,
+ /// Handle an S_SETREG variant targeting MODE register. On certain hardware,
/// this instruction clobbers VGPR MSB bits[12:19], so we need to restore
/// the current mode. \returns true if the instruction was modified or a
/// new one was inserted.
bool handleSetregMode(MachineInstr &MI);
- /// Update bits[12:19] of the imm operand in S_SETREG_IMM32_B32 to contain
- /// the VGPR MSB mode value. \returns true if the immediate was changed.
+ /// Update bits[12:19] of the imm operand in an S_SETREG_IMM32_B32 variant to
+ /// contain the VGPR MSB mode value. \returns true if the immediate was
+ /// changed.
bool updateSetregModeImm(MachineInstr &MI, int64_t ModeValue);
+
+ /// Insert S_NOP + S_SET_VGPR_MSB restoring \p ModeValue after setreg \p MI.
+ void restoreModeAfterSetreg(MachineInstr &MI, int64_t ModeValue);
};
bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode,
@@ -433,9 +437,9 @@ AMDGPULowerVGPREncoding::handleCoissue(MachineBasicBlock::instr_iterator I) {
return I;
}
-/// Returns whether \p MI is a S_SETREG_IMM32_B32(MODE).
+/// Returns whether \p MI is an S_SETREG variant targeting MODE.
static bool isSetregMode(const MachineInstr &MI, const SIInstrInfo &TII) {
- if (MI.getOpcode() != AMDGPU::S_SETREG_IMM32_B32)
+ if (!SIInstrInfo::isSSetReg(MI.getOpcode()))
return false;
const MachineOperand *SIMM16Op =
@@ -460,7 +464,7 @@ bool AMDGPULowerVGPREncoding::needNopBeforeSetVGPRMSB(
}
// Look for a potential fallthrough predecessor block. When it ends with a
- // S_SETREG_IMM32_B32(MODE) we need to insert a S_NOP too. We assume that an
+ // setreg targeting MODE we need to insert a S_NOP too. We assume that an
// explicit jump to the current block from the block that would otherwise
// have naturally fallen through to it will remain in the final assembly.
CurrentMBB = CurrentMBB->getPrevNode();
@@ -482,7 +486,8 @@ static int64_t convertModeToSetregFormat(int64_t Mode) {
bool AMDGPULowerVGPREncoding::updateSetregModeImm(MachineInstr &MI,
int64_t ModeValue) {
- assert(MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32);
+ assert(MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
+ MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32_mode);
// Convert from S_SET_VGPR_MSB format to MODE register format
int64_t SetregMode = convertModeToSetregFormat(ModeValue);
@@ -499,8 +504,8 @@ bool AMDGPULowerVGPREncoding::updateSetregModeImm(MachineInstr &MI,
bool AMDGPULowerVGPREncoding::handleSetregMode(MachineInstr &MI) {
using namespace AMDGPU::Hwreg;
- assert(MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 &&
- "only S_SETREG_IMM32_B32 needs to be handled");
+ assert(SIInstrInfo::isSSetReg(MI.getOpcode()) &&
+ "expected an S_SETREG variant");
LLVM_DEBUG(dbgs() << " handleSetregMode: " << MI);
@@ -526,6 +531,14 @@ bool AMDGPULowerVGPREncoding::handleSetregMode(MachineInstr &MI) {
<< " VGPRMSBShift=" << VGPRMSBShift << '\n';
});
+ // Register variants write an SGPR to MODE, so the resulting VGPR MSBs are
+ // unknown at compile time.
+ if (MI.getOpcode() == AMDGPU::S_SETREG_B32 ||
+ MI.getOpcode() == AMDGPU::S_SETREG_B32_mode) {
+ restoreModeAfterSetreg(MI, ModeValue);
+ return true;
+ }
+
// Case 1: Size <= 12 - the original instruction uses imm32[0:Size-1], so
// imm32[12:19] is unused, or Offset is zero and it is safe to set
// imm32[12:19] to the correct VGPR MSBs.
@@ -555,10 +568,15 @@ bool AMDGPULowerVGPREncoding::handleSetregMode(MachineInstr &MI) {
return false;
}
- // imm32[12:19] doesn't match VGPR MSBs - insert s_set_vgpr_msb after
- // the original instruction to restore the correct value. Insert S_NOP
- // to avoid the GFX1250 hazard where S_SET_VGPR_MSB immediately after
- // S_SETREG_IMM32_B32(MODE) is silently dropped.
+ // imm32[12:19] doesn't match VGPR MSBs - restore the correct value after MI.
+ restoreModeAfterSetreg(MI, ModeValue);
+ return true;
+}
+
+void AMDGPULowerVGPREncoding::restoreModeAfterSetreg(MachineInstr &MI,
+ int64_t ModeValue) {
+ // S_NOP avoids the GFX1250 hazard: S_SET_VGPR_MSB right after a MODE setreg
+ // is silently dropped.
MachineBasicBlock::iterator InsertPt = std::next(MI.getIterator());
BuildMI(*MBB, InsertPt, MI.getDebugLoc(), TII->get(AMDGPU::S_NOP)).addImm(0);
MostRecentModeSet = BuildMI(*MBB, InsertPt, MI.getDebugLoc(),
@@ -566,7 +584,6 @@ bool AMDGPULowerVGPREncoding::handleSetregMode(MachineInstr &MI) {
.addImm(ModeValue | (ModeValue << ModeWidth));
LLVM_DEBUG(dbgs() << " -> inserted S_SET_VGPR_MSB after setreg: "
<< *MostRecentModeSet);
- return true;
}
bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
@@ -623,7 +640,7 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
continue;
}
- if (MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 &&
+ if (SIInstrInfo::isSSetReg(MI.getOpcode()) &&
ST.hasSetregVGPRMSBFixup()) {
Changed |= handleSetregMode(MI);
continue;
diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
index 9d01a529eb012..3c0d9656dc4ab 100644
--- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
@@ -459,17 +459,6 @@ static bool isSGetReg(unsigned Opcode) {
return Opcode == AMDGPU::S_GETREG_B32 || Opcode == AMDGPU::S_GETREG_B32_const;
}
-static bool isSSetReg(unsigned Opcode) {
- switch (Opcode) {
- case AMDGPU::S_SETREG_B32:
- case AMDGPU::S_SETREG_B32_mode:
- case AMDGPU::S_SETREG_IMM32_B32:
- case AMDGPU::S_SETREG_IMM32_B32_mode:
- return true;
- }
- return false;
-}
-
static bool isRWLane(unsigned Opcode) {
return Opcode == AMDGPU::V_READLANE_B32 || Opcode == AMDGPU::V_WRITELANE_B32;
}
@@ -615,7 +604,7 @@ GCNHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
if (isSGetReg(MI->getOpcode()) && checkGetRegHazards(MI) > 0)
return HazardType;
- if (isSSetReg(MI->getOpcode()) && checkSetRegHazards(MI) > 0)
+ if (SIInstrInfo::isSSetReg(MI->getOpcode()) && checkSetRegHazards(MI) > 0)
return HazardType;
if (isRFE(MI->getOpcode()) && checkRFEHazards(MI) > 0)
@@ -773,7 +762,7 @@ unsigned GCNHazardRecognizer::PreEmitNoopsCommon(MachineInstr *MI) const {
if (isSGetReg(MI->getOpcode()))
return std::max(WaitStates, checkGetRegHazards(MI));
- if (isSSetReg(MI->getOpcode()))
+ if (SIInstrInfo::isSSetReg(MI->getOpcode()))
return std::max(WaitStates, checkSetRegHazards(MI));
if (isRFE(MI->getOpcode()))
@@ -1094,7 +1083,7 @@ int GCNHazardRecognizer::getWaitStatesSinceDef(unsigned Reg,
int GCNHazardRecognizer::getWaitStatesSinceSetReg(IsHazardFn IsHazard,
int Limit) const {
auto IsHazardFn = [IsHazard](const MachineInstr &MI) {
- return isSSetReg(MI.getOpcode()) && IsHazard(MI);
+ return SIInstrInfo::isSSetReg(MI.getOpcode()) && IsHazard(MI);
};
return getWaitStatesSince(IsHazardFn, Limit);
@@ -4300,7 +4289,7 @@ bool GCNHazardRecognizer::fixScratchBaseForwardingHazard(MachineInstr *MI) {
}
bool GCNHazardRecognizer::fixSetRegMode(MachineInstr *MI) {
- if (!isSSetReg(MI->getOpcode()) ||
+ if (!SIInstrInfo::isSSetReg(MI->getOpcode()) ||
MI->getOperand(1).getImm() != AMDGPU::Hwreg::ID_MODE)
return false;
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index a62a753b41b08..b49524be99c98 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -1252,6 +1252,19 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
}
}
+ /// \returns true if \p Opcode is any S_SETREG_B32/S_SETREG_IMM32_B32 variant.
+ static bool isSSetReg(unsigned Opcode) {
+ switch (Opcode) {
+ case AMDGPU::S_SETREG_B32:
+ case AMDGPU::S_SETREG_B32_mode:
+ case AMDGPU::S_SETREG_IMM32_B32:
+ case AMDGPU::S_SETREG_IMM32_B32_mode:
+ return true;
+ default:
+ return false;
+ }
+ }
+
bool isVGPRCopy(const MachineInstr &MI) const {
assert(isCopyInstr(MI));
Register Dest = MI.getOperand(0).getReg();
diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
new file mode 100644
index 0000000000000..ab53e3fa6f19c
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck %s
+
+; llvm.set.rounding lowers to s_setreg_b32(MODE), leaving garbage in
+; bits[19:12] of the SGPR operand, so the tracked mode must be re-established.
+
+declare void @llvm.set.rounding(i32)
+
+; CHECK-LABEL: {{^}}dynamic_rounding_mode_with_high_vgprs:
+; CHECK: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+; CHECK-NEXT: s_nop 0
+; CHECK-NEXT: s_set_vgpr_msb 0x4141
+define amdgpu_kernel void @dynamic_rounding_mode_with_high_vgprs(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %mode) #0 {
+ %a = load volatile <64 x float>, ptr addrspace(1) %p
+ %b = load volatile <64 x float>, ptr addrspace(1) %p
+ %c = load volatile <64 x float>, ptr addrspace(1) %p
+ %d = load volatile <64 x float>, ptr addrspace(1) %p
+ %e = load volatile <64 x float>, ptr addrspace(1) %p
+ store volatile <64 x float> %a, ptr addrspace(1) %q
+ call void @llvm.set.rounding(i32 %mode)
+ %sum = call <64 x float> @llvm.experimental.constrained.fadd.v64f32(<64 x float> %b, <64 x float> %c, metadata !"round.dynamic", metadata !"fpexcept.strict")
+ store volatile <64 x float> %sum, ptr addrspace(1) %q
+ store volatile <64 x float> %d, ptr addrspace(1) %q
+ store volatile <64 x float> %e, ptr addrspace(1) %q
+ ret void
+}
+
+attributes #0 = { strictfp "amdgpu-flat-work-group-size"="1,32" "amdgpu-waves-per-eu"="1,1" }
diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir
index b9c3cdb3db45f..b0a0143325f07 100644
--- a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir
+++ b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir
@@ -517,3 +517,125 @@ body: |
S_SETREG_IMM32_B32 23228, 30785, implicit-def $mode, implicit $mode
S_ENDPGM 0
...
+
+---
+# S_SETREG_IMM32_B32_mode clobbers VGPR MSBs the same way as S_SETREG_IMM32_B32.
+
+# ASM-LABEL: {{^}}setreg_imm32_mode_variant:
+# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x5005
+
+# DIS-LABEL: <setreg_imm32_mode_variant>:
+# DIS: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x5005
+# DIS-NEXT: v_mov_b32_e32 v2 /*v258*/, v3 /*v259*/
+
+name: setreg_imm32_mode_variant
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: setreg_imm32_mode_variant
+ ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode
+ ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; CHECK-NEXT: S_SETREG_IMM32_B32_mode 20485, 6145, implicit-def $mode, implicit $mode
+ ; CHECK-NEXT: $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145
+ S_SETREG_IMM32_B32_mode 5, 6145, implicit-def $mode, implicit $mode
+ $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ S_ENDPGM 0
+...
+
+---
+# Register variants write an SGPR to MODE, so the VGPR MSBs are unknown at
+# compile time and must always be restored.
+
+# ASM-LABEL: {{^}}setreg_sgpr:
+# ASM: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+# ASM-NEXT: s_nop 0
+# ASM-NEXT: s_set_vgpr_msb 0x4141
+
+# DIS-LABEL: <setreg_sgpr>:
+# DIS: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+# DIS-NEXT: s_nop 0
+# DIS-NEXT: s_set_vgpr_msb 0x4141
+# DIS-NEXT: v_mov_b32_e32 v2 /*v258*/, v3 /*v259*/
+
+name: setreg_sgpr
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: setreg_sgpr
+ ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode
+ ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; CHECK-NEXT: S_SETREG_B32 $sgpr0, 6145, implicit-def $mode, implicit $mode
+ ; CHECK-NEXT: S_NOP 0
+ ; CHECK-NEXT: S_SET_VGPR_MSB 16705, implicit-def $mode
+ ; CHECK-NEXT: $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145
+ S_SETREG_B32 $sgpr0, 6145, implicit-def $mode, implicit $mode
+ $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ S_ENDPGM 0
+...
+
+---
+# ASM-LABEL: {{^}}setreg_sgpr_mode_variant:
+# ASM: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+# ASM-NEXT: s_nop 0
+# ASM-NEXT: s_set_vgpr_msb 0x4141
+
+# DIS-LABEL: <setreg_sgpr_mode_variant>:
+# DIS: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+# DIS-NEXT: s_nop 0
+# DIS-NEXT: s_set_vgpr_msb 0x4141
+# DIS-NEXT: v_mov_b32_e32 v2 /*v258*/, v3 /*v259*/
+
+name: setreg_sgpr_mode_variant
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: setreg_sgpr_mode_variant
+ ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode
+ ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; CHECK-NEXT: S_SETREG_B32_mode $sgpr0, 6145, implicit-def $mode, implicit $mode
+ ; CHECK-NEXT: S_NOP 0
+ ; CHECK-NEXT: S_SET_VGPR_MSB 16705, implicit-def $mode
+ ; CHECK-NEXT: $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145
+ S_SETREG_B32_mode $sgpr0, 6145, implicit-def $mode, implicit $mode
+ $vgpr258 = V_MOV_B32_e32 $vgpr259, implicit $exec
+ S_ENDPGM 0
+...
+
+---
+# A non-MODE register setreg must be left alone.
+
+# ASM-LABEL: {{^}}setreg_sgpr_non_mode:
+# ASM: s_setreg_b32 hwreg(HW_REG_WAVE_STATUS, 0, 4), s0
+# ASM-NOT: s_set_vgpr_msb
+# ASM: s_endpgm
+
+# DIS-LABEL: <setreg_sgpr_non_mode>:
+# DIS: s_setreg_b32 hwreg(HW_REG_WAVE_STATUS, 0, 4), s0
+# DIS-NEXT: s_endpgm
+
+name: setreg_sgpr_non_mode
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0
+ ; CHECK-LABEL: name: setreg_sgpr_non_mode
+ ; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode
+ ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; CHECK-NEXT: S_SETREG_B32 $sgpr0, 6146, implicit-def $mode, implicit $mode
+ ; CHECK-NEXT: S_ENDPGM 0
+ $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
+ ; size=4, offset=0, hwreg=STATUS: simm16 = 0x1802 = 6146
+ S_SETREG_B32 $sgpr0, 6146, implicit-def $mode, implicit $mode
+ S_ENDPGM 0
+...
>From d66ae6c75b003b75b60e6578c3b80c8e6f587970 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 26 Aug 2026 21:41:59 +0200
Subject: [PATCH 2/4] comments part 1
---
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 7 +++----
llvm/lib/Target/AMDGPU/SIModeRegister.cpp | 5 +----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index bc419d813f171..d26ed603efce6 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -3597,15 +3597,14 @@ bool SIInstrInfo::isXcntDrain(const MachineInstr &MI) {
if (MI.isBranch() || MI.isCall() || MI.isReturn() || MI.isIndirectBranch())
return true;
+ if (isSSetReg(MI.getOpcode()))
+ return true;
+
switch (MI.getOpcode()) {
case AMDGPU::S_ENDPGM:
case AMDGPU::S_ENDPGM_SAVED:
case AMDGPU::S_TRAP:
case AMDGPU::S_GETREG_B32:
- case AMDGPU::S_SETREG_B32:
- case AMDGPU::S_SETREG_B32_mode:
- case AMDGPU::S_SETREG_IMM32_B32:
- case AMDGPU::S_SETREG_IMM32_B32_mode:
case AMDGPU::S_SENDMSG:
case AMDGPU::S_SENDMSGHALT:
case AMDGPU::S_SENDMSG_RTN_B32:
diff --git a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
index f9b33b4175c2f..98d245c2390cd 100644
--- a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
+++ b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
@@ -273,10 +273,7 @@ void SIModeRegister::processBlockPhase1(MachineBasicBlock &MBB,
Status IPChange;
for (MachineInstr &MI : MBB) {
Status InstrMode = getInstructionMode(MI, TII);
- if (MI.getOpcode() == AMDGPU::S_SETREG_B32 ||
- MI.getOpcode() == AMDGPU::S_SETREG_B32_mode ||
- MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
- MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32_mode) {
+ if (SIInstrInfo::isSSetReg(MI.getOpcode())) {
// We preserve any explicit mode register setreg instruction we encounter,
// as we assume it has been inserted by a higher authority (this is
// likely to be a very rare occurrence).
>From 8d8ced814ccdf0736efe5b6893b8ff8a170a15d2 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 27 Aug 2026 06:13:27 +0200
Subject: [PATCH 3/4] comments part 2
---
.../CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll | 408 +++++++++++++++++-
1 file changed, 401 insertions(+), 7 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
index ab53e3fa6f19c..fbeba56244ac7 100644
--- a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
+++ b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
@@ -1,15 +1,409 @@
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=amdgpu12.50-amd-amdhsa < %s | FileCheck %s
; llvm.set.rounding lowers to s_setreg_b32(MODE), leaving garbage in
; bits[19:12] of the SGPR operand, so the tracked mode must be re-established.
-declare void @llvm.set.rounding(i32)
-
-; CHECK-LABEL: {{^}}dynamic_rounding_mode_with_high_vgprs:
-; CHECK: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
-; CHECK-NEXT: s_nop 0
-; CHECK-NEXT: s_set_vgpr_msb 0x4141
define amdgpu_kernel void @dynamic_rounding_mode_with_high_vgprs(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %mode) #0 {
+; CHECK-LABEL: dynamic_rounding_mode_with_high_vgprs:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_mov_b64 s[64:65], 0
+; CHECK-NEXT: v_nop
+; CHECK-NEXT: global_prefetch_b8 v0, s[64:65] scope:SCOPE_SE
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: s_set_vgpr_msb 64 ; msbs: dst=1 src0=0 src1=0 src2=0
+; CHECK-NEXT: v_mov_b32_e32 v64 /*v320*/, 0
+; CHECK-NEXT: s_set_vgpr_msb 0x4001 ; msbs: dst=0 src0=1 src1=0 src2=0
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: global_load_b128 v[0:3], v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[4:7], v64 /*v320*/, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[8:11], v64 /*v320*/, s[0:1] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[12:15], v64 /*v320*/, s[0:1] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[16:19], v64 /*v320*/, s[0:1] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[20:23], v64 /*v320*/, s[0:1] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[24:27], v64 /*v320*/, s[0:1] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[28:31], v64 /*v320*/, s[0:1] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[32:35], v64 /*v320*/, s[0:1] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[36:39], v64 /*v320*/, s[0:1] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[40:43], v64 /*v320*/, s[0:1] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[44:47], v64 /*v320*/, s[0:1] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[48:51], v64 /*v320*/, s[0:1] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[52:55], v64 /*v320*/, s[0:1] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[56:59], v64 /*v320*/, s[0:1] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[60:63], v64 /*v320*/, s[0:1] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[64:67], v64 /*v320*/, s[0:1] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[68:71], v64 /*v320*/, s[0:1] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[72:75], v64 /*v320*/, s[0:1] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[76:79], v64 /*v320*/, s[0:1] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[80:83], v64 /*v320*/, s[0:1] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[84:87], v64 /*v320*/, s[0:1] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[88:91], v64 /*v320*/, s[0:1] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[92:95], v64 /*v320*/, s[0:1] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[96:99], v64 /*v320*/, s[0:1] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[100:103], v64 /*v320*/, s[0:1] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[104:107], v64 /*v320*/, s[0:1] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[108:111], v64 /*v320*/, s[0:1] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[112:115], v64 /*v320*/, s[0:1] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[116:119], v64 /*v320*/, s[0:1] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[120:123], v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[124:127], v64 /*v320*/, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[128:131], v64 /*v320*/, s[0:1] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[132:135], v64 /*v320*/, s[0:1] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[136:139], v64 /*v320*/, s[0:1] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[140:143], v64 /*v320*/, s[0:1] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[144:147], v64 /*v320*/, s[0:1] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[148:151], v64 /*v320*/, s[0:1] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[152:155], v64 /*v320*/, s[0:1] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[156:159], v64 /*v320*/, s[0:1] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[160:163], v64 /*v320*/, s[0:1] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[164:167], v64 /*v320*/, s[0:1] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[168:171], v64 /*v320*/, s[0:1] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[172:175], v64 /*v320*/, s[0:1] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[176:179], v64 /*v320*/, s[0:1] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[180:183], v64 /*v320*/, s[0:1] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[184:187], v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[188:191], v64 /*v320*/, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[192:195], v64 /*v320*/, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[196:199], v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[200:203], v64 /*v320*/, s[0:1] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[204:207], v64 /*v320*/, s[0:1] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[208:211], v64 /*v320*/, s[0:1] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[212:215], v64 /*v320*/, s[0:1] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[216:219], v64 /*v320*/, s[0:1] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[220:223], v64 /*v320*/, s[0:1] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[224:227], v64 /*v320*/, s[0:1] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[228:231], v64 /*v320*/, s[0:1] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[232:235], v64 /*v320*/, s[0:1] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[236:239], v64 /*v320*/, s[0:1] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[240:243], v64 /*v320*/, s[0:1] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[244:247], v64 /*v320*/, s[0:1] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[248:251], v64 /*v320*/, s[0:1] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[252:255], v64 /*v320*/, s[0:1] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_set_vgpr_msb 0x141 ; msbs: dst=1 src0=1 src1=0 src2=0
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[0:3] /*v[256:259]*/, v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[4:7] /*v[260:263]*/, v64 /*v320*/, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[8:11] /*v[264:267]*/, v64 /*v320*/, s[0:1] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[12:15] /*v[268:271]*/, v64 /*v320*/, s[0:1] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[16:19] /*v[272:275]*/, v64 /*v320*/, s[0:1] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[20:23] /*v[276:279]*/, v64 /*v320*/, s[0:1] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[24:27] /*v[280:283]*/, v64 /*v320*/, s[0:1] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[28:31] /*v[284:287]*/, v64 /*v320*/, s[0:1] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[32:35] /*v[288:291]*/, v64 /*v320*/, s[0:1] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[36:39] /*v[292:295]*/, v64 /*v320*/, s[0:1] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[40:43] /*v[296:299]*/, v64 /*v320*/, s[0:1] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[44:47] /*v[300:303]*/, v64 /*v320*/, s[0:1] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[48:51] /*v[304:307]*/, v64 /*v320*/, s[0:1] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[52:55] /*v[308:311]*/, v64 /*v320*/, s[0:1] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[56:59] /*v[312:315]*/, v64 /*v320*/, s[0:1] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_load_b128 v[60:63] /*v[316:319]*/, v64 /*v320*/, s[0:1] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_loadcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[60:63], s[2:3] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[56:59], s[2:3] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[52:55], s[2:3] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[48:51], s[2:3] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[44:47], s[2:3] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[40:43], s[2:3] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[36:39], s[2:3] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[32:35], s[2:3] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[28:31], s[2:3] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[24:27], s[2:3] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[20:23], s[2:3] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[16:19], s[2:3] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[12:15], s[2:3] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[8:11], s[2:3] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[4:7], s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[0:3], s[2:3] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_sleep_var 0x1801
+; CHECK-NEXT: s_set_vgpr_msb 0x4100 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: v_dual_add_f32 v63, v67, v131 :: v_dual_add_f32 v62, v66, v130
+; CHECK-NEXT: v_dual_add_f32 v61, v65, v129 :: v_dual_add_f32 v60, v64, v128
+; CHECK-NEXT: v_dual_add_f32 v53, v73, v137 :: v_dual_add_f32 v59, v71, v135
+; CHECK-NEXT: v_dual_add_f32 v58, v70, v134 :: v_dual_add_f32 v57, v69, v133
+; CHECK-NEXT: v_dual_add_f32 v56, v68, v132 :: v_dual_add_f32 v55, v75, v139
+; CHECK-NEXT: v_dual_add_f32 v54, v74, v138 :: v_dual_add_f32 v52, v72, v136
+; CHECK-NEXT: v_dual_add_f32 v45, v81, v145 :: v_dual_add_f32 v51, v79, v143
+; CHECK-NEXT: v_dual_add_f32 v50, v78, v142 :: v_dual_add_f32 v49, v77, v141
+; CHECK-NEXT: v_dual_add_f32 v48, v76, v140 :: v_dual_add_f32 v47, v83, v147
+; CHECK-NEXT: v_dual_add_f32 v46, v82, v146 :: v_dual_add_f32 v44, v80, v144
+; CHECK-NEXT: v_dual_add_f32 v3, v127, v191 :: v_dual_add_f32 v2, v126, v190
+; CHECK-NEXT: v_dual_add_f32 v1, v125, v189 :: v_dual_add_f32 v0, v124, v188
+; CHECK-NEXT: v_dual_add_f32 v7, v123, v187 :: v_dual_add_f32 v6, v122, v186
+; CHECK-NEXT: v_dual_add_f32 v5, v121, v185 :: v_dual_add_f32 v4, v120, v184
+; CHECK-NEXT: v_dual_add_f32 v11, v119, v183 :: v_dual_add_f32 v10, v118, v182
+; CHECK-NEXT: v_dual_add_f32 v9, v117, v181 :: v_dual_add_f32 v8, v116, v180
+; CHECK-NEXT: v_dual_add_f32 v15, v115, v179 :: v_dual_add_f32 v14, v114, v178
+; CHECK-NEXT: v_dual_add_f32 v13, v113, v177 :: v_dual_add_f32 v12, v112, v176
+; CHECK-NEXT: v_dual_add_f32 v19, v111, v175 :: v_dual_add_f32 v18, v110, v174
+; CHECK-NEXT: v_dual_add_f32 v17, v109, v173 :: v_dual_add_f32 v16, v108, v172
+; CHECK-NEXT: v_dual_add_f32 v23, v107, v171 :: v_dual_add_f32 v22, v106, v170
+; CHECK-NEXT: v_dual_add_f32 v21, v105, v169 :: v_dual_add_f32 v20, v104, v168
+; CHECK-NEXT: v_dual_add_f32 v27, v103, v167 :: v_dual_add_f32 v26, v102, v166
+; CHECK-NEXT: v_dual_add_f32 v25, v101, v165 :: v_dual_add_f32 v24, v100, v164
+; CHECK-NEXT: v_dual_add_f32 v31, v99, v163 :: v_dual_add_f32 v30, v98, v162
+; CHECK-NEXT: v_dual_add_f32 v29, v97, v161 :: v_dual_add_f32 v28, v96, v160
+; CHECK-NEXT: v_dual_add_f32 v35, v95, v159 :: v_dual_add_f32 v34, v94, v158
+; CHECK-NEXT: v_dual_add_f32 v33, v93, v157 :: v_dual_add_f32 v32, v92, v156
+; CHECK-NEXT: v_dual_add_f32 v39, v91, v155 :: v_dual_add_f32 v38, v90, v154
+; CHECK-NEXT: v_dual_add_f32 v37, v89, v153 :: v_dual_add_f32 v36, v88, v152
+; CHECK-NEXT: v_dual_add_f32 v43, v87, v151 :: v_dual_add_f32 v42, v86, v150
+; CHECK-NEXT: v_dual_add_f32 v41, v85, v149 :: v_dual_add_f32 v40, v84, v148
+; CHECK-NEXT: s_set_vgpr_msb 1 ; msbs: dst=0 src0=1 src1=0 src2=0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[60:63], s[2:3] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[56:59], s[2:3] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[52:55], s[2:3] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[48:51], s[2:3] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[44:47], s[2:3] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[40:43], s[2:3] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[36:39], s[2:3] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[32:35], s[2:3] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[28:31], s[2:3] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[24:27], s[2:3] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[20:23], s[2:3] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[16:19], s[2:3] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[12:15], s[2:3] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[8:11], s[2:3] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[4:7], s[2:3] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[0:3], s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[252:255], s[2:3] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[248:251], s[2:3] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[244:247], s[2:3] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[240:243], s[2:3] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[236:239], s[2:3] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[232:235], s[2:3] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[228:231], s[2:3] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[224:227], s[2:3] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[220:223], s[2:3] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[216:219], s[2:3] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[212:215], s[2:3] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[208:211], s[2:3] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[204:207], s[2:3] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[200:203], s[2:3] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[196:199], s[2:3] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[192:195], s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_set_vgpr_msb 0x105 ; msbs: dst=0 src0=1 src1=1 src2=0
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[60:63] /*v[316:319]*/, s[2:3] offset:224 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[56:59] /*v[312:315]*/, s[2:3] offset:240 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[52:55] /*v[308:311]*/, s[2:3] offset:192 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[48:51] /*v[304:307]*/, s[2:3] offset:208 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[44:47] /*v[300:303]*/, s[2:3] offset:160 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[40:43] /*v[296:299]*/, s[2:3] offset:176 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[36:39] /*v[292:295]*/, s[2:3] offset:128 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[32:35] /*v[288:291]*/, s[2:3] offset:144 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[28:31] /*v[284:287]*/, s[2:3] offset:96 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[24:27] /*v[280:283]*/, s[2:3] offset:112 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[20:23] /*v[276:279]*/, s[2:3] offset:64 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[16:19] /*v[272:275]*/, s[2:3] offset:80 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[12:15] /*v[268:271]*/, s[2:3] offset:32 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[8:11] /*v[264:267]*/, s[2:3] offset:48 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[4:7] /*v[260:263]*/, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[0:3] /*v[256:259]*/, s[2:3] offset:16 scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)
+; CHECK-NEXT: s_endpgm
%a = load volatile <64 x float>, ptr addrspace(1) %p
%b = load volatile <64 x float>, ptr addrspace(1) %p
%c = load volatile <64 x float>, ptr addrspace(1) %p
>From d206186001808b9c9bf0d1aa1d133b0e1fe41a90 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 27 Aug 2026 09:38:24 +0200
Subject: [PATCH 4/4] fix test
---
llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
index fbeba56244ac7..0f7d43cccef21 100644
--- a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
+++ b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.ll
@@ -14,6 +14,7 @@ define amdgpu_kernel void @dynamic_rounding_mode_with_high_vgprs(ptr addrspace(1
; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
; CHECK-NEXT: s_set_vgpr_msb 64 ; msbs: dst=1 src0=0 src1=0 src2=0
; CHECK-NEXT: v_mov_b32_e32 v64 /*v320*/, 0
+; CHECK-NEXT: s_load_b32 s4, s[4:5], 0x10 nv
; CHECK-NEXT: s_set_vgpr_msb 0x4001 ; msbs: dst=0 src0=1 src1=0 src2=0
; CHECK-NEXT: s_wait_kmcnt 0x0
; CHECK-NEXT: global_load_b128 v[0:3], v64 /*v320*/, s[0:1] offset:16 scope:SCOPE_SYS
@@ -224,7 +225,13 @@ define amdgpu_kernel void @dynamic_rounding_mode_with_high_vgprs(ptr addrspace(1
; CHECK-NEXT: s_wait_xcnt 0x0
; CHECK-NEXT: global_store_b128 v64 /*v320*/, v[0:3], s[2:3] offset:16 scope:SCOPE_SYS
; CHECK-NEXT: s_wait_storecnt 0x0
-; CHECK-NEXT: s_sleep_var 0x1801
+; CHECK-NEXT: s_add_co_i32 s0, s4, -4
+; CHECK-NEXT: s_min_u32 s0, s4, s0
+; CHECK-NEXT: s_lshl_b32 s0, s0, 2
+; CHECK-NEXT: s_lshr_b64 s[0:1], 0xb73e62d91c84a50f, s0
+; CHECK-NEXT: s_setreg_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), s0
+; CHECK-NEXT: s_nop 0
+; CHECK-NEXT: s_set_vgpr_msb 0x4141 ; msbs: dst=1 src0=1 src1=0 src2=0
; CHECK-NEXT: s_set_vgpr_msb 0x4100 ; msbs: dst=0 src0=0 src1=0 src2=0
; CHECK-NEXT: v_dual_add_f32 v63, v67, v131 :: v_dual_add_f32 v62, v66, v130
; CHECK-NEXT: v_dual_add_f32 v61, v65, v129 :: v_dual_add_f32 v60, v64, v128
More information about the llvm-commits
mailing list