diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 56c288ee95b43..6533e8281631a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -30,6 +30,7 @@ #include "llvm/Target/TargetLoweringObjectFile.h" #include #include +#include #include #include @@ -1649,7 +1650,8 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { addUInt(MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8); addUInt(MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size); - uint64_t Offset = DT->getOffsetInBits(); + assert(DT->getOffsetInBits() <= std::numeric_limits::max()); + int64_t Offset = DT->getOffsetInBits(); // We can't use DT->getAlignInBits() here: AlignInBits for member type // is non-zero if and only if alignment was forced (e.g. _Alignas()), // which can't be done with bitfields. Thus we use FieldSize here. @@ -1669,7 +1671,12 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { if (Asm->getDataLayout().isLittleEndian()) Offset = FieldSize - (Offset + Size); - addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt, Offset); + if (Offset < 0) + addSInt(MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata, + Offset); + else + addUInt(MemberDie, dwarf::DW_AT_bit_offset, std::nullopt, + (uint64_t)Offset); OffsetInBytes = FieldOffset >> 3; } else { addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset); diff --git a/llvm/test/DebugInfo/ARM/bitfield.ll b/llvm/test/DebugInfo/ARM/bitfield.ll index 5bd06b785b159..672c61db6f491 100644 --- a/llvm/test/DebugInfo/ARM/bitfield.ll +++ b/llvm/test/DebugInfo/ARM/bitfield.ll @@ -12,7 +12,7 @@ ; CHECK: DW_AT_name {{.*}} "reserved" ; CHECK: DW_AT_byte_size {{.*}} (0x04) ; CHECK: DW_AT_bit_size {{.*}} (0x1c) -; CHECK: DW_AT_bit_offset {{.*}} (0xfffffffffffffff8) +; CHECK: DW_AT_bit_offset {{.*}} (-8) ; CHECK: DW_AT_data_member_location {{.*}} (DW_OP_plus_uconst 0x0) %struct.anon = type { i8, [5 x i8] } diff --git a/llvm/test/DebugInfo/NVPTX/packed_bitfields.ll b/llvm/test/DebugInfo/NVPTX/packed_bitfields.ll index e2097d7f49b48..62ffa0a4001f1 100644 --- a/llvm/test/DebugInfo/NVPTX/packed_bitfields.ll +++ b/llvm/test/DebugInfo/NVPTX/packed_bitfields.ll @@ -16,7 +16,7 @@ ; CHECK-NEXT: .b8 1 // DW_AT_byte_size ; CHECK-NEXT: .b8 6 // DW_AT_bit_size ; Negative offset must be encoded as an unsigned integer. -; CHECK-NEXT: .b64 0xffffffffffffffff // DW_AT_bit_offset +; CHECK-NEXT: .b8 127 // DW_AT_bit_offset ; CHECK-NEXT: .b8 2 // DW_AT_data_member_location %struct.anon = type { i16 } diff --git a/llvm/test/DebugInfo/X86/packed_bitfields.ll b/llvm/test/DebugInfo/X86/packed_bitfields.ll index 0e541f09d2270..614fa59c36784 100644 --- a/llvm/test/DebugInfo/X86/packed_bitfields.ll +++ b/llvm/test/DebugInfo/X86/packed_bitfields.ll @@ -15,7 +15,7 @@ ; CHECK-NOT: DW_TAG_member ; CHECK: DW_AT_byte_size {{.*}} (0x01) ; CHECK-NEXT: DW_AT_bit_size {{.*}} (0x06) -; CHECK-NEXT: DW_AT_bit_offset {{.*}} (0xffffffffffffffff) +; CHECK-NEXT: DW_AT_bit_offset {{.*}} (-1) ; CHECK-NEXT: DW_AT_data_member_location {{.*}} ({{.*}}0x0{{0*}}) ; ModuleID = 'repro.c'