https://github.com/firmiana402 updated 
https://github.com/llvm/llvm-project/pull/204353

>From d3248dd31deea96f173dbbd0ba2ad514ea2a15bf Mon Sep 17 00:00:00 2001
From: firmiana402 <[email protected]>
Date: Wed, 17 Jun 2026 19:17:07 +0800
Subject: [PATCH 1/2] [DebugInfo][LLDB] Fix generic DW_OP_const handling

Make LLDB evaluate DW_OP_constu and DW_OP_consts as generic address-sized 
values, and teach LLVM to use DW_OP_implicit_value for wide integer constants 
that cannot be represented by a target generic value.
---
 lldb/source/Expression/DWARFExpression.cpp    |  6 ++--
 .../Expression/DWARFExpressionTest.cpp        |  6 ++--
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    | 35 +++++++++++++++++--
 .../CodeGen/AsmPrinter/DwarfExpression.cpp    | 21 +++++++++++
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h |  3 ++
 llvm/test/DebugInfo/X86/constant-loclist.ll   | 16 +++++++++
 6 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index dd436e0c8afd9..7966673bb65ed 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1411,13 +1411,11 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
     case DW_OP_const8s:
       stack.push_back(to_generic(static_cast<int64_t>(op->getRawOperand(0))));
       break;
-    // These should also use to_generic, but we can't do that due to a
-    // producer-side bug in llvm. See llvm.org/pr48087.
     case DW_OP_constu:
-      stack.push_back(Scalar(op->getRawOperand(0)));
+      stack.push_back(to_generic(op->getRawOperand(0)));
       break;
     case DW_OP_consts:
-      stack.push_back(Scalar(static_cast<int64_t>(op->getRawOperand(0))));
+      stack.push_back(to_generic(static_cast<int64_t>(op->getRawOperand(0))));
       break;
 
     case DW_OP_dup:
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 6d4a624505390..7feacb2b9da24 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -388,13 +388,13 @@ TEST(DWARFExpression, DW_OP_const) {
       Evaluate({DW_OP_const8s, 0x00, 0x11, 0x22, 0x33, 0x44, 0x42, 0x47, 
0x88}),
       ExpectScalar(0x33221100));
 
-  // Don't truncate to address size for compatibility with clang (pr48087).
+  // LEB constants also push generic values, so truncate to address size.
   EXPECT_THAT_EXPECTED(
       Evaluate({DW_OP_constu, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}),
-      ExpectScalar(0x01010101010101));
+      ExpectScalar(32, 0x01010101, false));
   EXPECT_THAT_EXPECTED(
       Evaluate({DW_OP_consts, 0x81, 0x82, 0x84, 0x88, 0x90, 0xa0, 0x40}),
-      ExpectScalar(0xffff010101010101));
+      ExpectScalar(32, 0x01010101, true));
 }
 
 TEST(DWARFExpression, DW_OP_skip) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 3479485cf866c..02e1d8667cc62 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -50,6 +50,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MD5.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetMachine.h"
@@ -3251,10 +3252,38 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter 
&AP, const DIBasicType *BT,
                             &AP](const DbgValueLocEntry &Entry,
                                  DIExpressionCursor &Cursor) -> bool {
     if (Entry.isInt()) {
-      if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean))
+      if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean)) {
         DwarfExpr.addBooleanConstant(Entry.getInt());
-      else if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
-                      BT->getEncoding() == dwarf::DW_ATE_signed_char))
+        return true;
+      }
+
+      bool IsSigned = BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
+                             BT->getEncoding() == dwarf::DW_ATE_signed_char);
+      unsigned GenericBitSize = AP.MAI.getCodePointerSize() * 8;
+      if (BT && AP.getDwarfVersion() >= 4 &&
+          !AP.getDwarfDebug()->tuneForSCE() && !Cursor) {
+        // DW_OP_const* pushes a generic, address-sized value. For a wider
+        // source integer value that cannot fit in the generic type, use
+        // DW_OP_implicit_value to preserve the source bytes instead. Keep this
+        // limited to complete constant values: SCE tuning already avoids
+        // DW_OP_implicit_value for compatibility, and expressions with
+        // remaining operations may need a scalar stack value rather than an
+        // implicit value block.
+        uint64_t TypeBitSize = BT->getSizeInBits();
+        bool IsByteSized = TypeBitSize % 8 == 0;
+        bool IsOutOfRange =
+            IsSigned ? !isIntN(GenericBitSize, Entry.getInt())
+                     : !isUIntN(GenericBitSize,
+                                static_cast<uint64_t>(Entry.getInt()));
+        if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
+          DwarfExpr.addImplicitValue(
+              APInt(static_cast<unsigned>(TypeBitSize),
+                    static_cast<uint64_t>(Entry.getInt()), IsSigned));
+          return true;
+        }
+      }
+
+      if (IsSigned)
         DwarfExpr.addSignedConstant(Entry.getInt());
       else
         DwarfExpr.addUnsignedConstant(Entry.getInt());
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index d9b2deb6ccf3d..4057605d973c3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -236,6 +236,27 @@ void DwarfExpression::addUnsignedConstant(const APInt 
&Value) {
   }
 }
 
