[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume

2018-06-23 Thread Brian Gesiak via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL335422: [Coroutines] Less IR for noexcept await_resume 
(authored by modocache, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D47673

Files:
  cfe/trunk/lib/CodeGen/CGCoroutine.cpp
  cfe/trunk/test/CodeGenCoroutines/coro-await-resume-eh.cpp

Index: cfe/trunk/test/CodeGenCoroutines/coro-await-resume-eh.cpp
===
--- cfe/trunk/test/CodeGenCoroutines/coro-await-resume-eh.cpp
+++ cfe/trunk/test/CodeGenCoroutines/coro-await-resume-eh.cpp
@@ -18,18 +18,18 @@
   void await_resume() { throw 42; }
 };
 
-struct task {
+struct throwing_task {
   struct promise_type {
-task get_return_object() { return task{}; }
+auto get_return_object() { return throwing_task{}; }
 auto initial_suspend() { return throwing_awaitable{}; }
 auto final_suspend() { return coro::suspend_never{}; }
 void return_void() {}
 void unhandled_exception() {}
   };
 };
 
 // CHECK-LABEL: define void @_Z1fv()
-task f() {
+throwing_task f() {
   // A variable RESUMETHREW is used to keep track of whether the body
   // of 'await_resume' threw an exception. Exceptions thrown in
   // 'await_resume' are unwound to RESUMELPAD.
@@ -50,7 +50,7 @@
   // CHECK: [[RESUMELPAD]]:
   // CHECK: br label %[[RESUMECATCH:.+]]
   // CHECK: [[RESUMECATCH]]:
-  // CHECK: invoke void @_ZN4task12promise_type19unhandled_exceptionEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type19unhandled_exceptionEv
   // CHECK-NEXT: to label %[[RESUMEENDCATCH:.+]] unwind label
   // CHECK: [[RESUMEENDCATCH]]:
   // CHECK-NEXT: invoke void @__cxa_end_catch()
@@ -67,15 +67,42 @@
   // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]]
 
   // CHECK: [[RESUMEDBODY]]:
-  // CHECK: invoke void @_ZN4task12promise_type11return_voidEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type11return_voidEv
   // CHECK-NEXT: to label %[[REDUMEDBODYCONT:.+]] unwind label
   // CHECK: [[REDUMEDBODYCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL:.+]]
 
   // CHECK: [[RESUMEDCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL]]
 
   // CHECK: [[COROFINAL]]:
-  // CHECK-NEXT: invoke void @_ZN4task12promise_type13final_suspendEv
+  // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv
+  co_return;
+}
+
+struct noexcept_awaitable {
+  bool await_ready() { return true; }
+  void await_suspend(coro::coroutine_handle<>) {}
+  void await_resume() noexcept {}
+};
+
+struct noexcept_task {
+  struct promise_type {
+auto get_return_object() { return noexcept_task{}; }
+auto initial_suspend() { return noexcept_awaitable{}; }
+auto final_suspend() { return coro::suspend_never{}; }
+void return_void() {}
+void unhandled_exception() {}
+  };
+};
+
+// CHECK-LABEL: define void @_Z1gv()
+noexcept_task g() {
+  // If the await_resume function is marked as noexcept, none of the additional
+  // conditions that are present in f() above are added to the IR.
+  // This means that no i1 are stored before or after calling await_resume:
+  // CHECK: init.ready:
+  // CHECK-NEXT: call void @_ZN18noexcept_awaitable12await_resumeEv
+  // CHECK-NOT: store i1 false, i1*
   co_return;
 }
Index: cfe/trunk/lib/CodeGen/CGCoroutine.cpp
===
--- cfe/trunk/lib/CodeGen/CGCoroutine.cpp
+++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp
@@ -130,6 +130,16 @@
   return Prefix;
 }
 
+static bool memberCallExpressionCanThrow(const Expr *E) {
+  if (const auto *CE = dyn_cast(E))
+if (const auto *Proto =
+CE->getMethodDecl()->getType()->getAs())
+  if (isNoexceptExceptionSpec(Proto->getExceptionSpecType()) &&
+  Proto->canThrow() == CT_Cannot)
+return false;
+  return true;
+}
+
 // Emit suspend expression which roughly looks like:
 //
 //   auto && x = CommonExpr();
@@ -217,8 +227,12 @@
 
   // Emit await_resume expression.
   CGF.EmitBlock(ReadyBlock);
+
+  // Exception handling requires additional IR. If the 'await_resume' function
+  // is marked as 'noexcept', we avoid generating this additional IR.
   CXXTryStmt *TryStmt = nullptr;
-  if (Coro.ExceptionHandler && Kind == AwaitKind::Init) {
+  if (Coro.ExceptionHandler && Kind == AwaitKind::Init &&
+  memberCallExpressionCanThrow(S.getResumeExpr())) {
 Coro.ResumeEHVar =
 CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh"));
 Builder.CreateFlagStore(true, Coro.ResumeEHVar);
@@ -625,12 +639,20 @@
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
 
 if (CurCoro.Data->ExceptionHandler) {
-  BasicBlock *BodyBB = createBasicBlock("coro.resumed.body");
-  BasicBlock *ContBB = createBasicBlock("coro.resumed.cont");
-  Value *SkipBody =
-  Builder.CreateFlagLoad(CurCoro.Data->ResumeEHVar, "coro.resumed.eh");
-  Builder.CreateCondBr(SkipBody, 

[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume

2018-06-23 Thread Brian Gesiak via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC335422: [Coroutines] Less IR for noexcept await_resume 
(authored by modocache, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D47673?vs=152599=152602#toc

Repository:
  rC Clang

https://reviews.llvm.org/D47673

Files:
  lib/CodeGen/CGCoroutine.cpp
  test/CodeGenCoroutines/coro-await-resume-eh.cpp

Index: test/CodeGenCoroutines/coro-await-resume-eh.cpp
===
--- test/CodeGenCoroutines/coro-await-resume-eh.cpp
+++ test/CodeGenCoroutines/coro-await-resume-eh.cpp
@@ -18,18 +18,18 @@
   void await_resume() { throw 42; }
 };
 
-struct task {
+struct throwing_task {
   struct promise_type {
-task get_return_object() { return task{}; }
+auto get_return_object() { return throwing_task{}; }
 auto initial_suspend() { return throwing_awaitable{}; }
 auto final_suspend() { return coro::suspend_never{}; }
 void return_void() {}
 void unhandled_exception() {}
   };
 };
 
 // CHECK-LABEL: define void @_Z1fv()
-task f() {
+throwing_task f() {
   // A variable RESUMETHREW is used to keep track of whether the body
   // of 'await_resume' threw an exception. Exceptions thrown in
   // 'await_resume' are unwound to RESUMELPAD.
@@ -50,7 +50,7 @@
   // CHECK: [[RESUMELPAD]]:
   // CHECK: br label %[[RESUMECATCH:.+]]
   // CHECK: [[RESUMECATCH]]:
-  // CHECK: invoke void @_ZN4task12promise_type19unhandled_exceptionEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type19unhandled_exceptionEv
   // CHECK-NEXT: to label %[[RESUMEENDCATCH:.+]] unwind label
   // CHECK: [[RESUMEENDCATCH]]:
   // CHECK-NEXT: invoke void @__cxa_end_catch()
@@ -67,15 +67,42 @@
   // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]]
 
   // CHECK: [[RESUMEDBODY]]:
-  // CHECK: invoke void @_ZN4task12promise_type11return_voidEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type11return_voidEv
   // CHECK-NEXT: to label %[[REDUMEDBODYCONT:.+]] unwind label
   // CHECK: [[REDUMEDBODYCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL:.+]]
 
   // CHECK: [[RESUMEDCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL]]
 
   // CHECK: [[COROFINAL]]:
-  // CHECK-NEXT: invoke void @_ZN4task12promise_type13final_suspendEv
+  // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv
+  co_return;
+}
+
+struct noexcept_awaitable {
+  bool await_ready() { return true; }
+  void await_suspend(coro::coroutine_handle<>) {}
+  void await_resume() noexcept {}
+};
+
+struct noexcept_task {
+  struct promise_type {
+auto get_return_object() { return noexcept_task{}; }
+auto initial_suspend() { return noexcept_awaitable{}; }
+auto final_suspend() { return coro::suspend_never{}; }
+void return_void() {}
+void unhandled_exception() {}
+  };
+};
+
+// CHECK-LABEL: define void @_Z1gv()
+noexcept_task g() {
+  // If the await_resume function is marked as noexcept, none of the additional
+  // conditions that are present in f() above are added to the IR.
+  // This means that no i1 are stored before or after calling await_resume:
+  // CHECK: init.ready:
+  // CHECK-NEXT: call void @_ZN18noexcept_awaitable12await_resumeEv
+  // CHECK-NOT: store i1 false, i1*
   co_return;
 }
Index: lib/CodeGen/CGCoroutine.cpp
===
--- lib/CodeGen/CGCoroutine.cpp
+++ lib/CodeGen/CGCoroutine.cpp
@@ -130,6 +130,16 @@
   return Prefix;
 }
 
+static bool memberCallExpressionCanThrow(const Expr *E) {
+  if (const auto *CE = dyn_cast(E))
+if (const auto *Proto =
+CE->getMethodDecl()->getType()->getAs())
+  if (isNoexceptExceptionSpec(Proto->getExceptionSpecType()) &&
+  Proto->canThrow() == CT_Cannot)
+return false;
+  return true;
+}
+
 // Emit suspend expression which roughly looks like:
 //
 //   auto && x = CommonExpr();
@@ -217,8 +227,12 @@
 
   // Emit await_resume expression.
   CGF.EmitBlock(ReadyBlock);
+
+  // Exception handling requires additional IR. If the 'await_resume' function
+  // is marked as 'noexcept', we avoid generating this additional IR.
   CXXTryStmt *TryStmt = nullptr;
-  if (Coro.ExceptionHandler && Kind == AwaitKind::Init) {
+  if (Coro.ExceptionHandler && Kind == AwaitKind::Init &&
+  memberCallExpressionCanThrow(S.getResumeExpr())) {
 Coro.ResumeEHVar =
 CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh"));
 Builder.CreateFlagStore(true, Coro.ResumeEHVar);
@@ -625,12 +639,20 @@
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
 
 if (CurCoro.Data->ExceptionHandler) {
-  BasicBlock *BodyBB = createBasicBlock("coro.resumed.body");
-  BasicBlock *ContBB = createBasicBlock("coro.resumed.cont");
-  Value *SkipBody =
-  Builder.CreateFlagLoad(CurCoro.Data->ResumeEHVar, "coro.resumed.eh");
-  Builder.CreateCondBr(SkipBody, 

[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume

2018-06-23 Thread Brian Gesiak via Phabricator via cfe-commits
modocache updated this revision to Diff 152599.
modocache added a comment.

Great, thanks @GorNishanov! I moved the 'can throw' logic into a function 
called 'memberCallExpressionCanThrow', to convey that some dyn_cast'ing is 
going on.


Repository:
  rC Clang

https://reviews.llvm.org/D47673

Files:
  lib/CodeGen/CGCoroutine.cpp
  test/CodeGenCoroutines/coro-await-resume-eh.cpp

Index: test/CodeGenCoroutines/coro-await-resume-eh.cpp
===
--- test/CodeGenCoroutines/coro-await-resume-eh.cpp
+++ test/CodeGenCoroutines/coro-await-resume-eh.cpp
@@ -18,18 +18,18 @@
   void await_resume() { throw 42; }
 };
 
-struct task {
+struct throwing_task {
   struct promise_type {
-task get_return_object() { return task{}; }
+auto get_return_object() { return throwing_task{}; }
 auto initial_suspend() { return throwing_awaitable{}; }
 auto final_suspend() { return coro::suspend_never{}; }
 void return_void() {}
 void unhandled_exception() {}
   };
 };
 
 // CHECK-LABEL: define void @_Z1fv()
-task f() {
+throwing_task f() {
   // A variable RESUMETHREW is used to keep track of whether the body
   // of 'await_resume' threw an exception. Exceptions thrown in
   // 'await_resume' are unwound to RESUMELPAD.
@@ -50,7 +50,7 @@
   // CHECK: [[RESUMELPAD]]:
   // CHECK: br label %[[RESUMECATCH:.+]]
   // CHECK: [[RESUMECATCH]]:
-  // CHECK: invoke void @_ZN4task12promise_type19unhandled_exceptionEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type19unhandled_exceptionEv
   // CHECK-NEXT: to label %[[RESUMEENDCATCH:.+]] unwind label
   // CHECK: [[RESUMEENDCATCH]]:
   // CHECK-NEXT: invoke void @__cxa_end_catch()
@@ -67,15 +67,42 @@
   // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]]
 
   // CHECK: [[RESUMEDBODY]]:
-  // CHECK: invoke void @_ZN4task12promise_type11return_voidEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type11return_voidEv
   // CHECK-NEXT: to label %[[REDUMEDBODYCONT:.+]] unwind label
   // CHECK: [[REDUMEDBODYCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL:.+]]
 
   // CHECK: [[RESUMEDCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL]]
 
   // CHECK: [[COROFINAL]]:
-  // CHECK-NEXT: invoke void @_ZN4task12promise_type13final_suspendEv
+  // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv
+  co_return;
+}
+
+struct noexcept_awaitable {
+  bool await_ready() { return true; }
+  void await_suspend(coro::coroutine_handle<>) {}
+  void await_resume() noexcept {}
+};
+
+struct noexcept_task {
+  struct promise_type {
+auto get_return_object() { return noexcept_task{}; }
+auto initial_suspend() { return noexcept_awaitable{}; }
+auto final_suspend() { return coro::suspend_never{}; }
+void return_void() {}
+void unhandled_exception() {}
+  };
+};
+
+// CHECK-LABEL: define void @_Z1gv()
+noexcept_task g() {
+  // If the await_resume function is marked as noexcept, none of the additional
+  // conditions that are present in f() above are added to the IR.
+  // This means that no i1 are stored before or after calling await_resume:
+  // CHECK: init.ready:
+  // CHECK-NEXT: call void @_ZN18noexcept_awaitable12await_resumeEv
+  // CHECK-NOT: store i1 false, i1*
   co_return;
 }
Index: lib/CodeGen/CGCoroutine.cpp
===
--- lib/CodeGen/CGCoroutine.cpp
+++ lib/CodeGen/CGCoroutine.cpp
@@ -130,6 +130,16 @@
   return Prefix;
 }
 
+static bool memberCallExpressionCanThrow(const Expr *E) {
+  if (const auto *CE = dyn_cast(E))
+if (const auto *Proto =
+CE->getMethodDecl()->getType()->getAs())
+  if (isNoexceptExceptionSpec(Proto->getExceptionSpecType()) &&
+  Proto->canThrow() == CT_Cannot)
+return false;
+  return true;
+}
+
 // Emit suspend expression which roughly looks like:
 //
 //   auto && x = CommonExpr();
@@ -217,8 +227,12 @@
 
   // Emit await_resume expression.
   CGF.EmitBlock(ReadyBlock);
+
+  // Exception handling requires additional IR. If the 'await_resume' function
+  // is marked as 'noexcept', we avoid generating this additional IR.
   CXXTryStmt *TryStmt = nullptr;
-  if (Coro.ExceptionHandler && Kind == AwaitKind::Init) {
+  if (Coro.ExceptionHandler && Kind == AwaitKind::Init &&
+  memberCallExpressionCanThrow(S.getResumeExpr())) {
 Coro.ResumeEHVar =
 CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh"));
 Builder.CreateFlagStore(true, Coro.ResumeEHVar);
@@ -625,12 +639,20 @@
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
 
 if (CurCoro.Data->ExceptionHandler) {
-  BasicBlock *BodyBB = createBasicBlock("coro.resumed.body");
-  BasicBlock *ContBB = createBasicBlock("coro.resumed.cont");
-  Value *SkipBody =
-  Builder.CreateFlagLoad(CurCoro.Data->ResumeEHVar, "coro.resumed.eh");
-  Builder.CreateCondBr(SkipBody, ContBB, BodyBB);
-  

[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume

2018-06-23 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov accepted this revision.
GorNishanov added a comment.
This revision is now accepted and ready to land.

LGTM with some suggestions.




Comment at: lib/CodeGen/CGCoroutine.cpp:224
+  bool ResumeCanThrow = true;
+  if (const auto *MCE = dyn_cast(S.getResumeExpr()))
+if (const auto *Proto =

This long sequence of if statements seems to be asking to be put into its own 
predicate function: expressionCanThrow or something like that.


Repository:
  rC Clang

https://reviews.llvm.org/D47673



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume

2018-06-02 Thread Brian Gesiak via Phabricator via cfe-commits
modocache created this revision.
modocache added reviewers: GorNishanov, EricWF.
Herald added a subscriber: cfe-commits.

In his review of https://reviews.llvm.org/D45860, @GorNishanov suggested
avoiding generating additional exception-handling IR in the case that
the resume function was marked as 'noexcept', and exceptions could not
occur. This implements that suggestion.

Test Plan: `check-clang`


Repository:
  rC Clang

https://reviews.llvm.org/D47673

Files:
  lib/CodeGen/CGCoroutine.cpp
  test/CodeGenCoroutines/coro-await-resume-eh.cpp

Index: test/CodeGenCoroutines/coro-await-resume-eh.cpp
===
--- test/CodeGenCoroutines/coro-await-resume-eh.cpp
+++ test/CodeGenCoroutines/coro-await-resume-eh.cpp
@@ -18,18 +18,18 @@
   void await_resume() { throw 42; }
 };
 
-struct task {
+struct throwing_task {
   struct promise_type {
-task get_return_object() { return task{}; }
+auto get_return_object() { return throwing_task{}; }
 auto initial_suspend() { return throwing_awaitable{}; }
 auto final_suspend() { return coro::suspend_never{}; }
 void return_void() {}
 void unhandled_exception() {}
   };
 };
 
 // CHECK-LABEL: define void @_Z1fv()
-task f() {
+throwing_task f() {
   // A variable RESUMETHREW is used to keep track of whether the body
   // of 'await_resume' threw an exception. Exceptions thrown in
   // 'await_resume' are unwound to RESUMELPAD.
@@ -50,7 +50,7 @@
   // CHECK: [[RESUMELPAD]]:
   // CHECK: br label %[[RESUMECATCH:.+]]
   // CHECK: [[RESUMECATCH]]:
-  // CHECK: invoke void @_ZN4task12promise_type19unhandled_exceptionEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type19unhandled_exceptionEv
   // CHECK-NEXT: to label %[[RESUMEENDCATCH:.+]] unwind label
   // CHECK: [[RESUMEENDCATCH]]:
   // CHECK-NEXT: invoke void @__cxa_end_catch()
@@ -67,15 +67,42 @@
   // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]]
 
   // CHECK: [[RESUMEDBODY]]:
-  // CHECK: invoke void @_ZN4task12promise_type11return_voidEv
+  // CHECK: invoke void @_ZN13throwing_task12promise_type11return_voidEv
   // CHECK-NEXT: to label %[[REDUMEDBODYCONT:.+]] unwind label
   // CHECK: [[REDUMEDBODYCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL:.+]]
 
   // CHECK: [[RESUMEDCONT]]:
   // CHECK-NEXT: br label %[[COROFINAL]]
 
   // CHECK: [[COROFINAL]]:
-  // CHECK-NEXT: invoke void @_ZN4task12promise_type13final_suspendEv
+  // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv
+  co_return;
+}
+
+struct noexcept_awaitable {
+  bool await_ready() { return true; }
+  void await_suspend(coro::coroutine_handle<>) {}
+  void await_resume() noexcept {}
+};
+
+struct noexcept_task {
+  struct promise_type {
+auto get_return_object() { return noexcept_task{}; }
+auto initial_suspend() { return noexcept_awaitable{}; }
+auto final_suspend() { return coro::suspend_never{}; }
+void return_void() {}
+void unhandled_exception() {}
+  };
+};
+
+// CHECK-LABEL: define void @_Z1gv()
+noexcept_task g() {
+  // If the await_resume function is marked as noexcept, none of the additional
+  // conditions that are present in f() above are added to the IR.
+  // This means that no i1 are stored before or after calling await_resume:
+  // CHECK: init.ready:
+  // CHECK-NEXT: call void @_ZN18noexcept_awaitable12await_resumeEv
+  // CHECK-NOT: store i1 false, i1*
   co_return;
 }
Index: lib/CodeGen/CGCoroutine.cpp
===
--- lib/CodeGen/CGCoroutine.cpp
+++ lib/CodeGen/CGCoroutine.cpp
@@ -217,8 +217,19 @@
 
   // Emit await_resume expression.
   CGF.EmitBlock(ReadyBlock);
+
+  // Exception handling requires additional IR. If the 'await_resume' function
+  // is marked as 'noexcept', we avoid generating this additional IR.
+  bool ResumeCanThrow = true;
+  if (const auto *MCE = dyn_cast(S.getResumeExpr()))
+if (const auto *Proto =
+MCE->getMethodDecl()->getType()->getAs())
+  if (isNoexceptExceptionSpec(Proto->getExceptionSpecType()) &&
+  Proto->canThrow() == CT_Cannot)
+ResumeCanThrow = false;
+
   CXXTryStmt *TryStmt = nullptr;
-  if (Coro.ExceptionHandler && Kind == AwaitKind::Init) {
+  if (Coro.ExceptionHandler && Kind == AwaitKind::Init && ResumeCanThrow) {
 Coro.ResumeEHVar =
 CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh"));
 Builder.CreateFlagStore(true, Coro.ResumeEHVar);
@@ -625,12 +636,20 @@
 CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal;
 
 if (CurCoro.Data->ExceptionHandler) {
-  BasicBlock *BodyBB = createBasicBlock("coro.resumed.body");
-  BasicBlock *ContBB = createBasicBlock("coro.resumed.cont");
-  Value *SkipBody =
-  Builder.CreateFlagLoad(CurCoro.Data->ResumeEHVar, "coro.resumed.eh");
-  Builder.CreateCondBr(SkipBody, ContBB, BodyBB);
-  EmitBlock(BodyBB);
+  // If we