[clang] [Clang][CodeGen] Do not emit lifetime intrinsics for coro promise alloca (PR #140548)
Weibo He via cfe-commits
cfe-commits at lists.llvm.org
Mon May 19 17:08:48 PDT 2025
https://github.com/NewSigma updated https://github.com/llvm/llvm-project/pull/140548
>From d2e1a8d8a650f2a38387c500f942a0c6722c8a84 Mon Sep 17 00:00:00 2001
From: NewSigma <NewSigma at 163.com>
Date: Mon, 19 May 2025 22:12:45 +0800
Subject: [PATCH 1/2] Do not emit lifetime intrinsics for coro promise alloca
---
clang/lib/CodeGen/CGDecl.cpp | 5 +++++
clang/test/CodeGenCoroutines/coro-params.cpp | 3 ---
clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 4a8f7f6a42ecb..556adebc6fa39 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1343,6 +1343,11 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
if (!ShouldEmitLifetimeMarkers)
return nullptr;
+ // No lifetimes on promise alloca, or middle end passes will assume promise
+ // dead after lifetime.end, leading to mis-optimization
+ if (Addr->getName() == "__promise")
+ return nullptr;
+
assert(Addr->getType()->getPointerAddressSpace() ==
CGM.getDataLayout().getAllocaAddrSpace() &&
"Pointer should be in alloca address space");
diff --git a/clang/test/CodeGenCoroutines/coro-params.cpp b/clang/test/CodeGenCoroutines/coro-params.cpp
index 719726cca29c5..4f13e093197ff 100644
--- a/clang/test/CodeGenCoroutines/coro-params.cpp
+++ b/clang/test/CodeGenCoroutines/coro-params.cpp
@@ -84,7 +84,6 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam, TrivialABI trivialParam)
// CHECK-NEXT: call void @_ZN11MoveAndCopyC1EOS_(ptr {{[^,]*}} %[[McCopy]], ptr noundef nonnull align 4 dereferenceable(4) %[[McParam]]) #
// CHECK-NEXT: call void @llvm.lifetime.start.p0(
// CHECK-NEXT: call void @_ZN10TrivialABIC1EOS_(ptr {{[^,]*}} %[[TrivialCopy]], ptr {{[^,]*}} %[[TrivialAlloca]])
- // CHECK-NEXT: call void @llvm.lifetime.start.p0(
// CHECK-NEXT: invoke void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopy10TrivialABIEE12promise_typeC1Ev(
// CHECK: call void @_ZN14suspend_always12await_resumeEv(
@@ -106,7 +105,6 @@ void f(int val, MoveOnly moParam, MoveAndCopy mcParam, TrivialABI trivialParam)
// Destroy promise, then parameter copies:
// CHECK: call void @_ZNSt16coroutine_traitsIJvi8MoveOnly11MoveAndCopy10TrivialABIEE12promise_typeD1Ev(ptr {{[^,]*}} %__promise)
- // CHECK-NEXT: call void @llvm.lifetime.end.p0(
// CHECK-NEXT: call void @_ZN10TrivialABID1Ev(ptr {{[^,]*}} %[[TrivialCopy]])
// CHECK-NEXT: call void @llvm.lifetime.end.p0(
// CHECK-NEXT: call void @_ZN11MoveAndCopyD1Ev(ptr {{[^,]*}} %[[McCopy]])
@@ -135,7 +133,6 @@ void dependent_params(T x, U, U y) {
// CHECK-NEXT: call void @_ZN1BC1EOS_(ptr {{[^,]*}} %[[unnamed_copy]], ptr noundef nonnull align 4 dereferenceable(512) %0)
// CHECK-NEXT: call void @llvm.lifetime.start.p0(
// CHECK-NEXT: call void @_ZN1BC1EOS_(ptr {{[^,]*}} %[[y_copy]], ptr noundef nonnull align 4 dereferenceable(512) %y)
- // CHECK-NEXT: call void @llvm.lifetime.start.p0(
// CHECK-NEXT: invoke void @_ZNSt16coroutine_traitsIJv1A1BS1_EE12promise_typeC1Ev(
co_return;
diff --git a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
index d71c2c558996a..d028c127e1e21 100644
--- a/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
+++ b/clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp
@@ -52,7 +52,7 @@ coroutine ArrayInitCoro() {
// CHECK-NEXT: store ptr %arrayinit.element, ptr %arrayinit.endOfInit.reload.addr, align 8
co_await Awaiter{}
// CHECK-NEXT: @_ZNSt14suspend_always11await_readyEv
- // CHECK-NEXT: br i1 %{{.+}}, label %await.ready, label %CoroSave30
+ // CHECK-NEXT: br i1 %{{.+}}, label %await.ready, label %CoroSave29
};
// CHECK: await.cleanup: ; preds = %AfterCoroSuspend{{.*}}
// CHECK-NEXT: br label %cleanup{{.*}}.from.await.cleanup
>From 8f3a3bdc40d418d1b9325c63236b5d5741d0d760 Mon Sep 17 00:00:00 2001
From: NewSigma <NewSigma at 163.com>
Date: Tue, 20 May 2025 08:03:02 +0800
Subject: [PATCH 2/2] Use VarDecl::getName instead of Value::getName
---
clang/lib/CodeGen/CGDecl.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 556adebc6fa39..a308b8bf2c387 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1343,11 +1343,6 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
if (!ShouldEmitLifetimeMarkers)
return nullptr;
- // No lifetimes on promise alloca, or middle end passes will assume promise
- // dead after lifetime.end, leading to mis-optimization
- if (Addr->getName() == "__promise")
- return nullptr;
-
assert(Addr->getType()->getPointerAddressSpace() ==
CGM.getDataLayout().getAllocaAddrSpace() &&
"Pointer should be in alloca address space");
@@ -1604,9 +1599,14 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
bool IsMSCatchParam =
D.isExceptionVariable() && getTarget().getCXXABI().isMicrosoft();
+ // No lifetime intrinsics on coroutine promise alloca, or middle end
+ // passes will assume promise dead after lifetime.end, leading to
+ // mis-optimization
+ bool IsCoroPromise = D.getName() == "__promise";
+
// Emit a lifetime intrinsic if meaningful. There's no point in doing this
// if we don't have a valid insertion point (?).
- if (HaveInsertPoint() && !IsMSCatchParam) {
+ if (HaveInsertPoint() && !IsMSCatchParam && !IsCoroPromise) {
// If there's a jump into the lifetime of this variable, its lifetime
// gets broken up into several regions in IR, which requires more work
// to handle correctly. For now, just omit the intrinsics; this is a
More information about the cfe-commits
mailing list