[llvm] [AMDGPU] Do not forward reserved aperture registers into wider copies (PR #220517)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 12:40:23 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/220517
>From 26cdf4980548bc8ad3f5a3c270730f6bfbc0392f Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 2 Sep 2026 10:41:17 +0200
Subject: [PATCH 1/4] [AMDGPU] Do not forward reserved aperture registers into
wider copies
src_shared_base/src_private_base have no addressable high half, so MachineCopyPropagation must not forward them into a copy that later splits into subregisters
SIInstrInfo::copyPhysReg now reports an error instead of asserting if asked to do so anyway
---
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 22 +++++++++++++
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 9 ++++++
.../AMDGPU/illegal-aperture-reg-copy.mir | 14 ++++++++
.../CodeGen/AMDGPU/machine-cp-aperture-reg.ll | 15 +++++++++
.../CodeGen/AMDGPU/machine-cp-propagation.mir | 32 +++++++++++++++++++
5 files changed, 92 insertions(+)
create mode 100644 llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
create mode 100644 llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 0568890583c1dd..2d165e7c59a472 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -821,6 +821,20 @@ bool MachineCopyPropagation::canUpdateSrcUsers(const MachineInstr &Copy,
return true;
}
+/// Return true if \p NewReg has a non-artificial subregister for every
+/// subregister index where \p OldReg has one.
+static bool hasMatchingSubRegs(MCRegister OldReg, MCRegister NewReg,
+ const TargetRegisterInfo *TRI) {
+ for (MCSubRegIndexIterator SRI(OldReg, TRI); SRI.isValid(); ++SRI) {
+ if (TRI->isArtificial(SRI.getSubReg()))
+ continue;
+ MCRegister Sub = TRI->getSubReg(NewReg, SRI.getSubRegIndex());
+ if (!Sub || TRI->isArtificial(Sub))
+ return false;
+ }
+ return true;
+}
+
/// Look for available copies whose destination register is used by \p MI and
/// replace the use in \p MI with the copy's source register.
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
@@ -879,6 +893,14 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
if (MRI->isReserved(CopySrc) && !MRI->isConstantPhysReg(CopySrc))
continue;
+ // A reserved source may lack subregs the copy is later split into.
+ if (MRI->isReserved(CopySrc) && isCopyInstr(MI, *TII, UseCopyInstr) &&
+ !hasMatchingSubRegs(MOUse.getReg().asMCReg(), ForwardedReg, TRI)) {
+ LLVM_DEBUG(dbgs() << "MCP: Copy source is missing subregisters of "
+ << printReg(MOUse.getReg(), TRI) << '\n');
+ continue;
+ }
+
if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
continue;
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 3094c1390e9cf2..db3fdf0ea81472 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -1189,6 +1189,15 @@ void SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
ArrayRef<int16_t> SubIndices = RI.getRegSplitParts(RC, EltSize);
+ // Report rather than assert if a register is missing a required subreg.
+ for (int16_t SubIdx : SubIndices) {
+ if (!RI.getSubReg(DestReg, SubIdx) || !RI.getSubReg(SrcReg, SubIdx)) {
+ reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc,
+ "Cannot decompose copy into subregister moves!");
+ return;
+ }
+ }
+
// If there is an overlap, we can't kill the super-register on the last
// instruction, since it will also kill the components made live by this def.
const bool Overlap = RI.regsOverlap(SrcReg, DestReg);
diff --git a/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir b/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
new file mode 100644
index 00000000000000..e3c5ac9abbe7f7
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
@@ -0,0 +1,14 @@
+# RUN: not llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -run-pass=postrapseudos -o /dev/null %s 2>&1 | FileCheck %s
+
+# src_shared_base has no addressable high half. copyPhysReg must not assert.
+
+# CHECK: error: {{.*}} in function illegal_aperture_reg_copy void (): Cannot decompose copy into subregister moves!
+
+---
+name: illegal_aperture_reg_copy
+tracksRegLiveness: true
+body: |
+ bb.0:
+ renamable $vgpr0_vgpr1 = COPY $src_shared_base
+ S_ENDPGM 0, implicit $vgpr0_vgpr1
+...
diff --git a/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
new file mode 100644
index 00000000000000..9e44e9e72973b1
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
@@ -0,0 +1,15 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -global-isel < %s | FileCheck %s
+
+; src_shared_base has no addressable high half. Must not forward into VGPRs.
+
+ at lds = internal addrspace(3) global [32 x float] poison, align 4
+
+; CHECK-LABEL: aperture_copy_to_vgpr_pair:
+; CHECK: s_mov_b64 s[{{[0-9]+}}:{{[0-9]+}}], src_shared_base
+define float @aperture_copy_to_vgpr_pair(i32 %i) {
+ %idx = zext i32 %i to i64
+ %gep = getelementptr float, ptr addrspacecast (ptr addrspace(3) @lds to ptr), i64 %idx
+ %cast = addrspacecast ptr %gep to ptr addrspace(3)
+ %v = load float, ptr addrspace(3) %cast, align 4
+ ret float %v
+}
diff --git a/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir b/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
index f8630245b69385..8cbd8cac4c5886 100644
--- a/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
+++ b/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
@@ -34,3 +34,35 @@ body: |
S_ENDPGM 0
...
+
+# src_shared_base has no addressable high half. machine-cp must not forward it.
+
+---
+name: no_forward_aperture_into_vgpr_copy
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: no_forward_aperture_into_vgpr_copy
+ ; CHECK: renamable $sgpr0_sgpr1 = COPY $src_shared_base
+ ; CHECK-NEXT: renamable $vgpr0_vgpr1 = COPY killed renamable $sgpr0_sgpr1
+ ; CHECK-NEXT: S_ENDPGM 0, implicit $vgpr0_vgpr1
+ renamable $sgpr0_sgpr1 = COPY $src_shared_base
+ renamable $vgpr0_vgpr1 = COPY killed renamable $sgpr0_sgpr1
+ S_ENDPGM 0, implicit $vgpr0_vgpr1
+...
+
+---
+name: forward_sgpr_into_vgpr_copy
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr4_sgpr5
+ ; CHECK-LABEL: name: forward_sgpr_into_vgpr_copy
+ ; CHECK: liveins: $sgpr4_sgpr5
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: renamable $vgpr0_vgpr1 = COPY $sgpr4_sgpr5
+ ; CHECK-NEXT: S_ENDPGM 0, implicit $vgpr0_vgpr1
+ renamable $sgpr0_sgpr1 = COPY $sgpr4_sgpr5
+ renamable $vgpr0_vgpr1 = COPY killed renamable $sgpr0_sgpr1
+ S_ENDPGM 0, implicit $vgpr0_vgpr1
+...
>From a646fee9f139cba7073e4913a14b50509d179782 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 8 Sep 2026 20:18:39 +0200
Subject: [PATCH 2/4] comments
---
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 33 ++++++++++---------
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 31 ++++++++++++-----
.../AMDGPU/illegal-aperture-reg-copy.mir | 14 --------
.../CodeGen/AMDGPU/machine-cp-aperture-reg.ll | 5 +--
.../CodeGen/AMDGPU/machine-cp-propagation.mir | 14 ++++----
.../AMDGPU/verify-copy-subreg-split.mir | 32 ++++++++++++++++++
6 files changed, 80 insertions(+), 49 deletions(-)
delete mode 100644 llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
create mode 100644 llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 2d165e7c59a472..c824d838283447 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -821,15 +821,14 @@ bool MachineCopyPropagation::canUpdateSrcUsers(const MachineInstr &Copy,
return true;
}
-/// Return true if \p NewReg has a non-artificial subregister for every
-/// subregister index where \p OldReg has one.
+/// Ignores artificial subregisters: copies never split into them, and
+/// requiring a match would reject pairs differing only in artificial shape.
static bool hasMatchingSubRegs(MCRegister OldReg, MCRegister NewReg,
- const TargetRegisterInfo *TRI) {
- for (MCSubRegIndexIterator SRI(OldReg, TRI); SRI.isValid(); ++SRI) {
- if (TRI->isArtificial(SRI.getSubReg()))
+ const TargetRegisterInfo &TRI) {
+ for (MCSubRegIndexIterator SRI(OldReg, &TRI); SRI.isValid(); ++SRI) {
+ if (TRI.isArtificial(SRI.getSubReg()))
continue;
- MCRegister Sub = TRI->getSubReg(NewReg, SRI.getSubRegIndex());
- if (!Sub || TRI->isArtificial(Sub))
+ if (!TRI.getSubReg(NewReg, SRI.getSubRegIndex()))
return false;
}
return true;
@@ -889,16 +888,18 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
}
}
- // Don't forward COPYs of reserved regs unless they are constant.
- if (MRI->isReserved(CopySrc) && !MRI->isConstantPhysReg(CopySrc))
- continue;
+ if (MRI->isReserved(CopySrc)) {
+ // Don't forward COPYs of reserved regs unless they are constant.
+ if (!MRI->isConstantPhysReg(CopySrc))
+ continue;
- // A reserved source may lack subregs the copy is later split into.
- if (MRI->isReserved(CopySrc) && isCopyInstr(MI, *TII, UseCopyInstr) &&
- !hasMatchingSubRegs(MOUse.getReg().asMCReg(), ForwardedReg, TRI)) {
- LLVM_DEBUG(dbgs() << "MCP: Copy source is missing subregisters of "
- << printReg(MOUse.getReg(), TRI) << '\n');
- continue;
+ // A reserved source may lack subregs the copy is later split into.
+ if (isCopyInstr(MI, *TII, UseCopyInstr) &&
+ !hasMatchingSubRegs(MOUse.getReg().asMCReg(), ForwardedReg, *TRI)) {
+ LLVM_DEBUG(dbgs() << "MCP: Copy source is missing subregisters of "
+ << printReg(MOUse.getReg(), TRI) << '\n');
+ continue;
+ }
}
if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 2e52c35c4b760b..77b49e3b430ad3 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -1193,15 +1193,6 @@ void SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
ArrayRef<int16_t> SubIndices = RI.getRegSplitParts(RC, 4);
- // Report rather than assert if a register is missing a required subreg.
- for (int16_t SubIdx : SubIndices) {
- if (!RI.getSubReg(DestReg, SubIdx) || !RI.getSubReg(SrcReg, SubIdx)) {
- reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc,
- "Cannot decompose copy into subregister moves!");
- return;
- }
- }
-
for (unsigned Idx{}; Idx < SubIndices.size();) {
unsigned NumRegs = 1;
unsigned ThisOpcode = Opcode;
@@ -5316,6 +5307,28 @@ bool SIInstrInfo::verifyCopy(const MachineInstr &MI,
ErrInfo = "illegal copy from vector register to SGPR";
return false;
}
+
+ if (!DstReg.isPhysical() || !SrcReg.isPhysical())
+ return true;
+
+ const TargetRegisterClass *RC = RI.getPhysRegBaseClass(DstReg);
+ const TargetRegisterClass *SrcRC = RI.getPhysRegBaseClass(SrcReg);
+ if (!RC || !SrcRC || RI.isSGPRClass(RC) || RI.getRegSizeInBits(*RC) <= 32)
+ return true;
+
+ // Copies handled by a single 64-bit move are not decomposed.
+ if (RC == RI.getVGPR64Class() && (SrcRC == RC || RI.isSGPRClass(SrcRC)) &&
+ (ST.hasVMovB64Inst() || ST.hasPkMovB32()))
+ return true;
+
+ // Other wide vector copies split into per-subregister moves.
+ for (int16_t SubIdx : RI.getRegSplitParts(RC, 4)) {
+ if (!RI.getSubReg(DstReg, SubIdx) || !RI.getSubReg(SrcReg, SubIdx)) {
+ ErrInfo = "cannot decompose copy into subregister moves";
+ return false;
+ }
+ }
+
return true;
}
diff --git a/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir b/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
deleted file mode 100644
index e3c5ac9abbe7f7..00000000000000
--- a/llvm/test/CodeGen/AMDGPU/illegal-aperture-reg-copy.mir
+++ /dev/null
@@ -1,14 +0,0 @@
-# RUN: not llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -run-pass=postrapseudos -o /dev/null %s 2>&1 | FileCheck %s
-
-# src_shared_base has no addressable high half. copyPhysReg must not assert.
-
-# CHECK: error: {{.*}} in function illegal_aperture_reg_copy void (): Cannot decompose copy into subregister moves!
-
----
-name: illegal_aperture_reg_copy
-tracksRegLiveness: true
-body: |
- bb.0:
- renamable $vgpr0_vgpr1 = COPY $src_shared_base
- S_ENDPGM 0, implicit $vgpr0_vgpr1
-...
diff --git a/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
index 9e44e9e72973b1..0dcddca9966628 100644
--- a/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
+++ b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
@@ -1,10 +1,11 @@
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -global-isel < %s | FileCheck %s
+; RUN: llc -global-isel -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck %s
; src_shared_base has no addressable high half. Must not forward into VGPRs.
@lds = internal addrspace(3) global [32 x float] poison, align 4
-; CHECK-LABEL: aperture_copy_to_vgpr_pair:
+; CHECK-LABEL: {{^}}aperture_copy_to_vgpr_pair:
+; CHECK-NOT: v_mov_b32{{.*}}src_shared_base
; CHECK: s_mov_b64 s[{{[0-9]+}}:{{[0-9]+}}], src_shared_base
define float @aperture_copy_to_vgpr_pair(i32 %i) {
%idx = zext i32 %i to i64
diff --git a/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir b/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
index 8cbd8cac4c5886..4aaf5bd8a5d8e8 100644
--- a/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
+++ b/llvm/test/CodeGen/AMDGPU/machine-cp-propagation.mir
@@ -34,7 +34,6 @@ body: |
S_ENDPGM 0
...
-
# src_shared_base has no addressable high half. machine-cp must not forward it.
---
@@ -51,18 +50,17 @@ body: |
S_ENDPGM 0, implicit $vgpr0_vgpr1
...
+# sgpr_null64 is also reserved, but it has both halves, so forwarding is fine.
+
---
-name: forward_sgpr_into_vgpr_copy
+name: forward_null_into_vgpr_copy
tracksRegLiveness: true
body: |
bb.0:
- liveins: $sgpr4_sgpr5
- ; CHECK-LABEL: name: forward_sgpr_into_vgpr_copy
- ; CHECK: liveins: $sgpr4_sgpr5
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: renamable $vgpr0_vgpr1 = COPY $sgpr4_sgpr5
+ ; CHECK-LABEL: name: forward_null_into_vgpr_copy
+ ; CHECK: renamable $vgpr0_vgpr1 = COPY $sgpr_null64
; CHECK-NEXT: S_ENDPGM 0, implicit $vgpr0_vgpr1
- renamable $sgpr0_sgpr1 = COPY $sgpr4_sgpr5
+ renamable $sgpr0_sgpr1 = COPY $sgpr_null64
renamable $vgpr0_vgpr1 = COPY killed renamable $sgpr0_sgpr1
S_ENDPGM 0, implicit $vgpr0_vgpr1
...
diff --git a/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir b/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
new file mode 100644
index 00000000000000..3a0a68f92cef84
--- /dev/null
+++ b/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
@@ -0,0 +1,32 @@
+# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -run-pass=none -filetype=null %s 2>&1 | FileCheck -implicit-check-not="Bad machine code" %s
+# gfx942 expands this into a single V_MOV_B64, so it needs no subregisters.
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -run-pass=none -filetype=null %s 2>&1 | FileCheck -check-prefix=GFX942 -implicit-check-not="Bad machine code" %s
+
+# src_shared_base has no addressable high half, so the copy cannot be split.
+
+# CHECK: *** Bad machine code: cannot decompose copy into subregister moves ***
+# GFX942: name: illegal_aperture_reg_copy
+
+---
+name: illegal_aperture_reg_copy
+# isSSA: false is required, the COPY check only runs after SSA.
+isSSA: false
+tracksRegLiveness: true
+body: |
+ bb.0:
+ renamable $vgpr0_vgpr1 = COPY $src_shared_base
+ S_ENDPGM 0, implicit $vgpr0_vgpr1
+...
+
+# $pc_reg belongs to no register class, so it has no base class to query.
+
+---
+name: copy_reg_without_base_class
+isSSA: false
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $sgpr0_sgpr1
+ $pc_reg = COPY $sgpr0_sgpr1
+ S_ENDPGM 0
+...
>From 3b42e5633d68d7bd0a10f4114b3d6e5969f4ad66 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 8 Sep 2026 22:10:15 +0200
Subject: [PATCH 3/4] triples
---
llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
index 0dcddca9966628..bcea04d2686334 100644
--- a/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
+++ b/llvm/test/CodeGen/AMDGPU/machine-cp-aperture-reg.ll
@@ -1,4 +1,4 @@
-; RUN: llc -global-isel -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck %s
+; RUN: llc -global-isel -mtriple=amdgpu11.00-amd-amdhsa < %s | FileCheck %s
; src_shared_base has no addressable high half. Must not forward into VGPRs.
>From 611eddb34b47eb4ad469ec1b8563e90c5cf1d54f Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Sun, 13 Sep 2026 21:37:40 +0200
Subject: [PATCH 4/4] address remarks
---
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 25 +++++++++++--------
.../AMDGPU/verify-copy-subreg-split.mir | 4 +--
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index c824d838283447..5490e3b97d9594 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -888,18 +888,21 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
}
}
- if (MRI->isReserved(CopySrc)) {
- // Don't forward COPYs of reserved regs unless they are constant.
- if (!MRI->isConstantPhysReg(CopySrc))
- continue;
+ // Don't forward COPYs of reserved regs unless they are constant.
+ if (MRI->isReserved(CopySrc) && !MRI->isConstantPhysReg(CopySrc))
+ continue;
- // A reserved source may lack subregs the copy is later split into.
- if (isCopyInstr(MI, *TII, UseCopyInstr) &&
- !hasMatchingSubRegs(MOUse.getReg().asMCReg(), ForwardedReg, *TRI)) {
- LLVM_DEBUG(dbgs() << "MCP: Copy source is missing subregisters of "
- << printReg(MOUse.getReg(), TRI) << '\n');
- continue;
- }
+ // The forwarded register may lack subregs the copy is later split into.
+ const TargetRegisterClass *OldRC =
+ TRI->getMinimalPhysRegClass(MOUse.getReg());
+ const TargetRegisterClass *NewRC =
+ TRI->getMinimalPhysRegClass(ForwardedReg);
+ if (TRI->getCommonSubClass(OldRC, NewRC) &&
+ isCopyInstr(MI, *TII, UseCopyInstr) &&
+ !hasMatchingSubRegs(MOUse.getReg().asMCReg(), ForwardedReg, *TRI)) {
+ LLVM_DEBUG(dbgs() << "MCP: Copy source is missing subregisters of "
+ << printReg(MOUse.getReg(), TRI) << '\n');
+ continue;
}
if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
diff --git a/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir b/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
index 3a0a68f92cef84..d275ccef2331aa 100644
--- a/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
+++ b/llvm/test/MachineVerifier/AMDGPU/verify-copy-subreg-split.mir
@@ -1,6 +1,6 @@
-# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -run-pass=none -filetype=null %s 2>&1 | FileCheck -implicit-check-not="Bad machine code" %s
+# RUN: not --crash llc -mtriple=amdgpu11.00-amd-amdhsa -run-pass=none -filetype=null %s 2>&1 | FileCheck -implicit-check-not="Bad machine code" %s
# gfx942 expands this into a single V_MOV_B64, so it needs no subregisters.
-# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -run-pass=none -filetype=null %s 2>&1 | FileCheck -check-prefix=GFX942 -implicit-check-not="Bad machine code" %s
+# RUN: llc -mtriple=amdgpu9.42-amd-amdhsa -run-pass=none -filetype=null %s 2>&1 | FileCheck -check-prefix=GFX942 -implicit-check-not="Bad machine code" %s
# src_shared_base has no addressable high half, so the copy cannot be split.
More information about the llvm-commits
mailing list