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,7 @@ 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,7 +294,7 @@ } else if (Size == Operation::WasmLocationArg) { assert(Operand == 1); switch (Operands[0]) { - case 0: case 1: case 2: + case 0: case 1: case 2: case 4: case 3: // global as uint32 OS << format(" 0x%" PRIx64, Operands[Operand]); break; 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) that needs to be dereferenced. + 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 @@ -242,6 +242,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 0x4 0x1, DW_OP_stack_value) ; 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 0x4 0x2, DW_OP_stack_value) ; CHECK-NEXT: DW_AT_name ("some_struct") ; CHECK-LABEL: DW_TAG_formal_parameter