Author: Tom Tromey Date: 2025-02-07T18:28:44-08:00 New Revision: e5ea8f0a4855acd532db6beab8944a6226287a5f
URL: https://github.com/llvm/llvm-project/commit/e5ea8f0a4855acd532db6beab8944a6226287a5f DIFF: https://github.com/llvm/llvm-project/commit/e5ea8f0a4855acd532db6beab8944a6226287a5f.diff LOG: Allow 128-bit discriminants in DWARF variants (#125578) 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 largely accomplished by moving part of DwarfUnit::addConstantValue to a new method. Fixes #119655 (cherry picked from commit 3c2807624d2006fa8aacf9c6441c9a3034a52b44) Added: Modified: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h llvm/test/DebugInfo/Generic/discriminated-union.ll Removed: ################################################################################ diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index d3450b8b0556fde..5a17aa3bc9dc52e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -232,6 +232,42 @@ void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form, addUInt(Block, (dwarf::Attribute)0, Form, Integer); } +void DwarfUnit::addIntAsBlock(DIE &Die, dwarf::Attribute Attribute, const APInt &Val) { + DIEBlock *Block = new (DIEValueAllocator) DIEBlock; + + // Get the raw data form of the large APInt. + const uint64_t *Ptr64 = Val.getRawData(); + + int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. + bool LittleEndian = Asm->getDataLayout().isLittleEndian(); + + // Output the constant to DWARF one byte at a time. + for (int i = 0; i < NumBytes; i++) { + uint8_t c; + if (LittleEndian) + c = Ptr64[i / 8] >> (8 * (i & 7)); + else + c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); + addUInt(*Block, dwarf::DW_FORM_data1, c); + } + + addBlock(Die, Attribute, Block); +} + +void DwarfUnit::addInt(DIE &Die, dwarf::Attribute Attribute, + const APInt &Val, bool Unsigned) { + unsigned CIBitWidth = Val.getBitWidth(); + if (CIBitWidth <= 64) { + if (Unsigned) + addUInt(Die, Attribute, std::nullopt, Val.getZExtValue()); + else + addSInt(Die, Attribute, std::nullopt, Val.getSExtValue()); + return; + } + + addIntAsBlock(Die, Attribute, Val); +} + void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional<dwarf::Form> Form, int64_t Integer) { if (!Form) @@ -484,25 +520,7 @@ void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) { return; } - DIEBlock *Block = new (DIEValueAllocator) DIEBlock; - - // Get the raw data form of the large APInt. - const uint64_t *Ptr64 = Val.getRawData(); - - int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. - bool LittleEndian = Asm->getDataLayout().isLittleEndian(); - - // Output the constant to DWARF one byte at a time. - for (int i = 0; i < NumBytes; i++) { - uint8_t c; - if (LittleEndian) - c = Ptr64[i / 8] >> (8 * (i & 7)); - else - c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); - addUInt(*Block, dwarf::DW_FORM_data1, c); - } - - addBlock(Die, dwarf::DW_AT_const_value, Block); + addIntAsBlock(Die, dwarf::DW_AT_const_value, Val); } void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) { @@ -980,12 +998,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer); if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) { - if (DD->isUnsignedDIType(Discriminator->getBaseType())) - addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt, - CI->getZExtValue()); - else - addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt, - CI->getSExtValue()); + addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(), + DD->isUnsignedDIType(Discriminator->getBaseType())); } constructMemberDIE(Variant, DDTy); } else { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 7a5295d826a483b..842a8d6ad53b107 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -167,6 +167,10 @@ class DwarfUnit : public DIEUnit { void addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, int64_t Integer); + /// Add an integer attribute data and value; value may be any width. + void addInt(DIE &Die, dwarf::Attribute Attribute, const APInt &Integer, + bool Unsigned); + /// Add a string attribute data and value. /// /// We always emit a reference to the string pool instead of immediate @@ -336,6 +340,10 @@ class DwarfUnit : public DIEUnit { void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT); private: + /// A helper to add a wide integer constant to a DIE using a block + /// form. + void addIntAsBlock(DIE &Die, dwarf::Attribute Attribute, const APInt &Val); + void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy); void constructTypeDIE(DIE &Buffer, const DIStringType *BTy); void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy); diff --git a/llvm/test/DebugInfo/Generic/discriminated-union.ll b/llvm/test/DebugInfo/Generic/discriminated-union.ll index d267d9b029e950c..592f2152ae68201 100644 --- a/llvm/test/DebugInfo/Generic/discriminated-union.ll +++ b/llvm/test/DebugInfo/Generic/discriminated-union.ll @@ -22,7 +22,7 @@ ; CHECK: DW_AT_alignment ; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00) ; CHECK: DW_TAG_variant -; CHECK: DW_AT_discr_value [DW_FORM_data1] (0x00) +; 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 ) ; CHECK: DW_TAG_member ; CHECK: DW_AT_type ; CHECK: DW_AT_alignment @@ -71,7 +71,7 @@ attributes #0 = { nounwind uwtable } !21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned) !22 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !7, baseType: !23, size: 64, align: 64) !23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64) -!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i64 0) +!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i128 18446744073709551616) !25 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nope", scope: !12, file: !7, size: 128, align: 64, elements: !4, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Nope") !27 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned) !28 = !DIExpression() _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits