[llvm-branch-commits] [llvm] AMDGPU: Validate VOPD/VOPD3 physical source registers against operand RC (PR #196515)
Petar Avramovic via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jul 21 04:34:48 PDT 2026
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 <Petar.Avramovic at amd.com>
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,
More information about the llvm-branch-commits
mailing list