[llvm] [AMDGPU] Fix verifier false positive for AV-class atomic registers (PR #212721)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 29 02:21:38 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/212721
>From d34fb47ed768ba63dff2bb103b6c6a6347b7a30e Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 29 Jul 2026 10:59:28 +0200
Subject: [PATCH 1/2] [AMDGPU] Fix verifier false positive for AV-class atomic
registers
AV-class registers can hold either a VGPR or an AGPR, but isAGPR() always returned false for them
This led to verifyInstruction wrongly rejecting valid atomic instructions when an AV-class register was paired with a real AGPR
---
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 10 ++++++++--
.../AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir | 6 ------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index b2c3772cb0041..25e903cf41e0f 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -5854,14 +5854,20 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
Data = nullptr;
if (ST.hasGFX90AInsts()) {
+ auto IsAGPRFileMismatch = [&](Register X, Register Y) {
+ if (RI.isVectorSuperClass(RI.getRegClassForReg(MRI, X)) ||
+ RI.isVectorSuperClass(RI.getRegClassForReg(MRI, Y)))
+ return false;
+ return RI.isAGPR(MRI, X) != RI.isAGPR(MRI, Y);
+ };
if (Dst && Data && !Dst->isTied() && !Data->isTied() &&
- (RI.isAGPR(MRI, Dst->getReg()) != RI.isAGPR(MRI, Data->getReg()))) {
+ IsAGPRFileMismatch(Dst->getReg(), Data->getReg())) {
ErrInfo = "Invalid register class: "
"vdata and vdst should be both VGPR or AGPR";
return false;
}
if (Data && Data2 &&
- (RI.isAGPR(MRI, Data->getReg()) != RI.isAGPR(MRI, Data2->getReg()))) {
+ IsAGPRFileMismatch(Data->getReg(), Data2->getReg())) {
ErrInfo = "Invalid register class: "
"both data operands should be VGPR or AGPR";
return false;
diff --git a/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir b/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
index dc01507df5e26..15773a6485425 100644
--- a/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
+++ b/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
@@ -32,25 +32,21 @@ body: |
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%9:vgpr_32 = DS_CMPST_RTN_B32_gfx9 %vgpr, %vgpr, %a_or_v, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: vdata and vdst should be both VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%10:av_32 = DS_CMPST_RTN_B32_gfx9 %addr, %agpr, %agpr, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: vdata and vdst should be both VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%11:agpr_32 = DS_CMPST_RTN_B32_gfx9 %addr, %a_or_v, %agpr, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%12:agpr_32 = DS_CMPST_RTN_B32_gfx9 %addr, %agpr, %a_or_v, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: vdata and vdst should be both VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
@@ -79,12 +75,10 @@ body: |
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %a_or_v, %vgpr, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %agpr, %a_or_v, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %a_or_v, %agpr, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
>From 640d5ad13ff06600ba3c5ea148689ba0675f1113 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 29 Jul 2026 11:21:11 +0200
Subject: [PATCH 2/2] rm
---
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 21 +------------------
...verify-ds-vdata-vdst-both-agpr-or-vgpr.mir | 5 -----
2 files changed, 1 insertion(+), 25 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 25e903cf41e0f..0b07d970654bd 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -5853,26 +5853,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
if (Data && !Data->isReg())
Data = nullptr;
- if (ST.hasGFX90AInsts()) {
- auto IsAGPRFileMismatch = [&](Register X, Register Y) {
- if (RI.isVectorSuperClass(RI.getRegClassForReg(MRI, X)) ||
- RI.isVectorSuperClass(RI.getRegClassForReg(MRI, Y)))
- return false;
- return RI.isAGPR(MRI, X) != RI.isAGPR(MRI, Y);
- };
- if (Dst && Data && !Dst->isTied() && !Data->isTied() &&
- IsAGPRFileMismatch(Dst->getReg(), Data->getReg())) {
- ErrInfo = "Invalid register class: "
- "vdata and vdst should be both VGPR or AGPR";
- return false;
- }
- if (Data && Data2 &&
- IsAGPRFileMismatch(Data->getReg(), Data2->getReg())) {
- ErrInfo = "Invalid register class: "
- "both data operands should be VGPR or AGPR";
- return false;
- }
- } else {
+ if (!ST.hasGFX90AInsts()) {
if ((Dst && RI.isAGPR(MRI, Dst->getReg())) ||
(Data && RI.isAGPR(MRI, Data->getReg())) ||
(Data2 && RI.isAGPR(MRI, Data2->getReg()))) {
diff --git a/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir b/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
index 15773a6485425..75d1d6152c886 100644
--- a/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
+++ b/llvm/test/MachineVerifier/AMDGPU/verify-ds-vdata-vdst-both-agpr-or-vgpr.mir
@@ -11,15 +11,12 @@ body: |
%agpr:agpr_32 = IMPLICIT_DEF
%a_or_v:av_32 = IMPLICIT_DEF
- ; CHECK: Bad machine code: Invalid register class: vdata and vdst should be both VGPR or AGPR
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%4:agpr_32 = DS_CMPST_RTN_B32_gfx9 %addr, %vgpr, %vgpr, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: Bad machine code: Invalid register class: vdata and vdst should be both VGPR or AGPR
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%5:vgpr_32 = DS_CMPST_RTN_B32_gfx9 %addr, %agpr, %vgpr, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
%6:vgpr_32 = DS_CMPST_RTN_B32_gfx9 %addr, %vgpr, %agpr, 0, 0, implicit $exec :: (load store seq_cst monotonic (s32), addrspace 3)
@@ -61,11 +58,9 @@ body: |
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %a_or_v, %a_or_v, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %agpr, %vgpr, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
- ; CHECK: *** Bad machine code: Invalid register class: both data operands should be VGPR or AGPR ***
; CHECK: *** Bad machine code: Illegal virtual register for instruction ***
DS_WRITE2_B32_gfx9 %addr, %vgpr, %agpr, 10, 24, 0, implicit $exec :: (store (s32), addrspace 3), (store (s32), addrspace 3)
More information about the llvm-commits
mailing list