[Lldb-commits] [lldb] [lldb][AMDGPU] Support terminal DW_OP_LLVM_piece_end (PR #220774)
Chen Li via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 3 10:05:20 PDT 2026
https://github.com/thechenli updated https://github.com/llvm/llvm-project/pull/220774
>From cd1222e6a6a4a30f1fa2171c3e3309f3544c3b0d Mon Sep 17 00:00:00 2001
From: Chen Li <chenlii at fb.com>
Date: Wed, 2 Sep 2026 17:36:11 -0700
Subject: [PATCH] [lldb][AMDGPU] Support terminal DW_OP_LLVM_piece_end
---
lldb/source/Expression/DWARFExpression.cpp | 18 ++++++++++++
.../Expression/DWARFExpressionTest.cpp | 28 +++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 60577bac07167..338bbf24cbb27 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -2228,6 +2228,24 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
return llvm::createStringError("unimplemented opcode %s",
DW_OP_value_to_name(opcode));
+ case DW_OP_LLVM_user:
+ if (op->getSubCode() == DW_OP_LLVM_piece_end) {
+ if (op->getEndOffset() != expr_data.size())
+ return llvm::createStringError(
+ "DW_OP_LLVM_piece_end is only supported at the end of an "
+ "expression");
+
+ // LLDB already constructs one composite in `pieces`, so a terminal
+ // DW_OP_LLVM_piece_end is a no-op. TODO: Support multiple composites
+ // and DW_OP_piece_end once LLVM implements DWARF 6 locations on the
+ // stack.
+ // Extension:
+ // https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html
+ // Standard: https://dwarfstd.org/issues/230524.1-orig.html
+ break;
+ }
+ [[fallthrough]];
+
default:
if (eval_ctx.dwarf_cu) {
const uint64_t operands_offset = op_offset + 1;
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 4b4b911800ae8..31e629967c6a2 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -1597,6 +1597,34 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_regx) {
ExpectScalar(0xBEEF, Value::ContextType::RegisterInfo));
}
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_LLVM_piece_end) {
+ TestContext ctx;
+ constexpr uint64_t reg_value = 0x8877665544332211;
+ ASSERT_TRUE(
+ CreateTestContext(&ctx, "i386-pc-linux", RegisterValue(reg_value)));
+
+ ExecutionContext exe_ctx(ctx.process_sp);
+ MockDwarfDelegate delegate = MockDwarfDelegate::Dwarf5();
+
+ // Match the expression emitted for a value split across two AMDGPU
+ // registers. A terminal DW_OP_LLVM_piece_end completes the composite.
+ EXPECT_THAT_EXPECTED(
+ Evaluate({DW_OP_regx, 0x20, DW_OP_piece, 4, DW_OP_regx, 0x21, DW_OP_piece,
+ 4, DW_OP_LLVM_user, DW_OP_LLVM_piece_end},
+ {}, &delegate, &exe_ctx, ctx.reg_ctx_sp.get()),
+ ExpectHostAddress({0x11, 0x22, 0x33, 0x44, 0x11, 0x22, 0x33, 0x44}));
+}
+
+TEST(DWARFExpression, DW_OP_LLVM_piece_end_multiple) {
+ EXPECT_THAT_ERROR(
+ Evaluate({DW_OP_const1u, 0xaa, DW_OP_piece, 1, DW_OP_LLVM_user,
+ DW_OP_LLVM_piece_end, DW_OP_LLVM_user, DW_OP_LLVM_piece_end})
+ .takeError(),
+ llvm::FailedWithMessage(
+ "DW_OP_LLVM_piece_end is only supported at the end of an "
+ "expression"));
+}
+
TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref_size_zero) {
// DW_OP_deref_size with size 0 must report an error instead of constructing
// a DataExtractor with addr_size 0 (caught by lldb-dwarf-expression-fuzzer:
More information about the lldb-commits
mailing list