+void DwarfExpression::addImplicitValue(const APInt &Value) {
+  assert(isImplicitLocation() || isUnknownLocation());
+  assert(DwarfVersion >= 4);
+
+  APInt API = Value;
+  unsigned NumBytes = API.getBitWidth() / 8;
+  assert(API.getBitWidth() == NumBytes * 8 &&
+         "implicit value must be byte-sized");
+
+  emitOp(dwarf::DW_OP_implicit_value);
+  emitUnsigned(NumBytes);
+
+  // The loop below is emitting the value starting at the least significant
+  // byte, so byte-swap first for big-endian targets.
+  if (CU.getAsmPrinter()->getDataLayout().isBigEndian())
+    API = API.byteSwap();
+
+  for (unsigned I = 0; I < NumBytes; ++I)
+    emitData1(API.extractBits(8, I * 8).getZExtValue());
+}
+
 void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
   assert(isImplicitLocation() || isUnknownLocation());
   APInt API = APF.bitcastToAPInt();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h 
b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index c4929aed1c197..14357168c52c9 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -240,6 +240,9 @@ class DwarfExpression {
   /// Emit an unsigned constant.
   void addUnsignedConstant(const APInt &Value);
 
+  /// Emit an implicit value.
+  void addImplicitValue(const APInt &Value);
+
   /// Emit an floating point constant.
   void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
 
diff --git a/llvm/test/DebugInfo/X86/constant-loclist.ll 
b/llvm/test/DebugInfo/X86/constant-loclist.ll
index 630c652ba0ccf..7d33bfd4d3341 100644
--- a/llvm/test/DebugInfo/X86/constant-loclist.ll
+++ b/llvm/test/DebugInfo/X86/constant-loclist.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -filetype=obj %s -o - -experimental-debug-variable-locations=true | 
llvm-dwarfdump -v -debug-info - | FileCheck %s
+; RUN: llc -filetype=obj %s -o - -experimental-debug-variable-locations=true 
-mtriple=i386-unknown-linux-gnu -dwarf-version=4 | llvm-dwarfdump -v 
-debug-info - | FileCheck %s --check-prefix=I386
 
 ; A hand-written testcase to check 64-bit constant handling in location lists.
 
@@ -18,6 +19,21 @@
 ; CHECK-NEXT:   {{.*}}: DW_OP_constu 0x4000000000000000)
 ; CHECK-NEXT: DW_AT_name {{.*}}"d"
 
+; On 32-bit targets, source integer constants that do not fit in the
+; address-sized DWARF generic type must use DW_OP_implicit_value to avoid
+; truncating the source value.
+; I386: .debug_info contents:
+; I386: DW_TAG_variable
+; I386-NEXT: DW_AT_location
+; I386-NEXT:   {{.*}}: DW_OP_lit0
+; I386-NEXT:   {{.*}}: DW_OP_implicit_value 0x8 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x40)
+; I386-NEXT: DW_AT_name {{.*}}"u"
+; I386: DW_TAG_variable
+; I386-NEXT: DW_AT_location
+; I386-NEXT:   {{.*}}: DW_OP_consts +0
+; I386-NEXT:   {{.*}}: DW_OP_implicit_value 0x8 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x40)
+; I386-NEXT: DW_AT_name {{.*}}"i"
+
 source_filename = "test.c"
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx"

>From ba5aa101f47a34eba42d14ec7c48b58250d7aa08 Mon Sep 17 00:00:00 2001
From: firmiana402 <[email protected]>
Date: Mon, 22 Jun 2026 16:58:49 +0800
Subject: [PATCH 2/2] [DebugInfo] Address DW_OP_const review comments

---
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp      |  5 +++--
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp |  5 +++--
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h   |  2 +-
 llvm/test/DebugInfo/X86/constant-loclist.ll     | 16 ++++++++++++++++
 4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 02e1d8667cc62..64b6b27346575 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -3259,7 +3259,6 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, 
const DIBasicType *BT,
 
       bool IsSigned = BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
                              BT->getEncoding() == dwarf::DW_ATE_signed_char);
