[llvm] [Coroutines] Always drop lifetime markers after moving allocas to frame (PR #149141)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 16 10:04:11 PDT 2025


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/149141

https://github.com/llvm/llvm-project/pull/142551 started always dropping lifetime markers after moving allocas on the frame, as these are not useful on non-allocas but can cause issues.

However, this was not done for other ABIs (retcon, retcononce, async) that go through a different code path. We should probably be treating those the same way?

>From 9379f880bf4c3277de4a9b2678bc2b170f9dbea2 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Wed, 16 Jul 2025 18:24:32 +0200
Subject: [PATCH] [Coroutines] Always drop lifetime markers on coro frame

https://github.com/llvm/llvm-project/pull/142551 started always
dropping lifetime markers after moving allocas on the frame, as
these are not useful on non-allocas but can cause issues.

However, this was not done for other ABIs (retcon, retcononce,
async) that go through a different code path. We should probably
be treating those the same way?
---
 llvm/lib/Transforms/Coroutines/CoroFrame.cpp               | 7 +++++++
 .../Coroutines/coro-async-addr-lifetime-start-bug.ll       | 6 +++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index fe30c6dc6abe4..fbeb7218ba9a3 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -1179,6 +1179,13 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
       AllocaInst *Alloca = P.Alloca;
       auto *G = GetFramePointer(Alloca);
 
+      // Remove any lifetime intrinsics, now that these are no longer allocas.
+      for (User *U : make_early_inc_range(Alloca->users())) {
+        auto *I = cast<Instruction>(U);
+        if (I->isLifetimeStartOrEnd())
+          I->eraseFromParent();
+      }
+
       // We are not using ReplaceInstWithInst(P.first, cast<Instruction>(G))
       // here, as we are changing location of the instruction.
       G->takeName(Alloca);
diff --git a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll
index 2306b72a0055f..40101595092b0 100644
--- a/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll
+++ b/llvm/test/Transforms/Coroutines/coro-async-addr-lifetime-start-bug.ll
@@ -87,9 +87,9 @@ loop_exit:
 }
 
 ; CHECK: define {{.*}} void @my_async_function.resume.0(
-; CHECK-NOT:  call void @llvm.lifetime.start.p0(i64 4, ptr %3)
-; CHECK:  br i1 %exitCond, label %loop_exit, label %loop
-; CHECK: lifetime.end
+; CHECK-NOT: llvm.lifetime
+; CHECK:  br i1 %exitCond, label %common.ret, label %loop
+; CHECK-NOT: llvm.lifetime
 ; CHECK: }
 
 declare { ptr, ptr, ptr, ptr } @llvm.coro.suspend.async.sl_p0i8p0i8p0i8p0i8s(i32, ptr, ptr, ...)



More information about the llvm-commits mailing list