llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb @llvm/pr-subscribers-debuginfo Author: Matt Davis (enferex) <details> <summary>Changes</summary> DW_OP_NVIDIA_mux (0xeb) takes a 1-byte unsigned selector, giving NVIDIA an extension space behind a single opcode in the crowded DW_OP_lo_user..DW_OP_hi_user range. The selector is opaque to LLVM; no NVIDIA operation semantics are defined here. Assissted-by: LLM --- Full diff: https://github.com/llvm/llvm-project/pull/216314.diff 6 Files Affected: - (modified) lldb/source/Expression/DWARFExpression.cpp (+1) - (modified) llvm/include/llvm/BinaryFormat/Dwarf.def (+7) - (modified) llvm/include/llvm/BinaryFormat/Dwarf.h (+1) - (modified) llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp (+2) - (modified) llvm/unittests/BinaryFormat/DwarfTest.cpp (+11) - (modified) llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp (+39) ``````````diff diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp index 2dbf61a14eac4..8b5944f206675 100644 --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -214,6 +214,7 @@ GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset, case DW_OP_HP_unmod_range: case DW_OP_HP_tls: case DW_OP_INTEL_bit_piece: + case DW_OP_NVIDIA_mux: case DW_OP_WASM_location: case DW_OP_WASM_location_int: case DW_OP_APPLE_uninit: diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index 32195aae562c3..885216bdc2de9 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -920,6 +920,13 @@ HANDLE_DW_OP(0xe5, HP_unmod_range, -1, -1, 0, HP) HANDLE_DW_OP(0xe6, HP_tls, -1, -1, 0, HP) HANDLE_DW_OP(0xe8, INTEL_bit_piece, -1, -1, 0, INTEL) +// Extension for NVIDIA. DW_OP_NVIDIA_mux acts as an extension multiplexer: its +// single 1-byte unsigned operand selects an NVIDIA-specific operation. This +// keeps the cost of the whole NVIDIA extension family at one encoding in the +// scarce DW_OP_lo_user..DW_OP_hi_user range. The selector value is opaque to +// LLVM; no NVIDIA operation semantics are defined here. +HANDLE_DW_OP(0xeb, NVIDIA_mux, 1, -1, 0, NVIDIA) + // Extensions for WebAssembly. HANDLE_DW_OP(0xed, WASM_location, -1, -1, 0, WASM) HANDLE_DW_OP(0xee, WASM_location_int, -1, -1, 0, WASM) diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 46124019206f2..ee7031b239479 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -83,6 +83,7 @@ enum LLVMConstants : uint32_t { DWARF_VENDOR_HP, DWARF_VENDOR_IBM, DWARF_VENDOR_INTEL, + DWARF_VENDOR_NVIDIA, DWARF_VENDOR_PGI, DWARF_VENDOR_SUN, DWARF_VENDOR_UPC, diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp index 61bd6fcb65bfa..654fb459feb37 100644 --- a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp @@ -103,6 +103,8 @@ static std::vector<Desc> getOpDescriptions() { Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_implicit_pointer] = Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB); + // The operand is an opaque 8-bit selector for an NVIDIA-specific operation. + Descriptions[DW_OP_NVIDIA_mux] = Desc(Op::Dwarf5, Op::Size1); // This Description acts as a marker that getSubOpDesc must be called // to fetch the final Description for the operation. Each such final // Description must share the same first SizeSubOpLEB operand. diff --git a/llvm/unittests/BinaryFormat/DwarfTest.cpp b/llvm/unittests/BinaryFormat/DwarfTest.cpp index c9522226c6031..0366bd7b7610e 100644 --- a/llvm/unittests/BinaryFormat/DwarfTest.cpp +++ b/llvm/unittests/BinaryFormat/DwarfTest.cpp @@ -48,6 +48,9 @@ TEST(DwarfTest, getOperationEncoding) { EXPECT_EQ(DW_OP_deref, getOperationEncoding("DW_OP_deref")); EXPECT_EQ(DW_OP_bit_piece, getOperationEncoding("DW_OP_bit_piece")); + // A vendor extension. + EXPECT_EQ(DW_OP_NVIDIA_mux, getOperationEncoding("DW_OP_NVIDIA_mux")); + // Invalid ops. EXPECT_EQ(0u, getOperationEncoding("DW_OP_otherthings")); EXPECT_EQ(0u, getOperationEncoding("other")); @@ -57,6 +60,14 @@ TEST(DwarfTest, getOperationEncoding) { EXPECT_EQ(0u, getOperationEncoding("DW_OP_hi_user")); } +TEST(DwarfTest, OperationEncodingString) { + // A vendor extension. + EXPECT_EQ("DW_OP_NVIDIA_mux", OperationEncodingString(DW_OP_NVIDIA_mux)); + + // Unassigned encodings in the vendor range shouldn't be stringified. + EXPECT_EQ(StringRef(), OperationEncodingString(DW_OP_hi_user)); +} + TEST(DwarfTest, LanguageStringOnInvalid) { // This is invalid, so it shouldn't be stringified. EXPECT_EQ(StringRef(), LanguageString(0)); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp index e328f0ffa8809..a853a22360c95 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -208,6 +208,45 @@ TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_LLVM_user_unknown_subop) { "DW_OP_LLVM_form_aspace_address (2)>"); } +// DW_OP_NVIDIA_mux carries an opaque 8-bit selector, so the compact printer +// cannot know its stack effect and must bail out naming the opcode. +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_NVIDIA_mux) { + TestExprPrinterFailure({DW_OP_NVIDIA_mux, 0xa5}, + "<unknown op DW_OP_NVIDIA_mux (235)>"); +} + +// The selector is a fixed 1-byte operand, so the full printer must consume +// exactly one byte and print its value. +TEST(NVIDIAMux, Full_DW_OP_NVIDIA_mux) { + const uint8_t Enc[] = {DW_OP_NVIDIA_mux, 0xa5}; + + std::string Result; + raw_string_ostream OS(Result); + DataExtractor DE(Enc, true); + DWARFExpression Expr(DE, 8); + + DIDumpOptions DumpOpts; + printDwarfExpression(&Expr, OS, DumpOpts, nullptr); + + EXPECT_EQ(OS.str(), "DW_OP_NVIDIA_mux 0xa5"); +} + +// A trailing operation must still decode, proving the selector advanced the +// offset by exactly one byte. +TEST(NVIDIAMux, Full_DW_OP_NVIDIA_mux_TrailingOp) { + const uint8_t Enc[] = {DW_OP_NVIDIA_mux, 0xa5, DW_OP_stack_value}; + + std::string Result; + raw_string_ostream OS(Result); + DataExtractor DE(Enc, true); + DWARFExpression Expr(DE, 8); + + DIDumpOptions DumpOpts; + printDwarfExpression(&Expr, OS, DumpOpts, nullptr); + + EXPECT_EQ(OS.str(), "DW_OP_NVIDIA_mux 0xa5, DW_OP_stack_value"); +} + // NVPTX packs virtual register names into DWARF register numbers, so compact // printing without a callback must recover the name and return true. TEST(NVPTXPackedRegister, Compact_DW_OP_regx_NoMRI) { `````````` </details> https://github.com/llvm/llvm-project/pull/216314 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