-      unsigned GenericBitSize = AP.MAI.getCodePointerSize() * 8;
       if (BT && AP.getDwarfVersion() >= 4 &&
           !AP.getDwarfDebug()->tuneForSCE() && !Cursor) {
         // DW_OP_const* pushes a generic, address-sized value. For a wider
@@ -3269,6 +3268,7 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, 
const DIBasicType *BT,
         // DW_OP_implicit_value for compatibility, and expressions with
         // remaining operations may need a scalar stack value rather than an
         // implicit value block.
+        unsigned GenericBitSize = AP.MAI.getCodePointerSize() * 8;
         uint64_t TypeBitSize = BT->getSizeInBits();
         bool IsByteSized = TypeBitSize % 8 == 0;
         bool IsOutOfRange =
@@ -3278,7 +3278,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, 
const DIBasicType *BT,
         if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
           DwarfExpr.addImplicitValue(
               APInt(static_cast<unsigned>(TypeBitSize),
-                    static_cast<uint64_t>(Entry.getInt()), IsSigned));
+                    static_cast<uint64_t>(Entry.getInt()), IsSigned),
+              AP);
           return true;
         }
       }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 4057605d973c3..ef83a877ad37c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -236,7 +236,8 @@ void DwarfExpression::addUnsignedConstant(const APInt 
&Value) {
   }
 }
 
-void DwarfExpression::addImplicitValue(const APInt &Value) {
+void DwarfExpression::addImplicitValue(const APInt &Value,
+                                       const AsmPrinter &AP) {
   assert(isImplicitLocation() || isUnknownLocation());
   assert(DwarfVersion >= 4);
 
@@ -250,7 +251,7 @@ void DwarfExpression::addImplicitValue(const APInt &Value) {
 
   // The loop below is emitting the value starting at the least significant
   // byte, so byte-swap first for big-endian targets.
-  if (CU.getAsmPrinter()->getDataLayout().isBigEndian())
+  if (AP.getDataLayout().isBigEndian())
     API = API.byteSwap();
 
   for (unsigned I = 0; I < NumBytes; ++I)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h 
b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 14357168c52c9..2525938c78d86 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -241,7 +241,7 @@ class DwarfExpression {
   void addUnsignedConstant(const APInt &Value);
 
   /// Emit an implicit value.
-  void addImplicitValue(const APInt &Value);
+  void addImplicitValue(const APInt &Value, const AsmPrinter &AP);
 
   /// Emit an floating point constant.
   void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
diff --git a/llvm/test/DebugInfo/X86/constant-loclist.ll 
b/llvm/test/DebugInfo/X86/constant-loclist.ll
index 7d33bfd4d3341..702f25ab2b71d 100644
--- a/llvm/test/DebugInfo/X86/constant-loclist.ll
+++ b/llvm/test/DebugInfo/X86/constant-loclist.ll
@@ -1,5 +1,6 @@
 ; RUN: llc -filetype=obj %s -o - -experimental-debug-variable-locations=true | 
llvm-dwarfdump -v -debug-info - | FileCheck %s
 ; RUN: llc -filetype=obj %s -o - -experimental-debug-variable-locations=true 
-mtriple=i386-unknown-linux-gnu -dwarf-version=4 | llvm-dwarfdump -v 
-debug-info - | FileCheck %s --check-prefix=I386
+; RUN: llc -filetype=obj %s -o - -experimental-debug-variable-locations=true 
-mtriple=i386-unknown-linux-gnu -dwarf-version=2 -debugger-tune=sce | 
llvm-dwarfdump -v -debug-info - | FileCheck %s --check-prefix=I386-COMPAT
 
 ; A hand-written testcase to check 64-bit constant handling in location lists.
 
@@ -34,6 +35,21 @@
 ; I386-NEXT:   {{.*}}: DW_OP_implicit_value 0x8 0x00 0x00 0x00 0x00 0x00 0x00 
0x00 0x40)
 ; I386-NEXT: DW_AT_name {{.*}}"i"
 
+; DWARF v2 and SCE tuning keep using DW_OP_const* for compatibility.
+; I386-COMPAT: .debug_info contents:
+; I386-COMPAT: DW_TAG_variable
+; I386-COMPAT-NEXT: DW_AT_location
+; I386-COMPAT-NEXT:   {{.*}}: DW_OP_lit0
+; I386-COMPAT-NOT: DW_OP_implicit_value
+; I386-COMPAT-NEXT:   {{.*}}: DW_OP_constu 0x4000000000000000)
+; I386-COMPAT-NEXT: DW_AT_name {{.*}}"u"
+; I386-COMPAT: DW_TAG_variable
+; I386-COMPAT-NEXT: DW_AT_location
+; I386-COMPAT-NEXT:   {{.*}}: DW_OP_consts +0
+; I386-COMPAT-NOT: DW_OP_implicit_value
+; I386-COMPAT-NEXT:   {{.*}}: DW_OP_consts +4611686018427387904)
+; I386-COMPAT-NEXT: DW_AT_name {{.*}}"i"
+
 source_filename = "test.c"
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx"

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to