[llvm] [DebugInfo][Inline] Propagate source locs when simplifying cond branches (PR #134827)

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 02:46:49 PDT 2025


https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/134827

During inlining, we may opportunistically simplify conditional branches (incl. switches) to unconditional branches if, after inlining, their destination is fixed. While we do this, we should propagate any DILocation attached to the original branch to the simplified branch, which this patch enables.

>From bd76ce65dda99ceacbea78830009ce99dcac20ef Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at sony.com>
Date: Fri, 4 Apr 2025 15:11:57 +0100
Subject: [PATCH] [DebugInfo][Inline] Propagate source locs when simplifying
 cond branches

During inlining, we may opportunistically simplify conditional branches
(incl. switches) to unconditional branches if, after inlining, their
destination is fixed. While we do this, we should propagate any
DILocation attached to the original branch to the simplified branch,
which this patch enables.
---
 llvm/lib/Transforms/Utils/CloneFunction.cpp   |  8 +-
 .../X86/inline-simplified-branch-dbg-loc.ll   | 97 +++++++++++++++++++
 2 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/X86/inline-simplified-branch-dbg-loc.ll

diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 9387797019023..35550642a4365 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -607,7 +607,9 @@ void PruningFunctionCloner::CloneBlock(
       // Constant fold to uncond branch!
       if (Cond) {
         BasicBlock *Dest = BI->getSuccessor(!Cond->getZExtValue());
-        VMap[OldTI] = BranchInst::Create(Dest, NewBB);
+        auto *NewBI = BranchInst::Create(Dest, NewBB);
+        NewBI->setDebugLoc(BI->getDebugLoc());
+        VMap[OldTI] = NewBI;
         ToClone.push_back(Dest);
         TerminatorDone = true;
       }
@@ -622,7 +624,9 @@ void PruningFunctionCloner::CloneBlock(
     if (Cond) { // Constant fold to uncond branch!
       SwitchInst::ConstCaseHandle Case = *SI->findCaseValue(Cond);
       BasicBlock *Dest = const_cast<BasicBlock *>(Case.getCaseSuccessor());
-      VMap[OldTI] = BranchInst::Create(Dest, NewBB);
+      auto *NewBI = BranchInst::Create(Dest, NewBB);
+      NewBI->setDebugLoc(SI->getDebugLoc());
+      VMap[OldTI] = NewBI;
       ToClone.push_back(Dest);
       TerminatorDone = true;
     }
diff --git a/llvm/test/Transforms/Inline/X86/inline-simplified-branch-dbg-loc.ll b/llvm/test/Transforms/Inline/X86/inline-simplified-branch-dbg-loc.ll
new file mode 100644
index 0000000000000..98844a753840a
--- /dev/null
+++ b/llvm/test/Transforms/Inline/X86/inline-simplified-branch-dbg-loc.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -mtriple=x86_64-unknown-unknown -S -passes=inline | FileCheck %s
+
+;; Test that when we simplify inlined conditional branch/switch instructions to
+;; unconditional branches, we propagate the original branch's source location to
+;; the simplified branch.
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i1 @ham() {
+; CHECK-LABEL: define i1 @ham() {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    br i1 poison, label %[[BB1_I:.*]], label %[[HOGE_EXIT:.*]]
+; CHECK:       [[BB1_I]]:
+; CHECK-NEXT:    br label %[[HOGE_EXIT]], !dbg [[DBG4:![0-9]+]]
+; CHECK:       [[HOGE_EXIT]]:
+; CHECK-NEXT:    br i1 poison, label %[[BB1_I1:.*]], label %[[QUUX_EXIT:.*]]
+; CHECK:       [[BB1_I1]]:
+; CHECK-NEXT:    br label %[[QUUX_EXIT]], !dbg [[DBG7:![0-9]+]]
+; CHECK:       [[QUUX_EXIT]]:
+; CHECK-NEXT:    ret i1 false
+;
+bb:
+  %call1 = call fastcc i32 @hoge(i1 false)
+  %call2 = call fastcc i32 @quux(i8 0)
+  ret i1 false
+}
+
+define fastcc i32 @hoge(i1 %in) {
+; CHECK-LABEL: define fastcc i32 @hoge(
+; CHECK-SAME: i1 [[IN:%.*]]) {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    br i1 poison, label %[[BB1:.*]], label %[[BB2:.*]]
+; CHECK:       [[BB1]]:
+; CHECK-NEXT:    br i1 [[IN]], label %[[BB2]], label %[[BB2]], !dbg [[DBG4]]
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    ret i32 0
+;
+bb:
+  br i1 poison, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  br i1 %in, label %bb2, label %bb2, !dbg !4
+
+bb2:                                              ; preds = %bb1, %bb1, %bb
+  ret i32 0
+}
+
+define fastcc i32 @quux(i8 %in) {
+; CHECK-LABEL: define fastcc i32 @quux(
+; CHECK-SAME: i8 [[IN:%.*]]) {
+; CHECK-NEXT:  [[BB:.*:]]
+; CHECK-NEXT:    br i1 poison, label %[[BB1:.*]], label %[[BB2:.*]]
+; CHECK:       [[BB1]]:
+; CHECK-NEXT:    switch i8 [[IN]], label %[[BB2]] [
+; CHECK-NEXT:      i8 0, label %[[BB2]]
+; CHECK-NEXT:    ], !dbg [[DBG7]]
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    ret i32 0
+;
+bb:
+  br i1 poison, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  switch i8 %in, label %bb2 [
+  i8 0, label %bb2
+  ], !dbg !14
+
+
+bb2:                                              ; preds = %bb1, %bb1, %bb
+  ret i32 0
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0git", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, globals: !2, imports: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "inline-simplified-branch-dbg-loc.cpp", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !DILocation(line: 26, column: 11, scope: !12)
+!6 = !DIFile(filename: "inline-simplified-branch-dbg-loc.cpp", directory: "/tmp")
+!12 = distinct !DISubprogram(name: "hoge", linkageName: "hoge", scope: !6, file: !6, line: 10, type: !13, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!13 = distinct !DISubroutineType(types: !2)
+!14 = !DILocation(line: 16, column: 1, scope: !15)
+!15 = distinct !DISubprogram(name: "quux", linkageName: "quux", scope: !6, file: !6, line: 20, type: !13, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: [[META2:![0-9]+]], globals: [[META2]], imports: [[META2]], splitDebugInlining: false, nameTableKind: None)
+; CHECK: [[META1]] = !DIFile(filename: "inline-simplified-branch-dbg-loc.cpp", directory: {{.*}})
+; CHECK: [[META2]] = !{}
+; CHECK: [[DBG4]] = !DILocation(line: 26, column: 11, scope: [[META5:![0-9]+]])
+; CHECK: [[META5]] = distinct !DISubprogram(name: "hoge", linkageName: "hoge", scope: [[META1]], file: [[META1]], line: 10, type: [[META6:![0-9]+]], scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META2]])
+; CHECK: [[META6]] = distinct !DISubroutineType(types: [[META2]])
+; CHECK: [[DBG7]] = !DILocation(line: 16, column: 1, scope: [[META8:![0-9]+]])
+; CHECK: [[META8]] = distinct !DISubprogram(name: "quux", linkageName: "quux", scope: [[META1]], file: [[META1]], line: 20, type: [[META6]], scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META2]])
+;.



More information about the llvm-commits mailing list