Skip to content

Commit 60a8b2b

Browse files
author
Aditi Medhane
authored
[AMDGPU] Add MachineVerifier check to detect illegal copies from vector register to SGPR (#105494)
Addition of a check in the MachineVerifier to detect and report illegal vector registers to SGPR copies in the AMDGPU backend, ensuring correct code generation. We can enforce this check only after SIFixSGPRCopies pass. This is half-fix in the pipeline with the help of isSSA MachineFuction property, the check is happening for passes after phi-node-elimination.
1 parent 959448f commit 60a8b2b

File tree

5 files changed

+92
-9
lines changed

5 files changed

+92
-9
lines changed

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4600,15 +4600,38 @@ static bool isSubRegOf(const SIRegisterInfo &TRI,
46004600
SubReg.getReg() == SuperVec.getReg();
46014601
}
46024602

4603+
// Verify the illegal copy from vector register to SGPR for generic opcode COPY
4604+
bool SIInstrInfo::verifyCopy(const MachineInstr &MI,
4605+
const MachineRegisterInfo &MRI,
4606+
StringRef &ErrInfo) const {
4607+
Register DstReg = MI.getOperand(0).getReg();
4608+
Register SrcReg = MI.getOperand(1).getReg();
4609+
// This is a check for copy from vector register to SGPR
4610+
if (RI.isVectorRegister(MRI, SrcReg) && RI.isSGPRReg(MRI, DstReg)) {
4611+
ErrInfo = "illegal copy from vector register to SGPR";
4612+
return false;
4613+
}
4614+
return true;
4615+
}
4616+
46034617
bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
46044618
StringRef &ErrInfo) const {
46054619
uint16_t Opcode = MI.getOpcode();
4606-
if (SIInstrInfo::isGenericOpcode(MI.getOpcode()))
4607-
return true;
4608-
46094620
const MachineFunction *MF = MI.getParent()->getParent();
46104621
const MachineRegisterInfo &MRI = MF->getRegInfo();
46114622

4623+
// FIXME: At this point the COPY verify is done only for non-ssa forms.
4624+
// Find a better property to recognize the point where instruction selection
4625+
// is just done.
4626+
// We can only enforce this check after SIFixSGPRCopies pass so that the
4627+
// illegal copies are legalized and thereafter we don't expect a pass
4628+
// inserting similar copies.
4629+
if (!MRI.isSSA() && MI.isCopy())
4630+
return verifyCopy(MI, MRI, ErrInfo);
4631+
4632+
if (SIInstrInfo::isGenericOpcode(MI.getOpcode()))
4633+
return true;
4634+
46124635
int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
46134636
int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
46144637
int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);

llvm/lib/Target/AMDGPU/SIInstrInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
178178

179179
Register findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
180180

181+
bool verifyCopy(const MachineInstr &MI, const MachineRegisterInfo &MRI,
182+
StringRef &ErrInfo) const;
183+
181184
protected:
182185
/// If the specific machine instruction is a instruction that moves/copies
183186
/// value from one register to another register return destination and source

llvm/test/CodeGen/AMDGPU/phi-vgpr-input-moveimm.mir

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ body: |
112112
S_BRANCH %bb.2
113113
...
114114

115-
116115
---
117116
name: phi_moveimm_bad_opcode_input
118117
tracksRegLiveness: true

