Skip to content

Commit a1e5919

Browse files
committed
Allow 128-bit discriminants in DWARF variants
If a variant part has a 128-bit discriminator, then DwarfUnit::constructTypeDIE will assert. This patch fixes the problem by allowing any size of integer to be used here. This is mostly implemented by copying DwarfUnit::addConstantValue. However, I did not reimplement that method in terms of the new addInt because that would introduce the need for unrelated test case changes. Fixes #119655
1 parent 59a9a8f commit a1e5919

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,38 @@ void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form,
232232
addUInt(Block, (dwarf::Attribute)0, Form, Integer);
233233
}
234234

235+
void DwarfUnit::addInt(DIE &Die, dwarf::Attribute Attribute,
236+
const APInt &Val, bool Unsigned) {
237+
unsigned CIBitWidth = Val.getBitWidth();
238+
if (CIBitWidth <= 64) {
239+
if (Unsigned)
240+
addUInt(Die, Attribute, std::nullopt, Val.getZExtValue());
241+
else
242+
addSInt(Die, Attribute, std::nullopt, Val.getSExtValue());
243+
return;
244+
}
245+
246+
DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
247+
248+
// Get the raw data form of the large APInt.
249+
const uint64_t *Ptr64 = Val.getRawData();
250+
251+
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
252+
bool LittleEndian = Asm->getDataLayout().isLittleEndian();
253+
254+
// Output the constant to DWARF one byte at a time.
255+
for (int i = 0; i < NumBytes; i++) {
256+
uint8_t c;
257+
if (LittleEndian)
258+
c = Ptr64[i / 8] >> (8 * (i & 7));
259+
else
260+
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
261+
addUInt(*Block, dwarf::DW_FORM_data1, c);
262+
}
263+
264+
addBlock(Die, Attribute, Block);
265+
}
266+
235267
void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
236268
std::optional<dwarf::Form> Form, int64_t Integer) {
237269
if (!Form)
@@ -972,12 +1004,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
9721004
DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
9731005
if (const ConstantInt *CI =
9741006
dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
975-
if (DD->isUnsignedDIType(Discriminator->getBaseType()))
976-
addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,
977-
CI->getZExtValue());
978-
else
979-
addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,
980-
CI->getSExtValue());
1007+
addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(),
1008+
DD->isUnsignedDIType(Discriminator->getBaseType()));
9811009
}
9821010
constructMemberDIE(Variant, DDTy);
9831011
} else {

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ class DwarfUnit : public DIEUnit {
167167

168168
void addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, int64_t Integer);
169169

170+
/// Add an integer attribute data and value; value may be any width.
171+
void addInt(DIE &Die, dwarf::Attribute Attribute, const APInt &Integer,
172+
bool Unsigned);
173+
170174
/// Add a string attribute data and value.
171175
///
172176
/// We always emit a reference to the string pool instead of immediate

llvm/test/DebugInfo/Generic/discriminated-union.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
; CHECK: DW_AT_alignment
2323
; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
2424
; CHECK: DW_TAG_variant
25-
; CHECK: DW_AT_discr_value [DW_FORM_data1] (0x00)
25+
; CHECK: DW_AT_discr_value [DW_FORM_block1] (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )
2626
; CHECK: DW_TAG_member
2727
; CHECK: DW_AT_type
2828
; CHECK: DW_AT_alignment
@@ -71,7 +71,7 @@ attributes #0 = { nounwind uwtable }
7171
!21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
7272
!22 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !7, baseType: !23, size: 64, align: 64)
7373
!23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64)
74-
!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i64 0)
74+
!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i128 18446744073709551616)
7575
!25 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nope", scope: !12, file: !7, size: 128, align: 64, elements: !4, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Nope")
7676
!27 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
7777
!28 = !DIExpression()

0 commit comments

Comments
 (0)