diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2501,8 +2501,8 @@ // encoding is supported. assert(AP.TM.getTargetTriple().isWasm()); DwarfExpr.addWasmLocation(Loc.Index, static_cast(Loc.Offset)); - DwarfExpr.addExpression(std::move(ExprCursor)); - return; + DwarfExpr.addExpression(std::move(ExprCursor)); + return; } else if (Value.isConstantFP()) { if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() && !ExprCursor) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -664,9 +664,14 @@ } void DwarfExpression::addWasmLocation(unsigned Index, uint64_t Offset) { - assert(LocationKind == Implicit || LocationKind == Unknown); - LocationKind = Implicit; emitOp(dwarf::DW_OP_WASM_location); - emitUnsigned(Index); + emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index); emitUnsigned(Offset); + if (Index == 4 /*TI_LOCAL_INDIRECT*/) { + assert(LocationKind == Unknown); + LocationKind = Memory; + } else { + assert(LocationKind == Implicit || LocationKind == Unknown); + LocationKind = Implicit; + } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -174,7 +174,10 @@ case Operation::WasmLocationArg: assert(Operand == 1); switch (Operands[0]) { - case 0: case 1: case 2: + case 0: + case 1: + case 2: + case 4: Operands[Operand] = Data.getULEB128(&Offset); break; case 3: // global as uint32 @@ -294,8 +297,11 @@ } else if (Size == Operation::WasmLocationArg) { assert(Operand == 1); switch (Operands[0]) { - case 0: case 1: case 2: + case 0: + case 1: + case 2: case 3: // global as uint32 + case 4: OS << format(" 0x%" PRIx64, Operands[Operand]); break; default: assert(false); diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.h b/llvm/lib/Target/WebAssembly/WebAssembly.h --- a/llvm/lib/Target/WebAssembly/WebAssembly.h +++ b/llvm/lib/Target/WebAssembly/WebAssembly.h @@ -87,10 +87,14 @@ TI_LOCAL, // Followed by an absolute global index (ULEB). DEPRECATED. TI_GLOBAL_FIXED, + // Followed by the index from the bottom of the Wasm stack. TI_OPERAND_STACK, // Followed by a compilation unit relative global index (uint32_t) // that will have an associated relocation. - TI_GLOBAL_RELOC + TI_GLOBAL_RELOC, + // Like TI_LOCAL, but indicates an indirect value (e.g. byval arg + // passed by pointer). + TI_LOCAL_INDIRECT }; } // end namespace WebAssembly diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -59,7 +59,11 @@ void WebAssemblyDebugValueManager::replaceWithLocal(unsigned LocalId) { for (auto *DBI : DbgValues) { - MachineOperand &Op = DBI->getDebugOperand(0); - Op.ChangeToTargetIndex(llvm::WebAssembly::TI_LOCAL, LocalId); + MachineOperand &Op0 = DBI->getDebugOperand(0); + MachineOperand &Op1 = DBI->getOperand(1); + bool Indirect = Op1.isImm() && Op1.getImm() == 0; + Op0.ChangeToTargetIndex(Indirect ? llvm::WebAssembly::TI_LOCAL_INDIRECT + : llvm::WebAssembly::TI_LOCAL, + LocalId); } } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp @@ -210,6 +210,7 @@ {WebAssembly::TI_LOCAL, "wasm-local"}, {WebAssembly::TI_GLOBAL_FIXED, "wasm-global-fixed"}, {WebAssembly::TI_OPERAND_STACK, "wasm-operand-stack"}, - {WebAssembly::TI_GLOBAL_RELOC, "wasm-global-reloc"}}; + {WebAssembly::TI_GLOBAL_RELOC, "wasm-global-reloc"}, + {WebAssembly::TI_LOCAL_INDIRECT, "wasm-local-indirect"}}; return makeArrayRef(TargetIndices); } diff --git a/llvm/test/MC/WebAssembly/debug-byval-struct.ll b/llvm/test/MC/WebAssembly/debug-byval-struct.ll --- a/llvm/test/MC/WebAssembly/debug-byval-struct.ll +++ b/llvm/test/MC/WebAssembly/debug-byval-struct.ll @@ -103,11 +103,11 @@ ; CHECK-NEXT: DW_AT_name ("x") ; CHECK-LABEL: DW_TAG_formal_parameter -; CHECK-NEXT: DW_AT_location (DW_OP_WASM_location 0x0 0x1, DW_OP_stack_value) +; CHECK-NEXT: DW_AT_location (DW_OP_WASM_location 0x0 0x1) ; CHECK-NEXT: DW_AT_name ("some_union") ; CHECK-LABEL: DW_TAG_formal_parameter -; CHECK-NEXT: DW_AT_location (DW_OP_WASM_location 0x0 0x2, DW_OP_stack_value) +; CHECK-NEXT: DW_AT_location (DW_OP_WASM_location 0x0 0x2) ; CHECK-NEXT: DW_AT_name ("some_struct") ; CHECK-LABEL: DW_TAG_formal_parameter