[llvm] [DebugInfo] Fix incorrect debug attribution for inlined allocas (PR #144345)

Shivam Kunwar via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 20 03:39:02 PDT 2025


https://github.com/phyBrackets updated https://github.com/llvm/llvm-project/pull/144345

>From c7e92da3b925b2e9c6f5b4504e477c400a6a6c17 Mon Sep 17 00:00:00 2001
From: Shivam Kunwar <shivam.kunwar at kdab.com>
Date: Mon, 16 Jun 2025 18:14:31 +0530
Subject: [PATCH 1/3] Fix incorrect debug attribution for inlined allocas

---
 llvm/lib/Transforms/Utils/InlineFunction.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 21467a909af10..312b4888ee6e7 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2703,6 +2703,16 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
     // Remember the first block that is newly cloned over.
     FirstNewBlock = LastBlock; ++FirstNewBlock;
 
+    // Clear debug locations for all inlined allocas to prevent stack protection
+    // code from inheriting incorrect source attribution
+    for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) {
+     for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
+        if (auto *AI = dyn_cast<AllocaInst>(I)) {
+          AI->setDebugLoc(DebugLoc());
+        }
+      }
+    }
+
     // Insert retainRV/clainRV runtime calls.
     objcarc::ARCInstKind RVCallKind = objcarc::getAttachedARCFunctionKind(&CB);
     if (RVCallKind != objcarc::ARCInstKind::None)

>From 7de1b9a27e43a220732ee1fc2984f19437993bf1 Mon Sep 17 00:00:00 2001
From: Shivam Kunwar <shivam.kunwar at kdab.com>
Date: Mon, 16 Jun 2025 22:44:38 +0530
Subject: [PATCH 2/3] Add test to verify the changes

---
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  5 +-
 .../Inline/inline-alloca-debug-clear.ll       | 65 +++++++++++++++++++
 2 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/inline-alloca-debug-clear.ll

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 312b4888ee6e7..e99e50e957aa3 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2705,8 +2705,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
 
     // Clear debug locations for all inlined allocas to prevent stack protection
     // code from inheriting incorrect source attribution
-    for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) {
-     for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
+    for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E;
+         ++BB) {
+      for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
         if (auto *AI = dyn_cast<AllocaInst>(I)) {
           AI->setDebugLoc(DebugLoc());
         }
diff --git a/llvm/test/Transforms/Inline/inline-alloca-debug-clear.ll b/llvm/test/Transforms/Inline/inline-alloca-debug-clear.ll
new file mode 100644
index 0000000000000..a3eb725006347
--- /dev/null
+++ b/llvm/test/Transforms/Inline/inline-alloca-debug-clear.ll
@@ -0,0 +1,65 @@
+; RUN: opt < %s -passes=always-inline -S | FileCheck %s
+; Test that inlined allocas do not retain debug locations from the callee
+; to prevent incorrect source attribution in generated code.
+
+; ModuleID = 'test-inline-debug-alloca.c'
+source_filename = "test-inline-debug-alloca.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: alwaysinline nounwind uwtable
+define dso_local i32 @callee() #0 !dbg !7 {
+entry:
+  %large_array = alloca [1000 x i8], align 1, !dbg !12
+  %x = alloca i32, align 4, !dbg !13
+  %arrayidx = getelementptr inbounds [1000 x i8], ptr %large_array, i64 0, i64 0, !dbg !14
+  store i8 42, ptr %arrayidx, align 1, !dbg !15
+  store i32 123, ptr %x, align 4, !dbg !16
+  %0 = load i32, ptr %x, align 4, !dbg !17
+  ret i32 %0, !dbg !18
+}
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @caller() #1 !dbg !19 {
+entry:
+  %call = call i32 @callee(), !dbg !20
+  ret i32 %call, !dbg !21
+}
+
+; CHECK-LABEL: define dso_local i32 @caller()
+; CHECK: entry:
+; CHECK: %large_array.i = alloca [1000 x i8], align 1{{$}}
+; CHECK-NOT: %large_array.i = alloca [1000 x i8], align 1, !dbg
+; CHECK: %x.i = alloca i32, align 4{{$}}
+; CHECK-NOT: %x.i = alloca i32, align 4, !dbg
+; CHECK: ret i32
+
+attributes #0 = { alwaysinline nounwind uwtable }
+attributes #1 = { nounwind uwtable }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false)
+!1 = !DIFile(filename: "test-inline-debug-alloca.c", directory: "/tmp")
+!2 = !{i32 7, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 8, !"PIC Level", i32 2}
+!6 = !{!"clang"}
+!7 = distinct !DISubprogram(name: "callee", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{}
+!12 = !DILocation(line: 2, column: 9, scope: !7)
+!13 = !DILocation(line: 3, column: 9, scope: !7)
+!14 = !DILocation(line: 4, column: 3, scope: !7)
+!15 = !DILocation(line: 4, column: 16, scope: !7)
+!16 = !DILocation(line: 5, column: 5, scope: !7)
+!17 = !DILocation(line: 6, column: 10, scope: !7)
+!18 = !DILocation(line: 6, column: 3, scope: !7)
+!19 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 9, type: !8, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !11)
+!20 = !DILocation(line: 10, column: 10, scope: !19)
+!21 = !DILocation(line: 10, column: 3, scope: !19)

>From 8db557b3fd414424e783b92453b0f9e060cd3c70 Mon Sep 17 00:00:00 2001
From: Shivam Kunwar <shivam.kunwar at kdab.com>
Date: Fri, 20 Jun 2025 16:07:45 +0530
Subject: [PATCH 3/3] commit review feedback

---
 llvm/lib/Transforms/Utils/InlineFunction.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index e99e50e957aa3..e6d29c78b94bd 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2704,12 +2704,12 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
     FirstNewBlock = LastBlock; ++FirstNewBlock;
 
     // Clear debug locations for all inlined allocas to prevent stack protection
-    // code from inheriting incorrect source attribution
+    // code from inheriting incorrect source attribution.
     for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E;
          ++BB) {
       for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
         if (auto *AI = dyn_cast<AllocaInst>(I)) {
-          AI->setDebugLoc(DebugLoc());
+          AI->setDebugLoc(DebugLoc::getDropped());
         }
       }
     }



More information about the llvm-commits mailing list