[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