Author: Jun Ma Date: 2020-04-29T17:13:34-07:00 New Revision: e4312b950dd7b019e14b991a17d6ac260b8e8082
URL: https://github.com/llvm/llvm-project/commit/e4312b950dd7b019e14b991a17d6ac260b8e8082 DIFF: https://github.com/llvm/llvm-project/commit/e4312b950dd7b019e14b991a17d6ac260b8e8082.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 (cherry picked from commit 032251e34d17c1cbf21e7571514bb775ed5cdf30) 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 66cb3e74e53e..1e067a45d016 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1155,7 +1155,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 fca096fa48bb..beb2431b7f19 100644 --- a/llvm/test/Transforms/Coroutines/no-suspend.ll +++ b/llvm/test/Transforms/Coroutines/no-suspend.ll @@ -361,6 +361,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 +; +define void @cannot_simplify_final_suspend() "coroutine.presplit"="1" personality i32 0 { +entry: + %id = call token @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-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
