[llvm] 032251e - [Coroutines] Fix PR45130

Tom Stellard via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 27 08:38:03 PDT 2020


On 03/26/2020 09:14 PM, Richard Smith wrote:
> Can we get this into the 10.0.1 release? This fixes a nasty miscompile for C++20 coroutines.
> 

I've created a tracking bug for this: https://bugs.llvm.org/show_bug.cgi?id=45330

-Tom

> On Thu, 19 Mar 2020 at 20:28, Jun Ma via llvm-commits <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
> 
> 
>     Author: Jun Ma
>     Date: 2020-03-20T11:27:08+08:00
>     New Revision: 032251e34d17c1cbf21e7571514bb775ed5cdf30
> 
>     URL: https://github.com/llvm/llvm-project/commit/032251e34d17c1cbf21e7571514bb775ed5cdf30
>     DIFF: https://github.com/llvm/llvm-project/commit/032251e34d17c1cbf21e7571514bb775ed5cdf30.diff
> 
>     LOG: [Coroutines] Fix PR45130
> 
>     For now, when final suspend can be simplified by simplifySuspendPoint,
>     handleFinalSuspend is executed as well to remove last case in switch
>     instruction. This patch fixes it.
> 
>     Differential Revision: https://reviews.llvm.org/D76345
> 
>     Added:
> 
> 
>     Modified:
>         llvm/lib/Transforms/Coroutines/CoroSplit.cpp
>         llvm/test/Transforms/Coroutines/no-suspend.ll
> 
>     Removed:
> 
> 
> 
>     ################################################################################
>     diff  --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
>     index 04c06e3653d7..8aca27b9b42c 100644
>     --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
>     +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
>     @@ -1157,7 +1157,10 @@ static void simplifySuspendPoints(coro::Shape &Shape) {
>        if (N == 0)
>          return;
>        while (true) {
>     -    if (simplifySuspendPoint(cast<CoroSuspendInst>(S[I]), Shape.CoroBegin)) {
>     +    auto SI = cast<CoroSuspendInst>(S[I]);
>     +    // Leave final.suspend to handleFinalSuspend since it is undefined behavior
>     +    // to resume a coroutine suspended at the final suspend point.
>     +    if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) {
>            if (--N == I)
>              break;
>            std::swap(S[I], S[N]);
> 
>     diff  --git a/llvm/test/Transforms/Coroutines/no-suspend.ll b/llvm/test/Transforms/Coroutines/no-suspend.ll
>     index be48c2ab09fe..211e16c6ccdb 100644
>     --- a/llvm/test/Transforms/Coroutines/no-suspend.ll
>     +++ b/llvm/test/Transforms/Coroutines/no-suspend.ll
>     @@ -362,6 +362,58 @@ suspend:
>        ret void
>      }
> 
>     +; SimplifySuspendPoint should not simplify final suspend point
>     +;
>     +; CHECK-LABEL: define void @cannot_simplify_final_suspend(
>     +; CHECK-NEXT:  entry:
>     +; CHECK-NEXT:     llvm.coro.id <http://llvm.coro.id>
>     +;
>     +define void @cannot_simplify_final_suspend() "coroutine.presplit"="1" personality i32 0 {
>     +entry:
>     +  %id = call token @llvm.coro.id <http://llvm.coro.id>(i32 0, i8* null, i8* null, i8* null)
>     +  %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
>     +  br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin
>     +dyn.alloc:
>     +  %size = call i32 @llvm.coro.size.i32()
>     +  %alloc = call i8* @malloc(i32 %size)
>     +  br label %coro.begin
>     +coro.begin:
>     +  %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ]
>     +  %hdl = call noalias i8* @llvm.coro.begin(token %id, i8* %phi)
>     +  br label %body
>     +body:
>     +  %save = call token @llvm.coro.save(i8* %hdl)
>     +  %subfn = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
>     +  %bcast = bitcast i8* %subfn to void (i8*)*
>     +  invoke fastcc void %bcast(i8* %hdl) to label %real_susp unwind label %lpad
>     +
>     +real_susp:
>     +  %0 = call i8 @llvm.coro.suspend(token %save, i1 1)
>     +  switch i8 %0, label %suspend [i8 0, label %resume
>     +                                i8 1, label %pre.cleanup]
>     +resume:
>     +  call void @print(i32 0)
>     +  br label %cleanup
>     +
>     +pre.cleanup:
>     +  call void @print(i32 1)
>     +  br label %cleanup
>     +
>     +cleanup:
>     +  %mem = call i8* @llvm.coro.free(token %id, i8* %hdl)
>     +  call void @free(i8* %mem)
>     +  br label %suspend
>     +suspend:
>     +  call i1 @llvm.coro.end(i8* %hdl, i1 false)
>     +  ret void
>     +lpad:
>     +  %lpval = landingpad { i8*, i32 }
>     +     cleanup
>     +
>     +  call void @print(i32 2)
>     +  resume { i8*, i32 } %lpval
>     +}
>     +
>      declare i8* @malloc(i32)
>      declare void @free(i8*)
>      declare void @print(i32)
> 
> 
> 
>     _______________________________________________
>     llvm-commits mailing list
>     llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>     https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> 



More information about the llvm-commits mailing list