[llvm] BPF: Fix misfolding subregisters (PR #208244)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 9 10:52:08 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/208244

>From 62d05be08a169b91347bc0ac652307a3133389e3 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         |  6 ++-
 .../CodeGen/BPF/mov32-64-subreg-source.mir    | 44 +++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)
 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 c6fa0bf6d23bc..2adf4ea6fdfe7 100644
--- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
@@ -155,7 +155,11 @@ bool BPFMIPeephole::isInsnFrom32Def(MachineInstr *DefInsn)
 
 bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI)
 {
-  MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg());
+  const MachineOperand &Src = MovMI->getOperand(1);
+  if (Src.getSubReg())
+    return false;
+
+  MachineInstr *DefInsn = MRI->getVRegDef(Src.getReg());
 
   LLVM_DEBUG(dbgs() << "  Def of Mov Src:");
   LLVM_DEBUG(DefInsn->dump());
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..6a83fec35fba2
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir
@@ -0,0 +1,44 @@
+# 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 -verify-machineinstrs %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: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[LD_imm64_]].sub_32
+    ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]]
+    ; 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