[llvm] [AMDGPU] Handle `s_setreg_imm32_b32` targeting `MODE` register (PR #174681)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 9 10:15:58 PST 2026
================
@@ -315,6 +338,82 @@ AMDGPULowerVGPREncoding::handleCoissue(MachineBasicBlock::instr_iterator I) {
return Prev;
}
+/// Convert mode value from S_SET_VGPR_MSB format to MODE register format.
+/// S_SET_VGPR_MSB uses: (src0[0-1], src1[2-3], src2[4-5], dst[6-7])
+/// MODE register uses: (dst[0-1], src0[2-3], src1[4-5], src2[6-7])
+/// This is a left rotation by 2 bits on an 8-bit value.
+static int64_t convertModeToSetregFormat(int64_t Mode) {
+ assert(isUInt<8>(Mode) && "Mode expected to be 8-bit");
+ return llvm::rotl<uint8_t>(static_cast<uint8_t>(Mode), /*R=*/2);
+}
+
+bool AMDGPULowerVGPREncoding::updateSetregModeImm(MachineInstr &MI,
+ int64_t ModeValue) {
+ assert(MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32);
+
+ // Convert from S_SET_VGPR_MSB format to MODE register format
+ int64_t SetregMode = convertModeToSetregFormat(ModeValue);
+
+ MachineOperand *ImmOp = TII->getNamedOperand(MI, AMDGPU::OpName::imm);
+ int64_t OldImm = ImmOp->getImm();
+ int64_t NewImm =
+ (OldImm & ~AMDGPU::Hwreg::VGPR_MSB_MASK) | (SetregMode << VGPRMSBShift);
+ ImmOp->setImm(NewImm);
+ return NewImm != OldImm;
+}
+
+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");
+
+ MachineOperand *SIMM16Op = TII->getNamedOperand(MI, AMDGPU::OpName::simm16);
+ assert(SIMM16Op && "SIMM16Op must be present");
+
+ auto [HwRegId, Offset, Size] = HwregEncoding::decode(SIMM16Op->getImm());
+ (void)Offset;
+ if (HwRegId != ID_MODE)
+ return false;
+
+ int64_t ModeValue = static_cast<int64_t>(CurrentMode);
+
+ // Case 1: Size <= 12 - the original instruction uses imm32[0:Size-1], so
+ // imm32[12:19] is unused. Safe to set imm32[12:19] to the correct VGPR
+ // MSBs.
+ if (Size <= VGPRMSBShift) {
+ // This instruction now acts as MostRecentModeSet so it can be updated if
+ // CurrentMode changes via piggybacking.
+ MostRecentModeSet = &MI;
----------------
shiltian wrote:
This is where we treat them the same.
https://github.com/llvm/llvm-project/pull/174681
More information about the llvm-commits
mailing list