[llvm-branch-commits] [llvm] [AMDGPU] Decouple isVOP3P/isVINTERP from isVOP3 (#223448) (PR #223784)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 15 11:55:33 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Valery Pykhtin (vpykhtin)
<details>
<summary>Changes</summary>
VOP3P and VINTERP instructions also set the VOP3 TSFlags bit, so isVOP3()
returned true for them. This overloaded isVOP3() to mean both "the VOP3
encoding" and "uses VOP3-style operand rules" (modifiers, constant bus,
literal legality).
Make VOP3P and VINTERP their own instruction-format enum values so
isVOP3() is strict (Format == VOP3). Callers that need "any VOP3-family
operand encoding" now use isVOP3Like() (VOP3 | VOP3P | VINTERP), added as
a SIInstrInfo wrapper. Redundant "isVOP3() && !isVOP3P()" tests are
simplified to isVOP3().
Resolves llvm/llvm-project#<!-- -->223448.
Co-Authored-By: Claude <noreply@<!-- -->anthropic.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/223784.diff
11 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (+5-6)
- (modified) llvm/lib/Target/AMDGPU/GCNCreateVOPD.cpp (+1-1)
- (modified) llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp (+1-1)
- (modified) llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp (+2-2)
- (modified) llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (+2-2)
- (modified) llvm/lib/Target/AMDGPU/SIDefines.h (+12-13)
- (modified) llvm/lib/Target/AMDGPU/SIFoldOperands.cpp (+1-1)
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+1-1)
- (modified) llvm/lib/Target/AMDGPU/SIInstrFormats.td (+19-17)
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.cpp (+7-6)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (+2-2)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 15560e0758a19..acc6b3d22231d 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -3686,8 +3686,8 @@ ParseStatus AMDGPUAsmParser::parseVReg32OrOff(OperandVector &Operands) {
}
unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
- if ((getForcedEncodingSize() == 32 && SIInstrFlags::isVOP3(MII, Inst)) ||
- (getForcedEncodingSize() == 64 && !SIInstrFlags::isVOP3(MII, Inst)) ||
+ if ((getForcedEncodingSize() == 32 && SIInstrFlags::isVOP3Like(MII, Inst)) ||
+ (getForcedEncodingSize() == 64 && !SIInstrFlags::isVOP3Like(MII, Inst)) ||
(isForcedDPP() && !SIInstrFlags::isDPP(MII, Inst)) ||
(isForcedSDWA() && !SIInstrFlags::isSDWA(MII, Inst)))
return Match_InvalidOperand;
@@ -4904,8 +4904,7 @@ bool AMDGPUAsmParser::validateBF16InlineConst(const MCInst &Inst,
const unsigned Opc = Inst.getOpcode();
const MCInstrDesc &Desc = MII.get(Opc);
- const bool IsVOP3 =
- SIInstrFlags::isVOP3(Desc) && !SIInstrFlags::isVOP3P(Desc);
+ const bool IsVOP3 = SIInstrFlags::isVOP3(Desc);
if (!SIInstrFlags::isVOP1(Desc) && !IsVOP3)
return true;
@@ -5025,7 +5024,7 @@ bool AMDGPUAsmParser::validateOpSel(const MCInst &Inst) {
// op_sel[0:1] must be 0 for v_dot2_bf16_bf16 and v_dot2_f16_f16 (VOP3 Dot).
if (isGFX11Plus() && SIInstrFlags::isDOT(MII, Inst) &&
- SIInstrFlags::isVOP3(MII, Inst) && !SIInstrFlags::isVOP3P(MII, Inst)) {
+ SIInstrFlags::isVOP3(MII, Inst)) {
int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
if (OpSel & 3)
@@ -10634,7 +10633,7 @@ void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst, const OperandVector &Operands,
if (SIInstrFlags::isVOP3P(Desc))
cvtVOP3P(Inst, Operands, OptionalIdx);
- else if (SIInstrFlags::isVOP3(Desc))
+ else if (SIInstrFlags::isVOP3Like(Desc))
cvtVOP3OpSel(Inst, Operands, OptionalIdx);
else if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
addOptionalImmOperand(Inst, Operands, OptionalIdx,
diff --git a/llvm/lib/Target/AMDGPU/GCNCreateVOPD.cpp b/llvm/lib/Target/AMDGPU/GCNCreateVOPD.cpp
index aedf71e7bfac1..695a2913b59a8 100644
--- a/llvm/lib/Target/AMDGPU/GCNCreateVOPD.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNCreateVOPD.cpp
@@ -92,7 +92,7 @@ class GCNCreateVOPD {
for (auto CompIdx : VOPD::COMPONENTS) {
auto CompSrcOprNum = InstInfo[CompIdx].getCompSrcOperandsNum();
- bool IsVOP3 = SII->isVOP3(*MI[CompIdx]);
+ bool IsVOP3 = SIInstrFlags::isVOP3Like(*MI[CompIdx]);
for (unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOprNum; ++CompSrcIdx) {
if (AMDGPU::hasNamedOperand(VOPDOpc, Mods[CompIdx][CompSrcIdx])) {
const MachineOperand *Mod =
diff --git a/llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp b/llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp
index 4fb9abb707040..52917d198eb1a 100644
--- a/llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp
@@ -363,7 +363,7 @@ MachineInstr *GCNDPPCombine::createDPPInst(MachineInstr &OrigMI,
OpSel |= (Mod0 ? (!!(Mod0->getImm() & SISrcMods::OP_SEL_0) << 0) : 0);
OpSel |= (Mod1 ? (!!(Mod1->getImm() & SISrcMods::OP_SEL_0) << 1) : 0);
OpSel |= (Mod2 ? (!!(Mod2->getImm() & SISrcMods::OP_SEL_0) << 2) : 0);
- if (Mod0 && TII->isVOP3(OrigMI) && !TII->isVOP3P(OrigMI))
+ if (Mod0 && TII->isVOP3(OrigMI))
OpSel |= !!(Mod0->getImm() & SISrcMods::DST_OP_SEL) << 3;
if (OpSel != 0) {
diff --git a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
index 3def256f07f78..65bf6eb7e2722 100644
--- a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
@@ -104,8 +104,8 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII,
if (IsVOPD3 && !ST.hasVOPD3())
return false;
- if (!IsVOPD3 && ((TII.isVOP3(MIX) && !canMapVOP3PToVOPD(MIX)) ||
- (TII.isVOP3(MIY) && !canMapVOP3PToVOPD(MIY))))
+ if (!IsVOPD3 && ((SIInstrFlags::isVOP3Like(MIX) && !canMapVOP3PToVOPD(MIX)) ||
+ (SIInstrFlags::isVOP3Like(MIY) && !canMapVOP3PToVOPD(MIY))))
return false;
if (TII.isDPP(MIX) || TII.isDPP(MIY))
return false;
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
index 12880e6692918..aac7e1ad34d81 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
@@ -432,9 +432,9 @@ void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O) {
auto Opcode = MI->getOpcode();
if (OpNo == 0) {
- if (SIInstrFlags::isVOP3(MII, *MI) && SIInstrFlags::isDPP(MII, *MI))
+ if (SIInstrFlags::isVOP3Like(MII, *MI) && SIInstrFlags::isDPP(MII, *MI))
O << "_e64_dpp";
- else if (SIInstrFlags::isVOP3(MII, *MI)) {
+ else if (SIInstrFlags::isVOP3Like(MII, *MI)) {
if (!getVOP3IsSingle(Opcode))
O << "_e64";
} else if (SIInstrFlags::isDPP(MII, *MI))
diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h
index 65388e237a3b3..999754be8f356 100644
--- a/llvm/lib/Target/AMDGPU/SIDefines.h
+++ b/llvm/lib/Target/AMDGPU/SIDefines.h
@@ -77,12 +77,9 @@ enum : uint64_t {
SALU = 1 << 7,
VALU = 1 << 8,
- // Remaining modifiers that layer on top of a base format.
TRANS = 1 << 9,
- VOP3P = 1 << 10,
- VINTERP = 1 << 11,
- // Bits 30-12 are free.
+ // Bits 30-10 are free.
// High bits - other information.
VM_CNT = UINT64_C(1) << 32,
@@ -189,6 +186,8 @@ enum class InstFormat : uint64_t {
VOP2,
VOPC,
VOP3,
+ VOP3P,
+ VINTERP,
VINTRP,
VOPD3,
LDSDIR,
@@ -261,10 +260,13 @@ template <typename... T> constexpr bool isVOP3(const T &...O) {
return getFormat(O...) == InstFormat::VOP3;
}
template <typename... T> constexpr bool isVOP3P(const T &...O) {
- return getTSFlags(O...) & DontUseRawTSFlags::VOP3P;
+ return getFormat(O...) == InstFormat::VOP3P;
+}
+template <typename... T> constexpr bool isVINTERP(const T &...O) {
+ return getFormat(O...) == InstFormat::VINTERP;
}
template <typename... T> constexpr bool isVOP3Like(const T &...O) {
- return isVOP3(O...) || isVOP3P(O...);
+ return isVOP3(O...) || isVOP3P(O...) || isVINTERP(O...);
}
template <typename... T> constexpr bool isVINTRP(const T &...O) {
return getFormat(O...) == InstFormat::VINTRP;
@@ -281,13 +283,13 @@ template <typename... T> constexpr bool isSDWA(const T &...O) {
}
template <typename... T> constexpr bool isDPP(const T &...O) {
bool R = getFormatModifier(O...) == FormatModifier::DPP;
- // DPP layers on VOP3 and VOPC (VOP3P instructions carry Format::VOP3 here).
- // The VOP1/VOP2 e32 dpp forms currently carry Format::NONE instead of their
- // base format.
+ // DPP layers on VOP3, VOPC and VOP3P. The VOP1/VOP2 e32 dpp forms currently
+ // carry Format::NONE instead of their base format.
// TODO: tag VOP1/VOP2 e32 dpp forms with VOP1/VOP2 (see VOP_DPP_Pseudo) so
- // NONE can be dropped from this assert.
+ // Format::NONE can be dropped from this assert.
assert((!R || getFormat(O...) == InstFormat::VOP3 ||
getFormat(O...) == InstFormat::VOPC ||
+ getFormat(O...) == InstFormat::VOP3P ||
getFormat(O...) == InstFormat::NONE) &&
"unexpected base format for DPP");
return R;
@@ -331,9 +333,6 @@ template <typename... T> constexpr bool isSpill(const T &...O) {
template <typename... T> constexpr bool isLDSDIR(const T &...O) {
return getFormat(O...) == InstFormat::LDSDIR;
}
-template <typename... T> constexpr bool isVINTERP(const T &...O) {
- return getTSFlags(O...) & DontUseRawTSFlags::VINTERP;
-}
template <typename... T> constexpr bool isWQM(const T &...O) {
return getTSFlags(O...) & DontUseRawTSFlags::WQM;
}
diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
index e5490b390db08..bf0dc60790a53 100644
--- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
@@ -495,7 +495,7 @@ bool SIFoldOperandsImpl::canUseImmWithOpSel(const MachineInstr *MI,
case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
// VOP3 packed instructions ignore op_sel source modifiers, we cannot encode
// two different constants.
- if (SIInstrFlags::isVOP3(*MI) && !SIInstrFlags::isVOP3P(*MI) &&
+ if (SIInstrFlags::isVOP3(*MI) &&
static_cast<uint16_t>(ImmVal) != static_cast<uint16_t>(ImmVal >> 16))
return false;
break;
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 6a1f522d0011a..9297ca04b7ab7 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -19807,7 +19807,7 @@ void SITargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
MachineFunction *MF = MI.getMF();
MachineRegisterInfo &MRI = MF->getRegInfo();
- if (TII->isVOP3(MI.getOpcode())) {
+ if (SIInstrFlags::isVOP3Like(MI)) {
// Make sure constant bus requirements are respected.
TII->legalizeOperandsVOP3(MRI, MI);
diff --git a/llvm/lib/Target/AMDGPU/SIInstrFormats.td b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
index 22da81e387d60..ace334c7b97b7 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrFormats.td
+++ b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
@@ -26,23 +26,25 @@ def AMDGPUInstrFormat {
int VOP2 = 7;
int VOPC = 8;
int VOP3 = 9;
- int VINTRP = 10;
- int VOPD3 = 11;
- int LDSDIR = 12;
+ int VOP3P = 10;
+ int VINTERP = 11;
+ int VINTRP = 12;
+ int VOPD3 = 13;
+ int LDSDIR = 14;
// Memory instruction formats.
- int MUBUF = 13;
- int MTBUF = 14;
- int SMRD = 15;
- int MIMG = 16;
- int VIMAGE = 17;
- int VSAMPLE = 18;
- int EXP = 19;
- int FLAT = 20;
- int DS = 21;
+ int MUBUF = 15;
+ int MTBUF = 16;
+ int SMRD = 17;
+ int MIMG = 18;
+ int VIMAGE = 19;
+ int VSAMPLE = 20;
+ int EXP = 21;
+ int FLAT = 22;
+ int DS = 23;
// Combined SGPR/VGPR spill pseudo.
- int Spill = 22;
+ int Spill = 24;
}
// Operand-encoding modifier, keep in sync with SIInstrFlags::FormatModifier in
@@ -201,7 +203,7 @@ class InstSI <dag outs, dag ins, string asm = "",
// Mutually-exclusive instruction format, derived from the format bits above.
// The base format bits are all exclusive, so they collapse into one enum
- // field.
+ // field. VOP3P/VINTERP also set the VOP3 bit, so match them before VOP3.
bits<5> Format = !cond(SOP1 : AMDGPUInstrFormat.SOP1,
SOP2 : AMDGPUInstrFormat.SOP2,
SOPC : AMDGPUInstrFormat.SOPC,
@@ -210,6 +212,8 @@ class InstSI <dag outs, dag ins, string asm = "",
VOP1 : AMDGPUInstrFormat.VOP1,
VOP2 : AMDGPUInstrFormat.VOP2,
VOPC : AMDGPUInstrFormat.VOPC,
+ VOP3P : AMDGPUInstrFormat.VOP3P,
+ VINTERP : AMDGPUInstrFormat.VINTERP,
VOP3 : AMDGPUInstrFormat.VOP3,
VINTRP : AMDGPUInstrFormat.VINTRP,
VOPD3 : AMDGPUInstrFormat.VOPD3,
@@ -238,10 +242,8 @@ class InstSI <dag outs, dag ins, string asm = "",
let TSFlags{8} = VALU;
let TSFlags{9} = TRANS;
- let TSFlags{10} = VOP3P;
- let TSFlags{11} = VINTERP;
- // Bits 30-12 are free.
+ // Bits 30-10 are free.
let TSFlags{32} = VM_CNT;
let TSFlags{33} = EXP_CNT;
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 2c014218914b0..68e19bcb8a555 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -112,7 +112,7 @@ static bool nodesHaveSameOperandValue(SDNode *N0, SDNode *N1,
static bool canRemat(const MachineInstr &MI) {
if (SIInstrInfo::isVOP1(MI) || SIInstrInfo::isVOP2(MI) ||
- SIInstrInfo::isVOP3(MI) || SIInstrInfo::isSDWA(MI) ||
+ SIInstrFlags::isVOP3Like(MI) || SIInstrInfo::isSDWA(MI) ||
SIInstrInfo::isSALU(MI))
return true;
@@ -5063,7 +5063,7 @@ bool SIInstrInfo::isLiteralOperandLegal(const MCInstrDesc &InstDesc,
if (!RI.opCanUseLiteralConstant(OpInfo.OperandType))
return false;
- if (!isVOP3(InstDesc) || !AMDGPU::isSISrcOperand(OpInfo))
+ if (!SIInstrFlags::isVOP3Like(InstDesc) || !AMDGPU::isSISrcOperand(OpInfo))
return true;
return ST.hasVOP3Literal();
@@ -5743,7 +5743,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
UsesLiteral = true;
LiteralVal = &MO;
} else if (!MO.isIdenticalTo(*LiteralVal)) {
- assert(isVOP2(MI) || isVOP3(MI));
+ assert(isVOP2(MI) || SIInstrFlags::isVOP3Like(MI));
ErrInfo = "VOP2/VOP3 instruction uses more than one literal";
return false;
}
@@ -5770,7 +5770,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
return false;
}
- if (isVOP3(MI) && UsesLiteral && !ST.hasVOP3Literal()) {
+ if (SIInstrFlags::isVOP3Like(MI) && UsesLiteral && !ST.hasVOP3Literal()) {
ErrInfo = "VOP3 instruction uses literal";
return false;
}
@@ -6716,7 +6716,8 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
const MachineOperand *UsedLiteral = nullptr;
int ConstantBusLimit = ST.getConstantBusLimit(MI.getOpcode());
- int LiteralLimit = !isVOP3(MI) || ST.hasVOP3Literal() ? 1 : 0;
+ int LiteralLimit =
+ !SIInstrFlags::isVOP3Like(MI) || ST.hasVOP3Literal() ? 1 : 0;
// TODO: Be more permissive with frame indexes.
if (!MO->isReg() && !isInlineConstant(*MO, OpInfo)) {
@@ -7716,7 +7717,7 @@ SIInstrInfo::legalizeOperands(MachineInstr &MI,
}
// Legalize VOP3
- if (isVOP3(MI)) {
+ if (SIInstrFlags::isVOP3Like(MI)) {
legalizeOperandsVOP3(MRI, MI);
return CreatedBB;
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 58ca7e69cecf8..ecd9e283d7e2f 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -914,7 +914,7 @@ ComponentProps::ComponentProps(const MCInstrDesc &OpDesc, bool VOP3Layout) {
HasSrc2Acc = TiedIdx != -1;
Opcode = OpDesc.getOpcode();
- IsVOP3 = VOP3Layout || SIInstrFlags::isVOP3(OpDesc);
+ IsVOP3 = VOP3Layout || SIInstrFlags::isVOP3Like(OpDesc);
SrcOperandsNum = AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src2) ? 3
: AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::imm) ? 3
: AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src1) ? 2
@@ -943,7 +943,7 @@ ComponentProps::ComponentProps(const MCInstrDesc &OpDesc, bool VOP3Layout) {
--NumVOPD3Mods;
}
- if (SIInstrFlags::isVOP3(OpDesc))
+ if (SIInstrFlags::isVOP3Like(OpDesc))
return;
auto OperandsNum = OpDesc.getNumOperands();
``````````
</details>
https://github.com/llvm/llvm-project/pull/223784
More information about the llvm-branch-commits
mailing list