Skip to content

Commit 547d52f

Browse files
committed
Fixes #130020
This fixes an issue where the si-fold-operands pass would incorrectly fold immediate values into COPY instructions targeting av_32 registers, which is illegal. The pass now properly checks register class constraints before attempting to fold the immediates.
1 parent 26a3099 commit 547d52f

File tree

2 files changed

+72
-50
lines changed

2 files changed

+72
-50
lines changed

llvm/lib/Target/AMDGPU/SIFoldOperands.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,15 +1068,19 @@ void SIFoldOperandsImpl::foldOperand(
10681068
if (MovOp == AMDGPU::COPY)
10691069
return;
10701070

1071-
// Fold if the destination register class of the MOV instruction (ResRC)
1072-
// is a superclass of (or equal to) the destination register class of the COPY (DestRC).
1073-
// If this condition fails, folding would be illegal.
1071+
// Check for common register subclass between destination (DestRC) and MOV
1072+
// result (ResRC). If exists, verify this common subclass is a superclass of
1073+
// (or equal to) the destination register class, otherwise folding is
1074+
// illegal.
1075+
10741076
const MCInstrDesc &MovDesc = TII->get(MovOp);
1075-
if (MovDesc.getNumDefs() > 0 && MovDesc.operands()[0].RegClass != -1) {
1076-
const TargetRegisterClass *ResRC =
1077-
TRI->getRegClass(MovDesc.operands()[0].RegClass);
1078-
if (!DestRC -> hasSuperClassEq(ResRC)) return;
1079-
}
1077+
assert(MovDesc.getNumDefs() > 0 && MovDesc.operands()[0].RegClass != -1);
1078+
const TargetRegisterClass *ResRC =
1079+
TRI->getRegClass(MovDesc.operands()[0].RegClass);
1080+
const TargetRegisterClass *CommonRC = TRI->getCommonSubClass(DestRC, ResRC);
1081+
1082+
if (!CommonRC || !DestRC->hasSuperClassEq(CommonRC))
1083+
return;
10801084

10811085
MachineInstr::mop_iterator ImpOpI = UseMI->implicit_operands().begin();
10821086
MachineInstr::mop_iterator ImpOpE = UseMI->implicit_operands().end();

llvm/test/CodeGen/AMDGPU/fold-imm-copy.mir

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -208,52 +208,70 @@ body: |
208208
209209
...
210210

211-
# FIXME: Register class restrictions of av register not respected,
212-
# issue 130020
211+
---
212+
name: s_mov_b32_inlineimm_copy_s_to_av_32
213+
tracksRegLiveness: true
214+
body: |
215+
bb.0:
216+
; GCN-LABEL: name: s_mov_b32_inlineimm_copy_s_to_av_32
217+
; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 32
218+
; GCN-NEXT: [[COPY:%[0-9]+]]:av_32 = COPY [[S_MOV_B32_]]
219+
; GCN-NEXT: $agpr0 = COPY [[COPY]]
220+
; GCN-NEXT: S_ENDPGM 0
221+
%0:sreg_32 = S_MOV_B32 32
222+
%1:av_32 = COPY %0
223+
$agpr0 = COPY %1
224+
S_ENDPGM 0
213225
214-
# ---
215-
# name: s_mov_b32_inlineimm_copy_s_to_av_32
216-
# tracksRegLiveness: true
217-
# body: |
218-
# bb.0:
219-
# %0:sreg_32 = S_MOV_B32 32
220-
# %1:av_32 = COPY %0
221-
# $agpr0 = COPY %1
222-
# S_ENDPGM 0
226+
...
223227

224-
# ...
228+
---
229+
name: v_mov_b32_inlineimm_copy_v_to_av_32
230+
tracksRegLiveness: true
231+
body: |
232+
bb.0:
233+
; GCN-LABEL: name: v_mov_b32_inlineimm_copy_v_to_av_32
234+
; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 32, implicit $exec
235+
; GCN-NEXT: [[COPY:%[0-9]+]]:av_32 = COPY [[V_MOV_B32_e32_]]
236+
; GCN-NEXT: $agpr0 = COPY [[COPY]]
237+
; GCN-NEXT: S_ENDPGM 0
238+
%0:vgpr_32 = V_MOV_B32_e32 32, implicit $exec
239+
%1:av_32 = COPY %0
240+
$agpr0 = COPY %1
241+
S_ENDPGM 0
225242

226-
# ---
227-
# name: v_mov_b32_inlineimm_copy_v_to_av_32
228-
# tracksRegLiveness: true
229-
# body: |
230-
# bb.0:
231-
# %0:vgpr_32 = V_MOV_B32_e32 32, implicit $exec
232-
# %1:av_32 = COPY %0
233-
# $agpr0 = COPY %1
234-
# S_ENDPGM 0
235-
# ...
243+
...
236244

237-
# ---
238-
# name: s_mov_b32_imm_literal_copy_s_to_av_32
239-
# tracksRegLiveness: true
240-
# body: |
241-
# bb.0:
242-
# %0:sreg_32 = S_MOV_B32 999
243-
# %1:av_32 = COPY %0
244-
# $agpr0 = COPY %1
245-
# S_ENDPGM 0
245+
---
246+
name: s_mov_b32_imm_literal_copy_s_to_av_32
247+
tracksRegLiveness: true
248+
body: |
249+
bb.0:
250+
; GCN-LABEL: name: s_mov_b32_imm_literal_copy_s_to_av_32
251+
; GCN: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 999
252+
; GCN-NEXT: [[COPY:%[0-9]+]]:av_32 = COPY [[S_MOV_B32_]]
253+
; GCN-NEXT: $agpr0 = COPY [[COPY]]
254+
; GCN-NEXT: S_ENDPGM 0
255+
%0:sreg_32 = S_MOV_B32 999
256+
%1:av_32 = COPY %0
257+
$agpr0 = COPY %1
258+
S_ENDPGM 0
246259
247-
# ...
260+
...
248261

249-
# ---
250-
# name: v_mov_b32_imm_literal_copy_v_to_av_32
251-
# tracksRegLiveness: true
252-
# body: |
253-
# bb.0:
254-
# %0:vgpr_32 = V_MOV_B32_e32 999, implicit $exec
255-
# %1:av_32 = COPY %0
256-
# $agpr0 = COPY %1
257-
# S_ENDPGM 0
262+
---
263+
name: v_mov_b32_imm_literal_copy_v_to_av_32
264+
tracksRegLiveness: true
265+
body: |
266+
bb.0:
267+
; GCN-LABEL: name: v_mov_b32_imm_literal_copy_v_to_av_32
268+
; GCN: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 999, implicit $exec
269+
; GCN-NEXT: [[COPY:%[0-9]+]]:av_32 = COPY [[V_MOV_B32_e32_]]
270+
; GCN-NEXT: $agpr0 = COPY [[COPY]]
271+
; GCN-NEXT: S_ENDPGM 0
272+
%0:vgpr_32 = V_MOV_B32_e32 999, implicit $exec
273+
%1:av_32 = COPY %0
274+
$agpr0 = COPY %1
275+
S_ENDPGM 0
258276
259-
# ...
277+
...

0 commit comments

Comments
 (0)