[llvm] [AArch64][GlobalISel] Ignore debug uses in mul-constant combine (PR #228100)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 08:02:04 PDT 2026
https://github.com/GopinathBalaji created https://github.com/llvm/llvm-project/pull/228100
This PR is intended for the issue #227648.
When checking whether a multiply has a single non-debug use, retrieve that use using the non-debug use iterator as well. Otherwise a DBG_VALUE can get selected instead of the actual arithmetic user, causing debug info to change the combine decision.
So, my fix is as follows:
1. Use the non-debug instruction iterator, `use_nodbg_instructions()`, when retrieving the user so that it matches the preceding `hasOneNonDBGUse()` check.
2. Added a MIR regression test covering a `G_MUL` with a `DBG_VALUE` use and a single non-debug `G_ADD` user.
I added the regression test in the file:
`llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir`
since LLVM's testing guidance mentions to extend an existing relevant test file when possible.
I ran the following test commands:
```bash
build/bin/llvm-lit llvm-project/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir
```
```bash
build/bin/llvm-lit llvm-project/llvm/test/CodeGen/AArch64/GlobalISel
```
### Validation
Without this fix, the patch-included regression test failed; both commands now pass successfully.
<br></br>
Since this issue is tagged good-first-issue, I used LLM to only setup, search and learn. Wrote the fix myself.
<br></br>
Fixes #227648.
>From 601c561535c16ba887943bca1944a97eadef5445 Mon Sep 17 00:00:00 2001
From: Gopinath Balaji <gopibalaji13 at gmail.com>
Date: Thu, 1 Oct 2026 05:55:44 -0500
Subject: [PATCH] [AArch64][GlobalISel] Ignore debug uses in mul-constant
combine
When checking whether a multiply has a single non-debug use, retrive that use using the non-debug use
iterator as well. Otherwise a DBG_VALUE can be selected instead of the actual arithmetic user, causing
debug info to change the combine decision.
Also added a MIR regression test covering G_MUL with a debug use and a single G_ADD user.
---
.../GISel/AArch64PostLegalizerCombiner.cpp | 2 +-
.../postlegalizercombiner-mulpow2.mir | 66 +++++++++++++++++++
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
index 3f450693b00af..c03f320268efa 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp
@@ -173,7 +173,7 @@ bool matchAArch64MulConstCombine(
// Conservatively do not lower to shift+add+shift if the mul might be
// folded into madd or msub.
if (MRI.hasOneNonDBGUse(Dst)) {
- MachineInstr &UseMI = *MRI.use_instr_begin(Dst);
+ MachineInstr &UseMI = *MRI.use_nodbg_instructions(Dst).begin();
unsigned UseOpc = UseMI.getOpcode();
if (UseOpc == TargetOpcode::G_ADD || UseOpc == TargetOpcode::G_PTR_ADD ||
UseOpc == TargetOpcode::G_SUB)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir
index f9bc49db4a1f5..a455b09b29188 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir
@@ -1,6 +1,35 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple aarch64 -run-pass=aarch64-postlegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+--- |
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64-unknown-linux-gnu"
+
+ define ptr @dont_combine_ptr_add(i64 %x0, i64 %x1, ptr %x2) {
+ ret ptr %x2
+ }
+
+ define i64 @dont_combine_mul_with_dbg_use(i64 %x0, i64 %x1) !dbg !5 {
+ ret i64 0, !dbg !9
+ }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!3}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "postlegalizercombiner-mulpow2.mir", directory: "/")
+ !2 = !{}
+ !3 = !{i32 2, !"Debug Info Version", i32 3}
+ !5 = distinct !DISubprogram(name: "dont_combine_mul_with_dbg_use", linkageName: "dont_combine_mul_with_dbg_use", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
+ !6 = !DISubroutineType(types: !7)
+ !7 = !{!8, !8, !8}
+ !8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
+ !9 = !DILocation(line: 1, column: 1, scope: !5)
+ !10 = !{!11}
+ !11 = !DILocalVariable(name: "mul_result", scope: !5, file: !1, line: 1, type: !8)
+
+
...
---
name: dont_combine_ptr_add
@@ -31,3 +60,40 @@ body: |
%ptr_add:_(p0) = G_PTR_ADD %ptr, %mul
$x0 = COPY %ptr_add(p0)
RET_ReallyLR implicit $x0
+
+
+
+...
+---
+name: dont_combine_mul_with_dbg_use
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $x0, $x1
+
+ ; We don't want a debug use of the multiply result to hide its sole non-debug
+ ; G_ADD user. We want to keep G_MUL so that it can potentially form a madd later.
+
+ ; CHECK-LABEL: name: dont_combine_mul_with_dbg_use
+ ; CHECK: liveins: $x0, $x1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %reg0:_(i64) = COPY $x0
+ ; CHECK-NEXT: %reg1:_(i64) = COPY $x1
+ ; CHECK-NEXT: %cst:_(i64) = G_CONSTANT i64 6
+ ; CHECK-NEXT: %mul:_(i64) = G_MUL %reg0, %cst
+ ; CHECK-NEXT: DBG_VALUE %mul(i64), $noreg, ![[VAR:[0-9]+]], !DIExpression(), debug-location ![[LOC:[0-9]+]]
+ ; CHECK-NEXT: %add:_(i64) = G_ADD %mul, %reg1
+ ; CHECK-NEXT: $x0 = COPY %add(i64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+
+ %reg0:_(i64) = COPY $x0
+ %reg1:_(i64) = COPY $x1
+ %cst:_(i64) = G_CONSTANT i64 6
+ %mul:_(i64) = G_MUL %reg0, %cst
+ DBG_VALUE %mul(i64), $noreg, !11, !DIExpression(), debug-location !9
+ %add:_(i64) = G_ADD %mul, %reg1
+ $x0 = COPY %add(i64)
+ RET_ReallyLR implicit $x0
+
+...
More information about the llvm-commits
mailing list