diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp index ac3d078714ce1b..e691decfa9b1b4 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(DVI)) { - if (auto *InsertPt = dyn_cast(Storage)) + if (auto *II = dyn_cast(Storage)) + DVI->moveBefore(II->getNormalDest()->getFirstNonPHI()); + else if (auto *InsertPt = dyn_cast(Storage)) { + assert(!InsertPt->isTerminator() && + "Unimaged terminator that could return a storage."); DVI->moveAfter(InsertPt); - else if (isa(Storage)) + } else if (isa(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 6bff5474642e2f..0108f7c4c6cd2f 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"