Skip to content

[DebugInfo][Inline] Propagate source locs when simplifying cond branches #134827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 9, 2025

Conversation

SLTozer
Copy link
Contributor

@SLTozer SLTozer commented Apr 8, 2025

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.

Found using #107279.

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.
@llvmbot
Copy link
Member

llvmbot commented Apr 8, 2025

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-debuginfo

Author: Stephen Tozer (SLTozer)

Changes

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.

Found using #107279.


Full diff: https://github.com/llvm/llvm-project/pull/134827.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Utils/CloneFunction.cpp (+6-2)
  • (added) llvm/test/Transforms/Inline/X86/inline-simplified-branch-dbg-loc.ll (+97)
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]])
+;.

Copy link
Contributor

@OCHyams OCHyams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@SLTozer SLTozer merged commit 5039bf4 into llvm:main Apr 9, 2025
14 checks passed
AllinLeeYL pushed a commit to AllinLeeYL/llvm-project that referenced this pull request Apr 10, 2025
…hes (llvm#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.

Found using llvm#107279.
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
…hes (llvm#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.

Found using llvm#107279.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants