diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -42,6 +42,7 @@ class ConstrainedFPIntrinsic; class DataLayout; class DbgDeclareInst; +class DbgValueInst; class Instruction; class MachineBasicBlock; class MachineFunction; @@ -253,6 +254,12 @@ /// lower it as an entry in the MF debug table. bool translateIfEntryValueArgument(const DbgDeclareInst &DebugInst); + /// If DebugInst targets an Argument and its expression is an EntryValue, + /// lower as a DBG_VALUE targeting the corresponding livein register for that + /// Argument. + bool translateIfEntryValueArgument(const DbgValueInst &DebugInst, + MachineIRBuilder &MIRBuilder); + bool translateInlineAsm(const CallBase &CB, MachineIRBuilder &MIRBuilder); /// Common code for translating normal calls or invokes. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1891,6 +1891,29 @@ return VRegDef->getOperand(1).getReg().asMCReg(); } +bool IRTranslator::translateIfEntryValueArgument(const DbgValueInst &DebugInst, + MachineIRBuilder &MIRBuilder) { + auto *Arg = dyn_cast(DebugInst.getValue()); + if (!Arg) + return false; + + const DIExpression *Expr = DebugInst.getExpression(); + if (!Expr->isEntryValue()) + return false; + + std::optional PhysReg = getArgPhysReg(*Arg); + if (!PhysReg) { + LLVM_DEBUG(dbgs() << "Dropping dbg.value: expression is entry_value but " + "couldn't find a physical register\n" + << DebugInst << "\n"); + return true; + } + + MIRBuilder.buildDirectDbgValue(*PhysReg, DebugInst.getVariable(), + DebugInst.getExpression()); + return true; +} + bool IRTranslator::translateIfEntryValueArgument( const DbgDeclareInst &DebugInst) { auto *Arg = dyn_cast(DebugInst.getAddress()); @@ -2044,6 +2067,8 @@ ExprDerefRemoved); return true; } + if (translateIfEntryValueArgument(DI, MIRBuilder)) + return true; for (Register Reg : getOrCreateVRegs(*V)) { // FIXME: This does not handle register-indirect values at offset 0. The // direct/indirect thing shouldn't really be handled by something as diff --git a/llvm/test/CodeGen/AArch64/dbg-value-swift-async.ll b/llvm/test/CodeGen/AArch64/dbg-value-swift-async.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/dbg-value-swift-async.ll @@ -0,0 +1,35 @@ +; RUN: llc -O0 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s + +; CHECK-NOT: DBG_VALUE +; CHECK: DBG_VALUE $x22, $noreg, !{{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1) +; CHECK-NEXT: DBG_VALUE $x22, $noreg, !{{.*}}, !DIExpression(DW_OP_LLVM_entry_value, 1) +; CHECK-NOT: DBG_VALUE + +target triple="aarch64--" + +define void @foo(ptr %unused_arg, ptr swiftasync %async_arg) !dbg !6 { + call void @llvm.dbg.value(metadata ptr %async_arg, metadata !12, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !14 + call void @llvm.dbg.value(metadata ptr %async_arg, metadata !12, metadata !DIExpression(DW_OP_LLVM_entry_value, 1)), !dbg !14 + call void @consume(ptr %async_arg) + ret void, !dbg !15 +} + +declare void @llvm.dbg.value(metadata, metadata, metadata) +declare void @consume(ptr %ptr) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +!1 = !DIFile(filename: "x.c", directory: "/") +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, unit: !0) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9, !9, !9} +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !11) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !DILocalVariable(name: "a", scope: !6, file: !1, line: 1, type: !9) +!14 = !DILocation(line: 1, column: 29, scope: !6) +!15 = !DILocation(line: 1, column: 37, scope: !6)