[llvm] Fix AsmWriter to account for dynamic bit offsets (PR #146704)
Tom Tromey via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 13:24:36 PDT 2025
https://github.com/tromey updated https://github.com/llvm/llvm-project/pull/146704
>From 16f9ec04edc8088e38229bef63837f6e5695605e Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey at adacore.com>
Date: Tue, 1 Jul 2025 14:17:27 -0600
Subject: [PATCH] Fix AsmWriter to account for dynamic bit offsets
PR #141106 changed the debug metadata to allow dynamic bit offsets and
sizes. In that patch, I forgot to update AsmWriter to handle this
case.
This patch corrects the oversight.
---
llvm/lib/IR/AsmWriter.cpp | 82 ++++++++++-----------
llvm/test/DebugInfo/X86/dynamic-bitfield.ll | 4 +-
2 files changed, 44 insertions(+), 42 deletions(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index af268b4fc6941..6d66e6402031c 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1914,6 +1914,8 @@ struct MDFieldPrinter {
bool ShouldSkipEmpty = true);
void printMetadata(StringRef Name, const Metadata *MD,
bool ShouldSkipNull = true);
+ void printMetadataOrInt(StringRef Name, const Metadata *MD, bool IsUnsigned,
+ bool ShouldSkipZero = true);
template <class IntTy>
void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned,
@@ -1986,6 +1988,21 @@ void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
writeMetadataAsOperand(Out, MD, WriterCtx);
}
+void MDFieldPrinter::printMetadataOrInt(StringRef Name, const Metadata *MD,
+ bool IsUnsigned, bool ShouldSkipZero) {
+ if (!MD)
+ return;
+
+ if (auto *CI = dyn_cast<ConstantAsMetadata>(MD)) {
+ auto *CV = cast<ConstantInt>(CI->getValue());
+ if (IsUnsigned)
+ printInt(Name, CV->getZExtValue(), ShouldSkipZero);
+ else
+ printInt(Name, CV->getSExtValue(), ShouldSkipZero);
+ } else
+ printMetadata(Name, MD);
+}
+
template <class IntTy>
void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
if (ShouldSkipZero && !Int)
@@ -2129,38 +2146,21 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
Out << "!DISubrange(";
MDFieldPrinter Printer(Out, WriterCtx);
- auto *Count = N->getRawCountNode();
- if (auto *CE = dyn_cast_or_null<ConstantAsMetadata>(Count)) {
- auto *CV = cast<ConstantInt>(CE->getValue());
- Printer.printInt("count", CV->getSExtValue(),
- /* ShouldSkipZero */ false);
- } else
- Printer.printMetadata("count", Count, /*ShouldSkipNull */ true);
+ Printer.printMetadataOrInt("count", N->getRawCountNode(),
+ /* IsUnsigned */ false,
+ /* ShouldSkipZero */ false);
// A lowerBound of constant 0 should not be skipped, since it is different
// from an unspecified lower bound (= nullptr).
- auto *LBound = N->getRawLowerBound();
- if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) {
- auto *LV = cast<ConstantInt>(LE->getValue());
- Printer.printInt("lowerBound", LV->getSExtValue(),
- /* ShouldSkipZero */ false);
- } else
- Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true);
-
- auto *UBound = N->getRawUpperBound();
- if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) {
- auto *UV = cast<ConstantInt>(UE->getValue());
- Printer.printInt("upperBound", UV->getSExtValue(),
- /* ShouldSkipZero */ false);
- } else
- Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true);
-
- auto *Stride = N->getRawStride();
- if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) {
- auto *SV = cast<ConstantInt>(SE->getValue());
- Printer.printInt("stride", SV->getSExtValue(), /* ShouldSkipZero */ false);
- } else
- Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true);
+ Printer.printMetadataOrInt("lowerBound", N->getRawLowerBound(),
+ /* IsUnsigned */ false,
+ /* ShouldSkipZero */ false);
+ Printer.printMetadataOrInt("upperBound", N->getRawUpperBound(),
+ /* IsUnsigned */ false,
+ /* ShouldSkipZero */ false);
+ Printer.printMetadataOrInt("stride", N->getRawStride(),
+ /* IsUnsigned */ false,
+ /* ShouldSkipZero */ false);
Out << ")";
}
@@ -2226,13 +2226,13 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
}
static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
- AsmWriterContext &) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIBasicType(";
- MDFieldPrinter Printer(Out);
+ MDFieldPrinter Printer(Out, WriterCtx);
if (N->getTag() != dwarf::DW_TAG_base_type)
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
Printer.printDwarfEnum("encoding", N->getEncoding(),
dwarf::AttributeEncodingString);
@@ -2242,13 +2242,13 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
}
static void writeDIFixedPointType(raw_ostream &Out, const DIFixedPointType *N,
- AsmWriterContext &) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIFixedPointType(";
- MDFieldPrinter Printer(Out);
+ MDFieldPrinter Printer(Out, WriterCtx);
if (N->getTag() != dwarf::DW_TAG_base_type)
Printer.printTag(N);
Printer.printString("name", N->getName());
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
Printer.printDwarfEnum("encoding", N->getEncoding(),
dwarf::AttributeEncodingString);
@@ -2275,7 +2275,7 @@ static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
Printer.printMetadata("stringLengthExpression", N->getRawStringLengthExp());
Printer.printMetadata("stringLocationExpression",
N->getRawStringLocationExp());
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
Printer.printDwarfEnum("encoding", N->getEncoding(),
dwarf::AttributeEncodingString);
@@ -2293,9 +2293,9 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
Printer.printInt("line", N->getLine());
Printer.printMetadata("baseType", N->getRawBaseType(),
/* ShouldSkipNull */ false);
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
- Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printMetadataOrInt("offset", N->getRawOffsetInBits(), true);
Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("extraData", N->getRawExtraData());
if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
@@ -2323,7 +2323,7 @@ static void writeDISubrangeType(raw_ostream &Out, const DISubrangeType *N,
Printer.printMetadata("scope", N->getRawScope());
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("baseType", N->getRawBaseType(),
@@ -2345,9 +2345,9 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Printer.printMetadata("baseType", N->getRawBaseType());
- Printer.printInt("size", N->getSizeInBits());
+ Printer.printMetadataOrInt("size", N->getRawSizeInBits(), true);
Printer.printInt("align", N->getAlignInBits());
- Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printMetadataOrInt("offset", N->getRawOffsetInBits(), true);
Printer.printInt("num_extra_inhabitants", N->getNumExtraInhabitants());
Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("elements", N->getRawElements());
diff --git a/llvm/test/DebugInfo/X86/dynamic-bitfield.ll b/llvm/test/DebugInfo/X86/dynamic-bitfield.ll
index eda4ff0f8f6d1..c9148ca4582f6 100644
--- a/llvm/test/DebugInfo/X86/dynamic-bitfield.ll
+++ b/llvm/test/DebugInfo/X86/dynamic-bitfield.ll
@@ -1,4 +1,6 @@
-; RUN: llc -mtriple=x86_64 -O0 -filetype=obj -o - %s | llvm-dwarfdump -v -debug-info - | FileCheck %s
+; The use of llvm-dis here tests that round-tripping the IR works
+; correctly for the expression case.
+; RUN: llvm-as < %s | llvm-dis | llc -mtriple=x86_64 -O0 -filetype=obj -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s
; A basic test of using a DIExpression for DW_AT_data_bit_offset and
; DW_AT_bit_size.
More information about the llvm-commits
mailing list