[llvm] BPF: Fix misfolding subregisters (PR #208244)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 8 08:42:56 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/208244
This would end up introducing a copy between registers
with mismatched sizes previously. Defends against verifier
failures in a future change.
The actual transform here should be deleted. Optimizations should
not be trying to introduce SUBREG_TO_REG.
>From 2fc4cd3ef7d7d42ae95b9d26fd699babfe5a7366 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 8 Jul 2026 09:46:53 +0200
Subject: [PATCH] BPF: Fix misfolding subregisters
This would end up introducing a copy between registers
with mismatched sizes previously. Defends against verifier
failures in a future change.
The actual transform here should be deleted. Optimizations should
not be trying to introduce SUBREG_TO_REG.
---
llvm/lib/Target/BPF/BPFMIPeephole.cpp | 11 +++--
.../CodeGen/BPF/mov32-64-subreg-source.mir | 43 +++++++++++++++++++
2 files changed, 50 insertions(+), 4 deletions(-)
create mode 100644 llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir
diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
index 637872ee2ebb8..d39259f074993 100644
--- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
@@ -48,6 +48,7 @@ struct BPFMIPeephole : public MachineFunctionPass {
static char ID;
const BPFInstrInfo *TII;
+ const BPFRegisterInfo *TRI;
MachineFunction *MF;
MachineRegisterInfo *MRI;
@@ -89,6 +90,7 @@ void BPFMIPeephole::initialize(MachineFunction &MFParm) {
MF = &MFParm;
MRI = &MF->getRegInfo();
TII = MF->getSubtarget<BPFSubtarget>().getInstrInfo();
+ TRI = &TII->getRegisterInfo();
LLVM_DEBUG(dbgs() << "*** BPF MachineSSA ZEXT Elim peephole pass ***\n\n");
}
@@ -96,9 +98,6 @@ bool BPFMIPeephole::isCopyFrom32Def(MachineInstr *CopyMI)
{
MachineOperand &opnd = CopyMI->getOperand(1);
- if (!opnd.isReg())
- return false;
-
// Return false if getting value from a 32bit physical register.
// Most likely, this physical register is aliased to
// function call return value or current function parameters.
@@ -106,7 +105,11 @@ bool BPFMIPeephole::isCopyFrom32Def(MachineInstr *CopyMI)
if (!Reg.isVirtual())
return false;
- if (MRI->getRegClass(Reg) == &BPF::GPRRegClass)
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+ if (unsigned SubReg = opnd.getSubReg())
+ RC = TRI->getSubRegisterClass(RC, SubReg);
+
+ if (!RC->hasSubClassEq(&BPF::GPRRegClass))
return false;
MachineInstr *DefInsn = MRI->getVRegDef(Reg);
diff --git a/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir
new file mode 100644
index 0000000000000..35ab96b279406
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir
@@ -0,0 +1,43 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple=bpfel -mattr=+alu32 -run-pass=bpf-mi-zext-elim %s -o - | FileCheck %s
+
+# Make sure that folds of MOV_32_64 respect a subregister index on the
+# source operand.
+
+---
+name: mov32_64_subreg_source_imm
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $r1
+ ; CHECK-LABEL: name: mov32_64_subreg_source_imm
+ ; CHECK: liveins: $r1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[LD_imm64_:%[0-9]+]]:gpr = LD_imm64 0
+ ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr = SUBREG_TO_REG [[LD_imm64_]], %subreg.sub_32
+ ; CHECK-NEXT: $r0 = COPY [[SUBREG_TO_REG]]
+ ; CHECK-NEXT: RET implicit $r0
+ %0:gpr = LD_imm64 0
+ %1:gpr = MOV_32_64 %0.sub_32
+ $r0 = COPY %1:gpr
+ RET implicit $r0
+...
+
+---
+name: mov32_64_subreg_source_copy
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $r1
+ ; CHECK-LABEL: name: mov32_64_subreg_source_copy
+ ; CHECK: liveins: $r1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r1
+ ; CHECK-NEXT: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[COPY]].sub_32
+ ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]]
+ ; CHECK-NEXT: RET implicit $r0
+ %0:gpr = COPY $r1
+ %1:gpr = MOV_32_64 %0.sub_32
+ $r0 = COPY %1:gpr
+ RET implicit $r0
+...
More information about the llvm-commits
mailing list