https://github.com/petar-avramovic updated https://github.com/llvm/llvm-project/pull/196515
>From 115502f896ef32fcccd8db1670b8682b46887963 Mon Sep 17 00:00:00 2001 From: Petar Avramovic <[email protected]> Date: Mon, 20 Jul 2026 17:19:21 +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 | 66 +++++++++++++++++++++---- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp index 44e467b0ba721..4698b4e1be57e 100644 --- a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp +++ b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp @@ -34,6 +34,35 @@ 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>. +static bool isValidVOPDSrc(const SIInstrInfo &TII, int VOPDOpc, + unsigned CompIdx, unsigned SrcIdx, + Register PhysSrcReg) { + using namespace AMDGPU; + int OpIdx = -1; + const bool IsX = CompIdx == VOPD::X; + switch (SrcIdx) { + case 0: + OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::src0X : OpName::src0Y); + break; + case 1: + OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::vsrc1X : OpName::vsrc1Y); + break; + case 2: + OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::vsrc2X : OpName::vsrc2Y); + if (OpIdx == -1) + OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::src2X : OpName::src2Y); + break; + default: + llvm_unreachable("unexpected VOPD source index"); + } + + assert(OpIdx != -1); + return TII.getRegClass(TII.get(VOPDOpc), OpIdx)->contains(PhysSrcReg); +} + bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, const MachineInstr &MIX, const MachineInstr &MIY, bool IsVOPD3, @@ -63,6 +92,12 @@ 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); + assert(VOPDOpc != -1); + auto InstInfo = AMDGPU::getVOPDInstInfo(MIX.getDesc(), MIY.getDesc()); for (auto CompIdx : VOPD::COMPONENTS) { @@ -70,9 +105,10 @@ bool llvm::checkVOPDRegConstraints(const SIInstrInfo &TII, const MachineOperand &Src0 = *TII.getNamedOperand(MI, AMDGPU::OpName::src0); if (Src0.isReg()) { - if (!TRI->isVectorRegister(MRI, Src0.getReg())) { + if (!isValidVOPDSrc(TII, VOPDOpc, CompIdx, 0, Src0.getReg())) + return false; + if (!TRI->isVectorRegister(MRI, Src0.getReg())) UniqueScalarRegs.insert(Src0.getReg()); - } } else if (!TII.isInlineConstant(Src0)) { if (IsVOPD3) return false; @@ -90,23 +126,33 @@ 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())) + if (const MachineOperand *Src1 = + TII.getNamedOperand(MI, AMDGPU::OpName::src1)) { + if (Src1->isReg()) { + if (!isValidVOPDSrc(TII, VOPDOpc, CompIdx, 1, Src1->getReg())) return false; + assert(TRI->isVectorRegister(MRI, Src1->getReg())); + } else if (IsVOPD3) { + return false; } + } + if (IsVOPD3) { if (const MachineOperand *Src2 = TII.getNamedOperand(MI, AMDGPU::OpName::src2)) { if (AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::bitop3)) { // BITOP3 can be converted to DUAL_BITOP2 when src2 is zero. if (!Src2->isImm() || Src2->getImm()) return false; - } else if (MI.getOpcode() == AMDGPU::V_CNDMASK_B32_e64) { - UniqueScalarRegs.insert(Src2->getReg()); - } else if (!Src2->isReg() || !TRI->isVGPR(MRI, Src2->getReg())) { - return false; + } else { + if (!Src2->isReg()) + return false; + if (!isValidVOPDSrc(TII, VOPDOpc, CompIdx, 2, Src2->getReg())) + return false; + if (!TRI->isVectorRegister(MRI, Src2->getReg())) { + assert(MI.getOpcode() == AMDGPU::V_CNDMASK_B32_e64); + UniqueScalarRegs.insert(Src2->getReg()); + } } } for (auto OpName : {AMDGPU::OpName::clamp, AMDGPU::OpName::omod, _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
