Index: llvm/lib/Transforms/Coroutines/CoroFrame.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -2513,8 +2513,8 @@ bool OutermostLoad = true; Value *Storage = DVI->getVariableLocationOp(0); Value *OriginalStorage = Storage; - while (Storage) { - if (auto *LdInst = dyn_cast(Storage)) { + while (auto *Inst = dyn_cast(Storage)) { + if (auto *LdInst = dyn_cast(Inst)) { Storage = LdInst->getOperand(0); // FIXME: This is a heuristic that works around the fact that // LLVM IR debug intrinsics cannot yet distinguish between @@ -2525,29 +2525,24 @@ if (!OutermostLoad) Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); OutermostLoad = false; - } else if (auto *StInst = dyn_cast(Storage)) { + } else if (auto *StInst = dyn_cast(Inst)) { Storage = StInst->getOperand(0); - } else if (auto *GEPInst = dyn_cast(Storage)) { + } else { SmallVector Ops; SmallVector AdditionalValues; - Storage = llvm::salvageDebugInfoImpl( - *GEPInst, Expr ? Expr->getNumLocationOperands() : 0, Ops, + Value *Op = llvm::salvageDebugInfoImpl( + *Inst, Expr ? Expr->getNumLocationOperands() : 0, Ops, AdditionalValues); - if (!Storage) - break; - // Debug declares cannot currently handle additional location - // operands. - if (!AdditionalValues.empty()) + if (!Op || !AdditionalValues.empty()) { + // If salvaging failed or salvaging produced more than one location + // operand, give up. break; + } + Storage = Op; Expr = DIExpression::appendOpsToArg(Expr, Ops, 0, /*StackValue*/false); - } else if (auto *BCInst = dyn_cast(Storage)) - Storage = BCInst->getOperand(0); - else - break; + } } - if (!Storage) - return; - + // Store a pointer to the coroutine frame object in an alloca so it // is available throughout the function when producing unoptimized // code. Extending the lifetime this way is correct because the Index: llvm/test/Transforms/Coroutines/coro-debug.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-debug.ll +++ llvm/test/Transforms/Coroutines/coro-debug.ll @@ -154,7 +154,7 @@ ; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[RESUME_DIRECT:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[EXPR_TAIL]]) ; CHECK: store %f.Frame* {{.*}}, %f.Frame** %[[DBG_PTR]] ; CHECK-NOT: alloca %struct.test* -; CHECK: call void @llvm.dbg.declare(metadata i32 0, metadata ![[RESUME_CONST:[0-9]+]], metadata !DIExpression()) +; CHECK: call void @llvm.dbg.declare(metadata i8 0, metadata ![[RESUME_CONST:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed)) ; Note that keeping the undef value here could be acceptable, too. ; CHECK-NOT: call void @llvm.dbg.declare(metadata i32* undef, metadata !{{[0-9]+}}, metadata !DIExpression()) ; CHECK: call void @coro.devirt.trigger(i8* null)