[llvm] [Coroutines] Walk inlinedAt recursively to create legal DILabels (PR #157099)
Christian Ulmann via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 5 06:02:16 PDT 2025
https://github.com/Dinistro created https://github.com/llvm/llvm-project/pull/157099
This commit resolves a defect in the creation of DILabels for suspend points. While a previous change introduced support for inlined locations, it did not consider that a location might originate from multiple inlinings. Therefore, we extend this to walk iteratively through all `inlinedAt` locations to get to the root.
>From 9865978ee1382f2325103404d9010bebed1fb249 Mon Sep 17 00:00:00 2001
From: Christian Ulmann <christian.ulmann at nextsilicon.com>
Date: Fri, 5 Sep 2025 12:57:23 +0000
Subject: [PATCH] [Coroutines] Walk inlinedAt recursively to create legal
DILabels
This commit resolves a defect in the creation of DILabels for suspend
points. While a previous change introduced support for inlined
locations, it did not consider that a location might originate from
multiple inlinings. Therefore, we extend this to walk iteratively
through all `inlinedAt` locations to get to the root.
---
llvm/lib/Transforms/Coroutines/CoroSplit.cpp | 16 +++++++++-------
.../Coroutines/coro-split-dbg-labels-inlined.ll | 8 +++++++-
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 88b2bd9aa2046..02c38d02cff64 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -1568,13 +1568,15 @@ struct SwitchCoroutineSplitter {
if (DebugLoc SuspendLoc = S->getDebugLoc()) {
std::string LabelName =
("__coro_resume_" + Twine(SuspendIndex)).str();
- // Take the "inlined at" location, if present. This is mandatory as
- // the DILabel insertion checks that the scopes of label and the
- // attached location match. This is not the case when the suspend
- // location has been inlined due to pointing to the original scope.
- DILocation *DILoc = SuspendLoc->getInlinedAt();
- if (!DILoc)
- DILoc = SuspendLoc;
+ // Take the "inlined at" location recursively, if present. This is
+ // mandatory as the DILabel insertion checks that the scopes of label
+ // and the attached location match. This is not the case when the
+ // suspend location has been inlined due to pointing to the original
+ // scope.
+ DILocation *DILoc = SuspendLoc;
+ while (DILocation *InlinedAt = DILoc->getInlinedAt())
+ DILoc = InlinedAt;
+
DILabel *ResumeLabel =
DBuilder.createLabel(DIS, LabelName, DILoc->getFile(),
SuspendLoc.getLine(), SuspendLoc.getCol(),
diff --git a/llvm/test/Transforms/Coroutines/coro-split-dbg-labels-inlined.ll b/llvm/test/Transforms/Coroutines/coro-split-dbg-labels-inlined.ll
index 0905f5981502c..e9737b62b0b8f 100644
--- a/llvm/test/Transforms/Coroutines/coro-split-dbg-labels-inlined.ll
+++ b/llvm/test/Transforms/Coroutines/coro-split-dbg-labels-inlined.ll
@@ -1,5 +1,8 @@
; RUN: opt %s -passes='cgscc(coro-split)' -S | FileCheck %s
+; Verifies that suspend points with inlined locations are handled properly,
+; i.e., that their debug labels point to the correct subprogram.
+
source_filename = "coro.c"
; Function Attrs: nounwind uwtable
@@ -96,4 +99,7 @@ attributes #4 = { argmemonly nounwind readonly }
!41 = !DILocation(line: 17, column: 1, scope: !16)
!100 = distinct !DISubprogram(name: "callee", scope: !1, file: !1, line: 8, type: !17, scopeLine: 4, isOptimized: true, unit: !0, retainedNodes: !2)
-!101 = !DILocation(line: 12, column: 6, scope: !16)
+!101 = !DILocation(line: 42, column: 6, scope: !102, inlinedAt: !103)
+
+!102 = distinct !DISubprogram(name: "callee_recursive", scope: !1, file: !1, line: 8, type: !17, scopeLine: 4, isOptimized: true, unit: !0, retainedNodes: !2)
+!103 = !DILocation(line: 12, column: 6, scope: !16)
More information about the llvm-commits
mailing list