https://github.com/petar-avramovic created https://github.com/llvm/llvm-project/pull/196515
Replace isVGPR checks with isValidVOPDSrc that validates physical source registers against the actual combined VOPD/VOPD3 instruction's operand register classes. Now we also validate operands for VOPD instructions. >From 2c22fc19e60c076ad79aee78f8fee037d683d26d Mon Sep 17 00:00:00 2001 From: Petar Avramovic <[email protected]> Date: Fri, 8 May 2026 12:56:09 +0200 Subject: [PATCH] AMDGPU: Validate VOPD/VOPD3 physical source registers against operand RC Replace isVGPR checks with isValidVOPDSrc that validates physical source registers against the actual combined VOPD/VOPD3 instruction's operand register classes. Now we also validate operands for VOPD instructions. --- llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp | 51 +++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp index 7c3ec382dc04b..fb26175769d94 100644 --- a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp +++ b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp @@ -34,6 +34,32 @@ using namespace llvm; #define DEBUG_TYPE "gcn-vopd-utils" +// Check if physical register from src<SrcIdx> operand of MI<CompIdx> matches +// register class constraints in corresponding VOPDOpc operand with name +// src/vsrc<SrcIdx><CompIdx>. +bool isValidVOPDSrc(const SIInstrInfo &TII, int VOPDOpc, unsigned CompIdx, + unsigned SrcIdx, Register PhysSrcReg) { + static const AMDGPU::OpName Src0X[] = {AMDGPU::OpName::src0X}; + static const AMDGPU::OpName Src1X[] = {AMDGPU::OpName::vsrc1X}; + static const AMDGPU::OpName Src2X[] = {AMDGPU::OpName::vsrc2X, + AMDGPU::OpName::src2X}; + static const AMDGPU::OpName Src0Y[] = {AMDGPU::OpName::src0Y}; + static const AMDGPU::OpName Src1Y[] = {AMDGPU::OpName::vsrc1Y}; + static const AMDGPU::OpName Src2Y[] = {AMDGPU::OpName::vsrc2Y, + AMDGPU::OpName::src2Y}; + static const ArrayRef<AMDGPU::OpName> SrcNames[2][3] = { + {Src0X, Src1X, Src2X}, {Src0Y, Src1Y, Src2Y}}; + + int Idx = -1; + for (AMDGPU::OpName Name : SrcNames[CompIdx][SrcIdx]) { + Idx = getNamedOperandIdx(VOPDOpc, Name); + if (Idx > 0) + break; + } + + return TII.getRegClass(TII.get(VOPDOpc), Idx)->contains(PhysSrcReg); +} + bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, const MachineInstr &MIX, const MachineInstr &MIY, bool IsVOPD3, @@ -63,6 +89,11 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, }; SmallSet<Register, 4> UniqueScalarRegs; + unsigned EncodingFamily = AMDGPU::getVOPDEncodingFamily(ST); + unsigned XOpc = AMDGPU::getVOPDOpcode(MIX.getOpcode(), IsVOPD3); + unsigned YOpc = AMDGPU::getVOPDOpcode(MIY.getOpcode(), IsVOPD3); + int VOPDOpc = AMDGPU::getVOPDFull(XOpc, YOpc, EncodingFamily, IsVOPD3); + auto InstInfo = AMDGPU::getVOPDInstInfo(MIX.getDesc(), MIY.getDesc()); for (auto CompIdx : VOPD::COMPONENTS) { @@ -73,6 +104,8 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, if (!TRI->isVectorRegister(MRI, Src0.getReg())) { UniqueScalarRegs.insert(Src0.getReg()); } + if (!isValidVOPDSrc(TII, VOPDOpc, CompIdx, 0, Src0.getReg())) + return false; } else if (!TII.isInlineConstant(Src0)) { if (IsVOPD3) return false; @@ -90,13 +123,16 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, if (MI.getDesc().hasImplicitUseOfPhysReg(AMDGPU::VCC)) UniqueScalarRegs.insert(AMDGPU::VCC_LO); - if (IsVOPD3) { - if (const MachineOperand *Src1 = - TII.getNamedOperand(MI, AMDGPU::OpName::src1)) { - if (!Src1->isReg() || !TRI->isVGPR(MRI, Src1->getReg())) - return false; - } + if (const MachineOperand *Src1 = + TII.getNamedOperand(MI, AMDGPU::OpName::src1)) { + if (IsVOPD3 && !Src1->isReg()) + return false; + if (Src1->isReg() && + !isValidVOPDSrc(TII, VOPDOpc, CompIdx, 1, Src1->getReg())) + return false; + } + if (IsVOPD3) { if (const MachineOperand *Src2 = TII.getNamedOperand(MI, AMDGPU::OpName::src2)) { if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::bitop3)) { @@ -105,7 +141,8 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, return false; } else if (MI.getOpcode() == AMDGPU::V_CNDMASK_B32_e64) { UniqueScalarRegs.insert(Src2->getReg()); - } else if (!Src2->isReg() || !TRI->isVGPR(MRI, Src2->getReg())) { + } else if (!Src2->isReg() || + !isValidVOPDSrc(TII, VOPDOpc, CompIdx, 2, Src2->getReg())) { return false; } } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
