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 @@ -1879,6 +1879,37 @@ return true; } +/// If V is a SwiftAsync Argument, return the ABI register associated +/// with it. +static std::optional<Register> +getRegisterIfSwiftAsyncArg(const Value &V, const MachineFunction &MF) { + auto *Arg = dyn_cast<Argument>(&V); + if (!Arg || !Arg->hasAttribute(Attribute::SwiftAsync)) + return std::nullopt; + return MF.getRegInfo().liveins()[Arg->getArgNo()].first; +} + +/// If DebugInst has a single location operand which is a SwiftAsync Argument, +/// translates DebugInst into a DBG_VALUE using the ABI register associated with +/// V and returns true. Otherwise, returns false. +static bool translateIfSwiftAsyncArg(const DbgVariableIntrinsic &DebugInst, + MachineIRBuilder &Builder) { + if (DebugInst.getNumVariableLocationOps() != 1) + return false; + auto MaybeReg = getRegisterIfSwiftAsyncArg( + *DebugInst.getVariableLocationOp(0), Builder.getMF()); + if (!MaybeReg) + return false; + + if (isa<DbgDeclareInst>(DebugInst)) + Builder.buildIndirectDbgValue(*MaybeReg, DebugInst.getVariable(), + DebugInst.getExpression()); + else + Builder.buildDirectDbgValue(*MaybeReg, DebugInst.getVariable(), + DebugInst.getExpression()); + return true; +} + bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { if (auto *MI = dyn_cast<AnyMemIntrinsic>(&CI)) { @@ -1945,6 +1976,7 @@ // instructions (in fact, they get ignored if they *do* exist). MF->setVariableDbgInfo(DI.getVariable(), DI.getExpression(), getOrCreateFrameIndex(*AI), DI.getDebugLoc()); + } else if (translateIfSwiftAsyncArg(DI, MIRBuilder)) { } else { // A dbg.declare describes the address of a source variable, so lower it // into an indirect DBG_VALUE. @@ -2004,6 +2036,7 @@ DIExpression::get(AI->getContext(), ExprOperands.drop_front()); MIRBuilder.buildFIDbgValue(getOrCreateFrameIndex(*AI), DI.getVariable(), ExprDerefRemoved); + } else if (translateIfSwiftAsyncArg(DI, MIRBuilder)) { } else { for (Register Reg : getOrCreateVRegs(*V)) { // FIXME: This does not handle register-indirect values at offset 0. The diff --git a/llvm/test/CodeGen/AArch64/dbg-swift-async.ll b/llvm/test/CodeGen/AArch64/dbg-swift-async.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/dbg-swift-async.ll @@ -0,0 +1,34 @@ +; RUN: llc -O0 -global-isel -stop-after=irtranslator --print-after=irtranslator -verify-machineinstrs %s -o %t 2>&1 | FileCheck %s + +; CHECK: Function Live Ins: $w0, $x22, $w1 +; CHECK: DBG_VALUE $x22, 0, !"a", !DIExpression(DW_OP_deref) +; CHECK-NEXT: DBG_VALUE $x22, $noreg, !"b", !DIExpression(DW_OP_deref) + +target triple="aarch64--" + +define void @f(i32 %blah, i8* swiftasync %async_arg, i32 %blah2) !dbg !6 { + call void @llvm.dbg.declare(metadata ptr %async_arg, metadata !12, metadata !DIExpression(DW_OP_deref)), !dbg !14 + call void @llvm.dbg.value(metadata ptr %async_arg, metadata !13, metadata !DIExpression(DW_OP_deref)), !dbg !14 + ret void, !dbg !15 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!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 = !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) +!13 = !DILocalVariable(name: "b", scope: !6, file: !1, line: 1, type: !9) +!14 = !DILocation(line: 1, column: 29, scope: !6) +!15 = !DILocation(line: 1, column: 37, scope: !6)