[llvm] [DSE] Mark promise of pre-split coroutine visible to caller (PR #133918)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 7 04:19:01 PDT 2025


NewSigma wrote:

I will try to elaborate on my concerns about the issue. Hope you will understand. :)

Consider the following example:

``` LLVM
resume:
; Do something with %promise
  br label %subpend
suspend:

  store ptr null, ptr %promise, align 8 ; Do not eliminate
  ret void
```

DSE will treat the function as a normal function, and stores just before 'ret' will be eliminated. This is done by eliminateDeadWritesAtEndOfFunction() in DSE, whose comments reads:

> Eliminate writes to objects that are not visible in the caller and are not accessed before returning from the function.

I have two questions:

1. What does 'end of function' mean when it comes to pre-split coroutines? Does the function end each time the coroutine suspends, or when the coroutine reaches the final suspend?
2. Is coroutine promise invisible to the caller, even indirectly?

If we consider that function ends each time coroutine suspends, then eliminateDeadWritesAtEndOfFunction() cannot be applied to pre-split coroutines and should be disabled.
If we consider that function ends when the coroutine reaches the final suspend point, we can analyze potential memory usage after the coroutine resumes and avoid mis-optimization. However, I believe it is more appropriate to do this after CoroSplit. After CoroSplit, the original example may looks like:

``` LLVM
suspend:
  store ptr null, ptr %promise, align 8 ; Do not eliminate
  ret void
```

``` LLVM
resume:
; Do something with %promise
  store ptr null, ptr %promise, align 8 ; Should eliminate
  ret void
```

Eager elimination introduces additional compilation costs and will not lead to more optimized code.

Personally, I prefer to consider the pre-split coroutine promise visible to the caller, as this is safer than simply disabling eliminateDeadWritesAtEndOfFunction() for pre-split coroutines. However, this depends on your understanding of coroutine semantics.

> This hack looks very problematic to me, and seems quite distinct from the existing coroutine workarounds we have (which are about the possibility of the thread identity changing across suspension points).

Since the issue does nothing with thread_local storage or readnone functions, I consider it essentially different from thread identity changing problem.


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


More information about the llvm-commits mailing list