[PATCH] D33817: PR33271: Remove stray coro.save intrinsics during CoroSplit

Gor Nishanov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 1 18:24:01 PDT 2017


GorNishanov created this revision.

Optimization passes may remove llvm.coro.suspend intrinsic while leaving matching llvm.coro.save intrinsic orphaned.
Make sure we clean up orphaned coro.saves.  The bug manifested with a crash similar to this:

  llvm_unreachable("Unknown type!");
  llvm::MVT::getVT (Ty=0x489518, HandleUnknown=false)
  llvm::EVT::getEVT 
  llvm::TargetLoweringBase::getValueType
  llvm::ComputeValueVTs
  llvm::SelectionDAGBuilder::visitTargetIntrinsic


https://reviews.llvm.org/D33817

Files:
  lib/Transforms/Coroutines/Coroutines.cpp
  test/Transforms/Coroutines/coro-split-02.ll


Index: test/Transforms/Coroutines/coro-split-02.ll
===================================================================
--- test/Transforms/Coroutines/coro-split-02.ll
+++ test/Transforms/Coroutines/coro-split-02.ll
@@ -1,5 +1,6 @@
 ; Tests that coro-split can handle the case when a code after coro.suspend uses
 ; a value produces between coro.save and coro.suspend (%Result.i19)
+; and checks whether stray coro.saves are properly removed
 ; RUN: opt < %s -coro-split -S | FileCheck %s
 
 %"struct.std::coroutine_handle" = type { i8* }
@@ -24,17 +25,19 @@
     i8 1, label %exit
   ]
 await.ready:
+  %StrayCoroSave = call token @llvm.coro.save(i8* null)
   %val = load i32, i32* %Result.i19
   call void @print(i32 %val)
-  br label %exit  
+  br label %exit
 exit:
   call i1 @llvm.coro.end(i8* null, i1 false)
   ret void
 }
 
 ; CHECK-LABEL: @a.resume(
 ; CHECK:         getelementptr inbounds %a.Frame
 ; CHECK-NEXT:    getelementptr inbounds %"struct.lean_future<int>::Awaiter"
+; CHECK-NOT:     call token @llvm.coro.save(i8* null)
 ; CHECK-NEXT:    %val = load i32, i32* %Result
 ; CHECK-NEXT:    call void @print(i32 %val)
 ; CHECK-NEXT:    ret void
Index: lib/Transforms/Coroutines/Coroutines.cpp
===================================================================
--- lib/Transforms/Coroutines/Coroutines.cpp
+++ lib/Transforms/Coroutines/Coroutines.cpp
@@ -218,6 +218,8 @@
   size_t FinalSuspendIndex = 0;
   clear(*this);
   SmallVector<CoroFrameInst *, 8> CoroFrames;
+  SmallVector<CoroSaveInst *, 2> UnusedCoroSaves;
+
   for (Instruction &I : instructions(F)) {
     if (auto II = dyn_cast<IntrinsicInst>(&I)) {
       switch (II->getIntrinsicID()) {
@@ -229,6 +231,12 @@
       case Intrinsic::coro_frame:
         CoroFrames.push_back(cast<CoroFrameInst>(II));
         break;
+      case Intrinsic::coro_save:
+        // After optimizations, coro_suspends using this coro_save might have
+        // been removed, remember orphaned coro_saves to remove them later.
+        if (II->use_empty())
+          UnusedCoroSaves.push_back(cast<CoroSaveInst>(II));
+        break;
       case Intrinsic::coro_suspend:
         CoroSuspends.push_back(cast<CoroSuspendInst>(II));
         if (CoroSuspends.back()->isFinal()) {
@@ -311,4 +319,8 @@
   if (HasFinalSuspend &&
       FinalSuspendIndex != CoroSuspends.size() - 1)
     std::swap(CoroSuspends[FinalSuspendIndex], CoroSuspends.back());
+
+  // Remove orphaned coro.saves.
+  for (CoroSaveInst *CoroSave : UnusedCoroSaves)
+    CoroSave->eraseFromParent();
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33817.101156.patch
Type: text/x-patch
Size: 2532 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170602/6c3e4172/attachment.bin>


More information about the llvm-commits mailing list