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