[AMDGPU][MC] Fix out-of-range MFMA tuple register-name assertion - #215147
Merged
Conversation
Contributor
Author
This stack of pull requests is managed by sgh. |
|
@llvm/pr-subscribers-backend-amdgpu Author: Shilei Tian (shiltian) ChangesFixes #215007. This PR was assisted by AI but I reviewed all the changes. Full diff: https://github.com/llvm/llvm-project/pull/215147.diff 3 Files Affected:
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index d05997cacba0a..ca1ec70327ff2 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -962,11 +962,11 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
if (SIInstrFlags::isSDWA(*MCII, MI))
convertSDWAInst(MI);
- if (SIInstrFlags::isMAI(*MCII, MI))
- convertMAIInst(MI);
+ if (SIInstrFlags::isMAI(*MCII, MI) && !convertMAIInst(MI))
+ return MCDisassembler::Fail;
- if (SIInstrFlags::isWMMA(*MCII, MI))
- convertWMMAInst(MI);
+ if (SIInstrFlags::isWMMA(*MCII, MI) && !convertWMMAInst(MI))
+ return MCDisassembler::Fail;
int VDstIn_Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
AMDGPU::OpName::vdst_in);
@@ -1065,33 +1065,50 @@ void AMDGPUDisassembler::convertSDWAInst(MCInst &MI) const {
/// Adjust the register values used by V_MFMA_F8F6F4_f8_f8 instructions to the
/// appropriate subregister for the used format width.
-static void adjustMFMA_F8F6F4OpRegClass(const MCRegisterInfo &MRI,
+///
+/// \returns false if the operand cannot be narrowed down to \p NumRegs, which
+/// means the encoding is malformed.
+static bool adjustMFMA_F8F6F4OpRegClass(const MCRegisterInfo &MRI,
MCOperand &MO, uint8_t NumRegs) {
+ // A malformed encoding can select an operand that is not a register at all.
+ if (!MO.isReg())
+ return false;
+
+ MCRegister NewReg;
switch (NumRegs) {
case 4:
- return MO.setReg(MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3));
+ NewReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3);
+ break;
case 6:
- return MO.setReg(
- MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5));
+ NewReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5);
+ break;
case 8:
- if (MCRegister NewReg = MRI.getSubReg(
- MO.getReg(), AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5_sub6_sub7)) {
- MO.setReg(NewReg);
- }
- return;
- case 12: {
+ NewReg = MRI.getSubReg(MO.getReg(),
+ AMDGPU::sub0_sub1_sub2_sub3_sub4_sub5_sub6_sub7);
+ // For mfma f8/f8 is the widest format, so the operand already has the
+ // requested width and there is no subregister to select.
+ if (!NewReg)
+ return true;
+ break;
+ case 12:
// There is no 384-bit subreg index defined.
- MCRegister BaseReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0);
- MCRegister NewReg = MRI.getMatchingSuperReg(
- BaseReg, AMDGPU::sub0, &MRI.getRegClass(AMDGPU::VReg_384RegClassID));
- return MO.setReg(NewReg);
- }
+ if (MCRegister BaseReg = MRI.getSubReg(MO.getReg(), AMDGPU::sub0)) {
+ NewReg = MRI.getMatchingSuperReg(
+ BaseReg, AMDGPU::sub0, &MRI.getRegClass(AMDGPU::VReg_384RegClassID));
+ }
+ break;
case 16:
// No-op in cases where one operand is still f8/bf8.
- return;
+ return true;
default:
llvm_unreachable("Unexpected size for mfma/wmma f8f6f4 operand");
}
+
+ if (!NewReg)
+ return false;
+
+ MO.setReg(NewReg);
+ return true;
}
/// f8f6f4 instructions have different pseudos depending on the used formats. In
@@ -1099,11 +1116,11 @@ static void adjustMFMA_F8F6F4OpRegClass(const MCRegisterInfo &MRI,
/// classes which assume using an fp8/bf8 format for both operands. The actual
/// register class depends on the format in blgp and cbsz operands. Adjust the
/// register classes depending on the used format.
-void AMDGPUDisassembler::convertMAIInst(MCInst &MI) const {
+bool AMDGPUDisassembler::convertMAIInst(MCInst &MI) const {
int BlgpIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::blgp);
if (BlgpIdx == -1)
- return;
+ return true;
int CbszIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::cbsz);
@@ -1115,24 +1132,24 @@ void AMDGPUDisassembler::convertMAIInst(MCInst &MI) const {
AMDGPU::getMFMA_F8F6F4_WithFormatArgs(CBSZ, BLGP, MI.getOpcode());
if (!AdjustedRegClassOpcode ||
AdjustedRegClassOpcode->Opcode == MI.getOpcode())
- return;
+ return true;
MI.setOpcode(AdjustedRegClassOpcode->Opcode);
int Src0Idx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
int Src1Idx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
- adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
- AdjustedRegClassOpcode->NumRegsSrcA);
- adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
- AdjustedRegClassOpcode->NumRegsSrcB);
+ return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
+ AdjustedRegClassOpcode->NumRegsSrcA) &&
+ adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
+ AdjustedRegClassOpcode->NumRegsSrcB);
}
-void AMDGPUDisassembler::convertWMMAInst(MCInst &MI) const {
+bool AMDGPUDisassembler::convertWMMAInst(MCInst &MI) const {
int FmtAIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_a_fmt);
if (FmtAIdx == -1)
- return;
+ return true;
int FmtBIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::matrix_b_fmt);
@@ -1144,17 +1161,17 @@ void AMDGPUDisassembler::convertWMMAInst(MCInst &MI) const {
AMDGPU::getWMMA_F8F6F4_WithFormatArgs(FmtA, FmtB, MI.getOpcode());
if (!AdjustedRegClassOpcode ||
AdjustedRegClassOpcode->Opcode == MI.getOpcode())
- return;
+ return true;
MI.setOpcode(AdjustedRegClassOpcode->Opcode);
int Src0Idx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
int Src1Idx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src1);
- adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
- AdjustedRegClassOpcode->NumRegsSrcA);
- adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
- AdjustedRegClassOpcode->NumRegsSrcB);
+ return adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src0Idx),
+ AdjustedRegClassOpcode->NumRegsSrcA) &&
+ adjustMFMA_F8F6F4OpRegClass(MRI, MI.getOperand(Src1Idx),
+ AdjustedRegClassOpcode->NumRegsSrcB);
}
struct VOPModifiers {
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
index d0859d144722f..16019611120cf 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
@@ -124,8 +124,8 @@ class AMDGPUDisassembler : public MCDisassembler {
void convertVINTERPInst(MCInst &MI) const;
void convertFMAanyK(MCInst &MI) const;
void convertSDWAInst(MCInst &MI) const;
- void convertMAIInst(MCInst &MI) const;
- void convertWMMAInst(MCInst &MI) const;
+ bool convertMAIInst(MCInst &MI) const;
+ bool convertWMMAInst(MCInst &MI) const;
void convertDPP8Inst(MCInst &MI) const;
void convertMIMGInst(MCInst &MI) const;
void convertVOP3DPPInst(MCInst &MI) const;
diff --git a/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt b/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt
index de9bf7bac9548..e9537d1ec6c24 100644
--- a/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt
+++ b/llvm/test/MC/Disassembler/AMDGPU/decode-err.txt
@@ -1,4 +1,5 @@
# RUN: llvm-mc -triple=amdgpu9.00 -disassemble -filetype=null < %s 2>&1 | FileCheck -check-prefix=GCN-ERR %s
+# RUN: llvm-mc -triple=amdgpu9.50 -disassemble -filetype=null < %s 2>&1 | FileCheck -check-prefix=GFX950-ERR %s
# RUN: llvm-mc -triple=amdgpu11.00 -disassemble -show-encoding < %s | FileCheck -check-prefixes=W32 %s
# RUN: llvm-mc -triple=amdgpu11.00 -mattr=+wavefrontsize64 -disassemble -show-encoding < %s 2>&1 | FileCheck -check-prefixes=W64 %s
# RUN: llvm-mc -triple=amdgpu12.00 -disassemble -filetype=null < %s 2>&1 | FileCheck -check-prefix=GFX12-ERR %s
@@ -109,6 +110,21 @@
# GFX90A: [[@LINE+1]]:1: warning: invalid instruction encoding
0x00,0x00,0x6d,0xd8,0x01,0x00,0x00,0x00
+# The f8f6f4 source tuples are narrowed down according to cbsz/blgp, but ttmp
+# registers have no 192-bit tuple.
+# GFX950-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding
+0x00,0x00,0xae,0xd3,0x00,0xe9,0x00,0x64
+
+# Same, except that the source selector is an inline constant, which is not a
+# register at all.
+# GFX950-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding
+0x00,0x00,0xae,0xd3,0xf2,0x00,0x02,0x64
+
+# The wmma source tuples are narrowed down according to the matrix formats, but
+# scalar registers have no 384-bit tuple.
+# GFX1250-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding
+0x00,0x18,0x33,0xcc,0x08,0x30,0xa2,0x04
+
# This encoding references a missing trailing literal.
# GFX1250-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding
0x00,0x00,0x33,0xcc,0xff,0x68,0x02,0x02
|
arsenm
reviewed
Aug 9, 2026
Comment on lines
+123
to
+126
| # The wmma source tuples are narrowed down according to the matrix formats, but | ||
| # scalar registers have no 384-bit tuple. | ||
| # GFX1250-ERR: [[@LINE+1]]:1: warning: invalid instruction encoding | ||
| 0x00,0x18,0x33,0xcc,0x08,0x30,0xa2,0x04 |
Contributor
There was a problem hiding this comment.
Seems like there are 3 size error cases, but only 2 size error tests?
Contributor
Author
There was a problem hiding this comment.
Only 12 could fail here.
arsenm
approved these changes
Aug 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #215007.
This PR was assisted by AI but I reviewed all the changes.