Open 009b8ea0-6754-41bc-becf-d830f82bdd65 opened 6 years ago
Is there any good place to handle arbitration between DWARF producers and consumers? The Dwarf-Discuss mailing list?
Dwarf-discuss is the best place to discuss this since that mailing list is read by both clang, gcc, gdb, and lldb developers.
I'm sorry for the late reply! I guess that I don't really have any other argument for this than "this is how GCC and GDB does things", which of course should not necessarily inform what Clang does.
Still, I think that it would be a shame if GDB's and Clang's behavior remain unaligned in the long run. Is there any good place to handle arbitration between DWARF producers and consumers? The Dwarf-Discuss mailing list?
Additionally, as our target is big-endian, the smaller fragments cover the wrong parts of the values.
That sounds like a separate problem. I expect DWARF for big-endian targets is not as well tested as we might like. I'd suggest a separate bug for that.
Okay, I'll write a separate bug for that. I guess that there are no upstream big-endian target with an aligned type like fp80, so I'm not sure if I can create a reproducer.
The main problem we are having with this representation is when using GDB. GDB requires that all DW_AT_byte_size bytes of a value are fully covered by non-empty composite location descriptions for the value to not be considered optimized out. In this case, the two members would therefore be seen as optimized out.
So, we have data values that don't occupy all of their associated storage. How to describe this situation changed from DWARF 3 to DWARF 4, but in both cases there should be a DW_AT_byte_size giving the size of the storage, and a DW_AT_bit_size giving the size of the value. (How to find the value within the storage is the part that changed.)
Assuming we emit DW_AT_bit_size and either DW_AT_bit_offset [v3] or DW_AT_data_bit_offset [v4] then GDB should be content to find the 80-bit values within the 128-bit storage container. We should not have to describe the padding as some sort of phantom field.
Additionally, as our target is big-endian, the smaller fragments cover the wrong parts of the values.
That sounds like a separate problem. I expect DWARF for big-endian targets is not as well tested as we might like. I'd suggest a separate bug for that.
I'm not sure:
call void @llvm.dbg.value(metadata x86_fp80 %0, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)), !dbg !32 call void @llvm.dbg.value(metadata x86_fp80 %1, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 128, 80)), !dbg !32
If I read this correctly, the value %0/%1 described by the dbg.value intrinsics are only 80 bits long and I don't think it is a good idea to have an LLVM_fragment larger than the value it is attached to. Also it looks like the offset of the fragment expression (128) does take the padding into account. Can you elaborate why you think that this representation is a problem?
The main problem we are having with this representation is when using GDB. GDB requires that all DW_AT_byte_size bytes of a value are fully covered by non-empty composite location descriptions for the value to not be considered optimized out. In this case, the two members would therefore be seen as optimized out. As mentioned in https://reviews.llvm.org/D42807, GCC 5.5.0 emits 10-byte pieces for long double. Somewhere along the way to 7.2.0 that was changed, so the padding bytes are now included in the pieces.
I have not found anything in the DWARF representation that seems to explicitly mandate this, and I'm struggling to find a mail thread or similar that clarifies this.
As X86FloatingPoint ultimately drops the debug values, this is not an issue in practice for long double, at least for now, I guess. However, we are having the same issue with a fixed-point type for our off-trunk backend. Additionally, as our target is big-endian, the smaller fragments cover the wrong parts of the values.
I'm not sure:
call void @llvm.dbg.value(metadata x86_fp80 %0, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)), !dbg !32 call void @llvm.dbg.value(metadata x86_fp80 %1, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 128, 80)), !dbg !32
If I read this correctly, the value %0/%1 described by the dbg.value intrinsics are only 80 bits long and I don't think it is a good idea to have an LLVM_fragment larger than the value it is attached to. Also it looks like the offset of the fragment expression (128) does take the padding into account. Can you elaborate why you think that this representation is a problem?
Extended Description
When running SROA on the attached reproducer, the pass emits 80-bit wide fragments for the long double elements, that are aligned to 128 bits. As the alignment is included in the long double's DW_AT_byte_size size, the fragments should also include it.
Can be reproduced using:
$ opt -sroa -S -o - sroa.ll | grep fragment call void @llvm.dbg.value(metadata x86_fp80 %0, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 80)), !dbg !32 call void @llvm.dbg.value(metadata x86_fp80 %1, metadata !28, metadata !DIExpression(DW_OP_LLVM_fragment, 128, 80)), !dbg !32
A similar change was made to GlobalOpt in: https://reviews.llvm.org/D42807. However, in this case I'm not sure how SROA should distinguish the cases where you want the padding to be included in the fragment, and the cases where it should be omitted (e.g. llvm/llvm-project#34795 ).