[llvm] [X86][GlobalISel] Ignore non-vregs in regbank mapping (PR #182880)

Tommy Chiang via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 21 10:35:57 PDT 2026


https://github.com/oToToT updated https://github.com/llvm/llvm-project/pull/182880

>From 93b05c0c9c43c93d590c19d34043f254bb1a0db7 Mon Sep 17 00:00:00 2001
From: Tommy Chiang <ototot at google.com>
Date: Mon, 23 Feb 2026 22:04:16 +0800
Subject: [PATCH] [X86][GlobalISel] Ignore non-vregs in regbank mapping

`X86RegisterBankInfo`'s regbank-mapping helpers work under the
assumption that every register operand was a typed virtual register.

This caused `RegBankSelect` crashes when such operands reached these
helpers:
* `getInstrPartialMappingIdxs` called `MRI.getType()` on a non-vreg
  operand.
* `getInstrValueMapping` then called `getValueMapping(PMI_None, ...)`
  for it.

Skip non-virtual register operands in both helpers. This keeps non-vregs
out of LLT/mapping logic while still mapping real vreg operands.

Fixes https://github.com/llvm/llvm-project/issues/182735
---
 .../Target/X86/GISel/X86RegisterBankInfo.cpp  |  4 +--
 .../regbankselect-dbg-value-physreg-crash.ll  | 26 ++++++++++++++
 .../regbankselect-dbg-value-physreg-crash.mir | 34 +++++++++++++++++++
 3 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.ll
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.mir

diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
index b23d791501729..8764cfc44613f 100644
--- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp
@@ -201,7 +201,7 @@ void X86RegisterBankInfo::getInstrPartialMappingIdxs(
   unsigned NumOperands = MI.getNumOperands();
   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
     auto &MO = MI.getOperand(Idx);
-    if (!MO.isReg() || !MO.getReg())
+    if (!MO.isReg() || !MO.getReg().isVirtual())
       OpRegBankIdx[Idx] = PMI_None;
     else
       OpRegBankIdx[Idx] =
@@ -218,7 +218,7 @@ bool X86RegisterBankInfo::getInstrValueMapping(
   for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
     if (!MI.getOperand(Idx).isReg())
       continue;
-    if (!MI.getOperand(Idx).getReg())
+    if (!MI.getOperand(Idx).getReg().isVirtual())
       continue;
 
     auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
diff --git a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.ll b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.ll
new file mode 100644
index 0000000000000..042eaa4935a90
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
+
+; CHECK-LABEL: foo:
+; CHECK:       #DEBUG_VALUE: foo:p <- $rdi
+; CHECK:       retq
+define void @foo(ptr %p) !dbg !0 {
+entry:
+    #dbg_value(ptr %p, !4, !DIExpression(), !5)
+  ret void, !dbg !5
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!8, !9}
+
+!0 = distinct !DISubprogram(name: "foo", scope: !2, file: !2, line: 1, type: !3, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !7)
+!1 = distinct !DICompileUnit(language: DW_LANG_C11, file: !2, emissionKind: FullDebug)
+!2 = !DIFile(filename: "regbankselect-dbg-value-physreg-crash.c", directory: "/")
+!3 = !DISubroutineType(types: !6)
+!4 = !DILocalVariable(name: "p", arg: 1, scope: !0, file: !2, line: 1, type: !10)
+!5 = !DILocation(line: 1, column: 1, scope: !0)
+!6 = !{null, !10}
+!7 = !{!4}
+!8 = !{i32 7, !"Dwarf Version", i32 4}
+!9 = !{i32 2, !"Debug Info Version", i32 3}
+!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
+!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
diff --git a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.mir b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.mir
new file mode 100644
index 0000000000000..79523b904ee9a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-dbg-value-physreg-crash.mir
@@ -0,0 +1,34 @@
+# RUN: llc -mtriple=x86_64-linux-gnu                       -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=x86_64-linux-gnu -regbankselect-greedy -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s
+
+# This reproduces a pre-regbankselect GMIR where DBG_VALUE already carries a
+# physical register. Regressions here used to crash when X86RegisterBankInfo
+# queried LLT for non-vreg register operands.
+
+--- |
+  define void @foo() {
+  entry:
+    ret void
+  }
+
+  !0 = distinct !DISubprogram(name: "foo")
+  !1 = !DILocation(line: 1, column: 1, scope: !0)
+...
+
+---
+name:            foo
+legalized:       true
+regBankSelected: false
+body:             |
+  bb.0:
+    liveins: $rdi
+
+    %0:_(p0) = COPY $rdi
+    DBG_VALUE $rdi, $noreg, 0, 0, debug-location !1
+    RET 0
+
+...
+
+# CHECK-LABEL: name: foo
+# CHECK: %0:gpr(p0) = COPY $rdi
+# CHECK: DBG_VALUE $rdi, $noreg, 0, 0



More information about the llvm-commits mailing list