llvm/test/CodeGen/AMDGPU/wqm.mir

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ body: |
190190
# Ensure that strict_wwm is not put around an EXEC copy
191191
#CHECK-LABEL: name: copy_exec
192192
#CHECK: %7:sreg_64 = COPY $exec
193-
#CHECK-NEXT: %14:sreg_64 = ENTER_STRICT_WWM -1, implicit-def $exec, implicit-def $scc, implicit $exec
193+
#CHECK-NEXT: %13:sreg_64 = ENTER_STRICT_WWM -1, implicit-def $exec, implicit-def $scc, implicit $exec
194194
#CHECK-NEXT: %8:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
195-
#CHECK-NEXT: $exec = EXIT_STRICT_WWM %14
195+
#CHECK-NEXT: $exec = EXIT_STRICT_WWM %13
196196
#CHECK-NEXT: %9:vgpr_32 = V_MBCNT_LO_U32_B32_e64 %7.sub0, 0, implicit $exec
197197
name: copy_exec
198198
tracksRegLiveness: true
@@ -213,10 +213,9 @@ body: |
213213
%10:vgpr_32 = V_MBCNT_LO_U32_B32_e64 %8.sub0:sreg_64, 0, implicit $exec
214214
%11:vgpr_32 = V_MOV_B32_dpp %9:vgpr_32, %10:vgpr_32, 312, 15, 15, 0, implicit $exec
215215
%12:sreg_32 = V_READLANE_B32 %11:vgpr_32, 63
216-
early-clobber %13:sreg_32 = STRICT_WWM %9:vgpr_32, implicit $exec
216+
early-clobber %13:vgpr_32 = STRICT_WWM %9:vgpr_32, implicit $exec
217217
218-
%14:vgpr_32 = COPY %13
219-
BUFFER_STORE_DWORD_OFFSET_exact killed %14, %4, %5, 4, 0, 0, implicit $exec
218+
BUFFER_STORE_DWORD_OFFSET_exact killed %13, %4, %5, 4, 0, 0, implicit $exec
220219
S_ENDPGM 0
221220
222221
...
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# RUN: not --crash llc -march=amdgcn -mcpu=gfx1200 -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
2+
3+
---
4+
name: fix-illegal-vector-copies
5+
tracksRegLiveness: true
6+
machineFunctionInfo:
7+
isEntryFunction: true
8+
body: |
9+
bb.0:
10+
%0:vgpr_32 = IMPLICIT_DEF
11+
%0:vgpr_32 = IMPLICIT_DEF ; Break SSA format
12+
%1:vgpr_32 = IMPLICIT_DEF
13+
%2:sgpr_32 = IMPLICIT_DEF
14+
%3:sgpr_32 = IMPLICIT_DEF
15+
%4:agpr_32 = IMPLICIT_DEF
16+
%5:agpr_32 = IMPLICIT_DEF
17+
18+
; copy from virtual VGPR to virtual SGPR
19+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
20+
; CHECK: - instruction: %6:sgpr_32 = COPY %0:vgpr_32
21+
%6:sgpr_32 = COPY %0:vgpr_32
22+
23+
; copy from virtual VGPR to physical SGPR
24+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
25+
; CHECK: - instruction: $sgpr0 = COPY %0:vgpr_32
26+
$sgpr0 = COPY %0:vgpr_32
27+
28+
; copy from physical VGPR to physical SGPR
29+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
30+
; CHECK: - instruction: $sgpr1 = COPY $vgpr0
31+
$sgpr1 = COPY $vgpr0
32+
33+
; copy from virtual AGPR to virtual SGPR
34+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
35+
; CHECK: - instruction: %7:sgpr_32 = COPY %4:agpr_32
36+
%7:sgpr_32 = COPY %4:agpr_32
37+
38+
; copy from virtual AGPR to physical SGPR
39+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
40+
; CHECK: - instruction: $sgpr2 = COPY %4:agpr_32
41+
$sgpr2 = COPY %4:agpr_32
42+
43+
; copy from physical AGPR to physical SGPR
44+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
45+
; CHECK: - instruction: $sgpr3 = COPY $agpr0
46+
$sgpr3 = COPY $agpr0
47+
48+
; copy from tuple of physical VGPRs to tuple of physical SGPRs
49+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
50+
; CHECK: - instruction: $sgpr4_sgpr5 = COPY $vgpr0_vgpr1
51+
$sgpr4_sgpr5 = COPY $vgpr0_vgpr1
52+
53+
; copy from tuple of physical AGPRs to tuple of physical SGPRs
54+
; CHECK: *** Bad machine code: illegal copy from vector register to SGPR ***
55+
; CHECK: - instruction: $sgpr6_sgpr7 = COPY $agpr0_agpr1
56+
$sgpr6_sgpr7 = COPY $agpr0_agpr1
57+
58+
S_ENDPGM 0
59+
...

0 commit comments

Comments
 (0)