[llvm] [Coroutines] Walk inlinedAt recursively to create legal DILabels (PR #157099)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 5 06:02:48 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-coroutines

Author: Christian Ulmann (Dinistro)

<details>
<summary>Changes</summary>

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.

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


2 Files Affected:

- (modified) llvm/lib/Transforms/Coroutines/CoroSplit.cpp (+9-7) 
- (modified) llvm/test/Transforms/Coroutines/coro-split-dbg-labels-inlined.ll (+7-1) 


``````````diff
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)

``````````

</details>


https://github.com/llvm/llvm-project/pull/157099


More information about the llvm-commits mailing list