diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td index de3ae53eb548..84f9a4bb9faa 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.td +++ b/llvm/lib/Target/AMDGPU/AMDGPU.td @@ -1264,6 +1264,12 @@ def Feature1024AddressableVGPRs : SubtargetFeature<"1024-addressable-vgprs", "Has 1024 addressable VGPRs" >; +def FeatureSetregVGPRMSBFixup : SubtargetFeature<"setreg-vgpr-msb-fixup", + "HasSetregVGPRMSBFixup", + "true", + "S_SETREG to MODE clobbers VGPR MSB bits, requires fixup" +>; + def FeatureWaitXcnt : SubtargetFeature<"wait-xcnt", "HasWaitXcnt", "true", @@ -2223,7 +2229,8 @@ def FeatureISAVersion12_50_Common : FeatureSet< def FeatureISAVersion12_50 : FeatureSet< !listconcat(FeatureISAVersion12_50_Common.Features, - [FeatureAddressableLocalMemorySize327680])>; + [FeatureAddressableLocalMemorySize327680, + FeatureSetregVGPRMSBFixup])>; def FeatureISAVersion12_51 : FeatureSet< !listconcat(FeatureISAVersion12_50_Common.Features, diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp index fddf8d2e6e68..0d89fc881992 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp @@ -44,8 +44,11 @@ #include "AMDGPU.h" #include "GCNSubtarget.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "SIDefines.h" #include "SIInstrInfo.h" #include "llvm/ADT/PackedVector.h" +#include "llvm/ADT/bit.h" +#include "llvm/Support/MathExtras.h" using namespace llvm; @@ -63,6 +66,9 @@ class AMDGPULowerVGPREncoding { using ModeType = PackedVector>; + static constexpr unsigned VGPRMSBShift = + llvm::countr_zero_constexpr(AMDGPU::Hwreg::DST_VGPR_MSB); + class ModeTy : public ModeType { public: // bitset constructor will set all bits to zero @@ -143,6 +149,16 @@ private: /// instruction to encourage more coissuing. MachineBasicBlock::instr_iterator handleCoissue(MachineBasicBlock::instr_iterator I); + + /// Handle S_SETREG_IMM32_B32 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. + bool updateSetregModeImm(MachineInstr &MI, int64_t ModeValue); }; bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode, ModeTy Mask, @@ -160,12 +176,19 @@ bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode, ModeTy Mask, CurrentMode |= NewMode; CurrentMask |= Mask; - MachineOperand &Op = MostRecentModeSet->getOperand(0); + // Update MostRecentModeSet with the new mode. It can be either + // S_SET_VGPR_MSB or S_SETREG_IMM32_B32 (with Size <= 12). + if (MostRecentModeSet->getOpcode() == AMDGPU::S_SET_VGPR_MSB) { + MachineOperand &Op = MostRecentModeSet->getOperand(0); + // Carry old mode bits from the existing instruction. + int64_t OldModeBits = Op.getImm() & (ModeMask << ModeWidth); + Op.setImm(CurrentMode | OldModeBits); + } else { + assert(MostRecentModeSet->getOpcode() == AMDGPU::S_SETREG_IMM32_B32 && + "unexpected MostRecentModeSet opcode"); + updateSetregModeImm(*MostRecentModeSet, CurrentMode); + } - // Carry old mode bits from the existing instruction. - int64_t OldModeBits = Op.getImm() & (ModeMask << ModeWidth); - - Op.setImm(CurrentMode | OldModeBits); return true; } @@ -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(static_cast(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(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; + return updateSetregModeImm(MI, ModeValue); + } + + // Case 2: Size > 12 - the original instruction uses bits beyond 11, so we + // cannot arbitrarily modify imm32[12:19]. Check if it already matches VGPR + // MSBs. Note: imm32[12:19] is in MODE register format, while ModeValue is + // in S_SET_VGPR_MSB format, so we need to convert before comparing. + MachineOperand *ImmOp = TII->getNamedOperand(MI, AMDGPU::OpName::imm); + assert(ImmOp && "ImmOp must be present"); + int64_t ImmBits12To19 = (ImmOp->getImm() & VGPR_MSB_MASK) >> VGPRMSBShift; + int64_t SetregModeValue = convertModeToSetregFormat(ModeValue); + if (ImmBits12To19 == SetregModeValue) { + // Already correct, but we must invalidate MostRecentModeSet because this + // instruction will overwrite mode[12:19]. We can't update this instruction + // via piggybacking (bits[12:19] are meaningful), so if CurrentMode changes, + // a new s_set_vgpr_msb will be inserted after this instruction. + MostRecentModeSet = nullptr; + return false; + } + + // imm32[12:19] doesn't match VGPR MSBs - insert s_set_vgpr_msb after + // the original instruction to restore the correct value. + MachineBasicBlock::iterator InsertPt = std::next(MI.getIterator()); + MostRecentModeSet = BuildMI(*MBB, InsertPt, MI.getDebugLoc(), + TII->get(AMDGPU::S_SET_VGPR_MSB)) + .addImm(ModeValue); + return true; +} + bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) { const GCNSubtarget &ST = MF.getSubtarget(); if (!ST.has1024AddressableVGPRs()) @@ -359,6 +458,12 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) { continue; } + if (MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 && + ST.hasSetregVGPRMSBFixup()) { + Changed |= handleSetregMode(MI); + continue; + } + Changed |= runOnMachineInstr(MI); if (ClauseRemaining) diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h index 9ccedf24b862..4f53325c3c67 100644 --- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h +++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h @@ -244,6 +244,7 @@ protected: bool HasRestrictedSOffset = false; bool Has64BitLiterals = false; bool Has1024AddressableVGPRs = false; + bool HasSetregVGPRMSBFixup = false; bool HasBitOp3Insts = false; bool HasTanhInsts = false; bool HasTensorCvtLutInsts = false; @@ -1445,6 +1446,8 @@ public: bool has1024AddressableVGPRs() const { return Has1024AddressableVGPRs; } + bool hasSetregVGPRMSBFixup() const { return HasSetregVGPRMSBFixup; } + bool hasMinimum3Maximum3PKF16() const { return HasMinimum3Maximum3PKF16; } diff --git a/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir new file mode 100644 index 000000000000..6109d5016b74 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir @@ -0,0 +1,244 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -run-pass=amdgpu-lower-vgpr-encoding -o - %s | FileCheck %s + +--- +# Case 1a: Size < 12 (size=4), imm32[12:19]=0 +# S_SET_VGPR_MSB format: (src0_msb[0-1], src1_msb[2-3], src2_msb[4-5], dst_msb[6-7]) +# MODE register format: (dst_msb[0-1], src0_msb[2-3], src1_msb[4-5], src2_msb[6-7]) +# vgpr256/257 (both MSB=1): S_SET_VGPR_MSB mode = (1 << 0) | (1 << 6) = 65 +# MODE register mode = (1 << 0) | (1 << 2) = 5 +# New setreg imm = 0x5 | (5 << 12) = 0x5005 = 20485 +name: setreg_size_lt_12 +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_lt_12 + ; 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 20485, 6145, implicit-def $mode, implicit $mode + ; 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 5, 6145, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 1b: Size == 12 (boundary), imm32[12:19]=0 +# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# New setreg imm = 0xABC | (5 << 12) = 0x5ABC = 23228 +name: setreg_size_eq_12 +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_eq_12 + ; 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 23228, 22529, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=12, offset=0, hwreg=MODE: simm16 = 0x5801 = 22529 + S_SETREG_IMM32_B32 2748, 22529, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 1c: Size <= 12 with existing non-zero bits in imm32[12:19] +# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# imm32 = 0x23005 (bits 12:19 = 0x23), result = 0x5005 = 20485 (bits 12:19 replaced with 5) +name: setreg_size_lt_12_nonzero_upper +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_lt_12_nonzero_upper + ; 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 20485, 6145, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 + ; imm32 = 0x23005 = 143365 (bits 12:19 = 0x23) + S_SETREG_IMM32_B32 143365, 6145, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 2: Size > 12 (size=16), imm32[12:19] already matches VGPR MSBs +# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# imm32 = 0x5ABC = 23228 (bits 12:19 = 5), no modification needed +name: setreg_size_gt_12_match +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_gt_12_match + ; 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 23228, 30721, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 + ; imm32 = 0x5ABC = 23228 (bits 12:19 = 5 = MODE register mode for vgpr256/257) + S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 3: Size > 12 (size=16), imm32[12:19] doesn't match VGPR MSBs +# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# imm32 = 0x23ABC = 146108 (bits 12:19 = 0x23 != 5), must insert s_set_vgpr_msb after +name: setreg_size_gt_12_mismatch +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_gt_12_mismatch + ; 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 146108, 30721, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_SET_VGPR_MSB 65, implicit-def $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 + ; imm32 = 0x23ABC = 146108 (bits 12:19 = 0x23 != 5) + S_SETREG_IMM32_B32 146108, 30721, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 4: Non-MODE hwreg should not be modified +# This uses ID_STATUS=2 instead of ID_MODE=1 +# vgpr256/257: S_SET_VGPR_MSB mode = 65 +name: setreg_non_mode_hwreg +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_non_mode_hwreg + ; 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 5, 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(2): simm16 = 2 | (0 << 6) | (3 << 11) = 0x1802 = 6146 + S_SETREG_IMM32_B32 5, 6146, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 5: Size <= 12 but VGPR MSBs already present (no change needed) +# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# imm32 = 0x5005 = 20485 (bits 12:19 = 5 = MODE register mode) +name: setreg_size_lt_12_already_correct +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_lt_12_already_correct + ; 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 20485, 6145, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 + ; imm32 = 0x5005 = 20485 (bits 12:19 = 5 = MODE register mode) + S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 6: Different VGPR MSB value (using different high VGPRs) +# vgpr512/513 (both MSB=2): S_SET_VGPR_MSB mode = (2 << 0) | (2 << 6) = 130 +# MODE register mode = (2 << 0) | (2 << 2) = 10 +# New setreg imm = 0x5 | (10 << 12) = 0xA005 = 40965 +name: setreg_different_vgpr_msb +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_different_vgpr_msb + ; CHECK: S_SET_VGPR_MSB 130, implicit-def $mode + ; CHECK-NEXT: $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec + ; CHECK-NEXT: S_SETREG_IMM32_B32 40965, 6145, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec + ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 + S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode + S_ENDPGM 0 +... + +--- +# Case 7: Piggybacking successfully updates s_setreg_imm32_b32 (Size <= 12) +# First VGPR (V_MOV vgpr256, vgpr257): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# Second VGPR (V_ADD_U32 vgpr256, vgpr257, vgpr512): +# S_SET_VGPR_MSB mode = (1 << 0) | (2 << 2) | (1 << 6) = 73 (src0=1, src1=2, dst=1) +# MODE register mode = (1 << 0) | (1 << 2) | (2 << 4) = 37 (dst=1, src0=1, src1=2) +# Piggybacking updates setreg imm32[12:19] from 5 to 37. +# Final setreg imm = 5 | (37 << 12) = 151557 +name: setreg_size_le_12_piggyback_superset +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_le_12_piggyback_superset + ; 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 151557, 6145, implicit-def $mode, implicit $mode + ; CHECK-NEXT: $vgpr256 = V_ADD_U32_e32 $vgpr257, $vgpr512, 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 5, 6145, implicit-def $mode, implicit $mode + ; Second instruction uses same dst/src0 (MSB=1) but adds src1 (MSB=2) + $vgpr256 = V_ADD_U32_e32 $vgpr257, $vgpr512, implicit $exec + S_ENDPGM 0 +... + +--- +# Case 8: s_setreg_imm32_b32 (Size <= 12) followed by VGPR with different mode bits +# First VGPR (V_MOV vgpr256, vgpr0): S_SET_VGPR_MSB mode = 64, MODE register mode = 1 +# Second VGPR (V_MOV vgpr256, vgpr256): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# Setreg gets MODE mode = 1 from first VGPR. Second VGPR needs different src0 bits, +# so a new S_SET_VGPR_MSB is inserted. The new S_SET_VGPR_MSB has mode = 65 | (64 << 8) = 16449. +name: setreg_size_le_12_then_different_vgpr +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + + ; CHECK-LABEL: name: setreg_size_le_12_then_different_vgpr + ; CHECK: liveins: $vgpr0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: S_SET_VGPR_MSB 64, implicit-def $mode + ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr0, implicit $exec + ; CHECK-NEXT: S_SETREG_IMM32_B32 4101, 6145, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_SET_VGPR_MSB 16449, implicit-def $mode + ; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr256, implicit $exec + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr0, implicit $exec + ; size=4, offset=0, hwreg=MODE: simm16 = 0x1801 = 6145 + S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode + $vgpr256 = V_MOV_B32_e32 $vgpr256, implicit $exec + S_ENDPGM 0 +... + +--- +# Case 9: After s_setreg_imm32_b32 (Size > 12, matching), new s_set_vgpr_msb needed +# First VGPR (vgpr256/257): S_SET_VGPR_MSB mode = 65, MODE register mode = 5 +# Setreg has size=16 with imm32[12:19]=5 (matches MODE register mode). +# handleSetregMode sets MostRecentModeSet = nullptr (can't piggyback on Size > 12). +# Second VGPR (vgpr512/513): S_SET_VGPR_MSB mode = 130, MODE register mode = 10 +# Since MostRecentModeSet = nullptr, a new s_set_vgpr_msb is inserted. +# New s_set_vgpr_msb imm = NewMode | (OldMode << 8) = 130 | (65 << 8) = 16770 +name: setreg_size_gt_12_match_then_different_vgpr +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: setreg_size_gt_12_match_then_different_vgpr + ; 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 23228, 30721, implicit-def $mode, implicit $mode + ; CHECK-NEXT: S_SET_VGPR_MSB 16770, implicit-def $mode + ; CHECK-NEXT: $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec + ; CHECK-NEXT: S_ENDPGM 0 + $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec + ; size=16, offset=0, hwreg=MODE: simm16 = 0x7801 = 30721 + ; imm32 = 0x5ABC = 23228 (bits 12:19 = 5 = MODE register mode, matches!) + S_SETREG_IMM32_B32 23228, 30721, implicit-def $mode, implicit $mode + $vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec + S_ENDPGM 0 +...