[llvm] 8498076 - [Coroutines] Handle InvokeInst in SalvageDebugInfo

Chuanqi Xu via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 2 21:53:57 PST 2021


Author: Chuanqi Xu
Date: 2021-12-03T13:46:54+08:00
New Revision: 84980761a777619291e4877014c5f00ca512e4b8

URL: https://github.com/llvm/llvm-project/commit/84980761a777619291e4877014c5f00ca512e4b8
DIFF: https://github.com/llvm/llvm-project/commit/84980761a777619291e4877014c5f00ca512e4b8.diff

LOG: [Coroutines] Handle InvokeInst in SalvageDebugInfo

Since coroutine would be splitted into pieces, compiler would move the
dbg.declare intrinsic after the Storage is created to make sure the
corresponding dbg instruction is still available aftet splitted.
However, it would be problematic if the storage instruction is an
InvokeInst, which is a terminator. We couldn't move instruction after an
InvokeInst. This patch tries to move the dbg.declare intrinsic in the
normal destination of the InvokeInst. It should make sense due to the
Storage should be invalid in exception path.

Added: 
    

Modified: 
    llvm/lib/Transforms/Coroutines/CoroFrame.cpp
    llvm/test/Transforms/Coroutines/coro-debug.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index ac3d078714ce1..e691decfa9b1b 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -2572,9 +2572,13 @@ void coro::salvageDebugInfo(
   DVI->setExpression(Expr);
   /// It makes no sense to move the dbg.value intrinsic.
   if (!isa<DbgValueInst>(DVI)) {
-    if (auto *InsertPt = dyn_cast<Instruction>(Storage))
+    if (auto *II = dyn_cast<InvokeInst>(Storage))
+      DVI->moveBefore(II->getNormalDest()->getFirstNonPHI());
+    else if (auto *InsertPt = dyn_cast<Instruction>(Storage)) {
+      assert(!InsertPt->isTerminator() &&
+             "Unimaged terminator that could return a storage.");
       DVI->moveAfter(InsertPt);
-    else if (isa<Argument>(Storage))
+    } else if (isa<Argument>(Storage))
       DVI->moveAfter(F->getEntryBlock().getFirstNonPHI());
   }
 }

diff  --git a/llvm/test/Transforms/Coroutines/coro-debug.ll b/llvm/test/Transforms/Coroutines/coro-debug.ll
index 6bff5474642e2..0108f7c4c6cd2 100644
--- a/llvm/test/Transforms/Coroutines/coro-debug.ll
+++ b/llvm/test/Transforms/Coroutines/coro-debug.ll
@@ -6,7 +6,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 ; Function Attrs: noinline nounwind
-define i8* @f(i32 %x) #0 !dbg !6 {
+define i8* @f(i32 %x) #0 personality i32 0 !dbg !6 {
 entry:
   %x.addr = alloca i32, align 4
   %coro_hdl = alloca i8*, align 8
@@ -39,7 +39,8 @@ sw.bb:                                            ; preds = %entry
   ; don't crash when encountering nonsensical debug info, verfifier doesn't yet reject these
   call void @llvm.dbg.declare(metadata i8* null, metadata !28, metadata !13), !dbg !16
   call void @llvm.dbg.declare(metadata !{}, metadata !28, metadata !13), !dbg !16
-  br label %next, !dbg !18
+  %new_storgae = invoke i8* @allocate()
+    to label %next unwind label %ehcleanup, !dbg !18
 
 next:
   br label %sw.epilog, !dbg !18
@@ -51,6 +52,7 @@ sw.default:                                       ; preds = %entry
   br label %coro_Suspend, !dbg !18
 
 sw.epilog:                                        ; preds = %sw.bb
+  call void @llvm.dbg.declare(metadata i8* %new_storgae, metadata !31, metadata !13), !dbg !16
   %4 = load i32, i32* %x.addr, align 4, !dbg !20
   %add = add nsw i32 %4, 1, !dbg !21
   store i32 %add, i32* %x.addr, align 4, !dbg !22
@@ -67,6 +69,12 @@ coro_Suspend:                                     ; preds = %coro_Cleanup, %sw.d
   %8 = load i8*, i8** %coro_hdl, align 8, !dbg !24
   store i32 0, i32* %late_local, !dbg !24
   ret i8* %8, !dbg !24
+
+ehcleanup:
+  %ex = landingpad { i8*, i32 }
+          catch i8* null
+  call void @print({ i8*, i32 } %ex)
+  unreachable
 }
 
 ; Function Attrs: nounwind readnone speculatable
@@ -79,6 +87,8 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
 declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #2
 
 declare i8* @malloc(i64) #3
+declare i8* @allocate() 
+declare void @print({ i8*, i32 })
 
 ; Function Attrs: nounwind readnone
 declare i64 @llvm.coro.size.i64() #4
@@ -151,9 +161,10 @@ attributes #7 = { noduplicate }
 !28 = !DILocalVariable(name: "null", scope: !6, file: !7, line: 55, type: !11)
 !29 = !DILocalVariable(name: "partial_dead", scope: !6, file: !7, line: 55, type: !11)
 !30 = !DILocalVariable(name: "direct_value", scope: !6, file: !7, line: 55, type: !11)
+!31 = !DILocalVariable(name: "allocated", scope: !6, file: !7, line: 55, type: !11)
 
-; CHECK: define i8* @f(i32 %x) #0 !dbg ![[ORIG:[0-9]+]]
-; CHECK: define internal fastcc void @f.resume(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[RESUME:[0-9]+]]
+; CHECK: define i8* @f(i32 %x) #0 personality i32 0 !dbg ![[ORIG:[0-9]+]]
+; CHECK: define internal fastcc void @f.resume(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 personality i32 0 !dbg ![[RESUME:[0-9]+]]
 ; CHECK: entry.resume:
 ; CHECK: %[[DBG_PTR:.*]] = alloca %f.Frame*
 ; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[RESUME_COROHDL:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst,
@@ -166,8 +177,13 @@ attributes #7 = { noduplicate }
 ; CHECK-NOT: call void @llvm.dbg.declare(metadata i32* undef, metadata !{{[0-9]+}}, metadata !DIExpression())
 ; CHECK: call void @coro.devirt.trigger(i8* null)
 ; CHECK: call void @llvm.dbg.value(metadata %f.Frame** {{.*}}, metadata ![[RESUME_DIRECT_VALUE:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref))
-; CHECK: define internal fastcc void @f.destroy(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[DESTROY:[0-9]+]]
-; CHECK: define internal fastcc void @f.cleanup(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[CLEANUP:[0-9]+]]
+; Check that the dbg.declare intrinsic of invoke instruction is hanled correctly.
+; CHECK: %[[ALLOCATED_STORAGE:.+]] = invoke i8* @allocate()
+; CHECK-NEXT: to label %[[NORMAL_DEST:.+]] unwind
+; CHECK: [[NORMAL_DEST]]
+; CHEKC-NEXT: call void @llvm.dbg.declare(metadata i8* %[[ALLOCATED_STORAGE]]
+; CHECK: define internal fastcc void @f.destroy(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 personality i32 0 !dbg ![[DESTROY:[0-9]+]]
+; CHECK: define internal fastcc void @f.cleanup(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 personality i32 0 !dbg ![[CLEANUP:[0-9]+]]
 
 ; CHECK: ![[ORIG]] = distinct !DISubprogram(name: "f", linkageName: "flink"
 


        


More information about the llvm-commits mailing list