The function transferSRADebugInfo is modified to include missing cases.
The existing handling produced crash for test case (attached with patch).
Please consider below IR
%struct.BSS3 = type <{ [24 x i8] }> @.BSS3 = internal unnamed_addr global %struct.BSS3 zeroinitializer, align 32, !dbg !0, !dbg !7, !dbg !29 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "bar1", scope: !2, file: !4, type: !12, isLocal: true, isDefinition: true) !12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 96, align: 32, elements: !14)
In SROA @.BSS3 is broken into @.BSS3.0, @.BSS3.1, @.BSS3.2
@.BSS3.0 = internal unnamed_addr global double 0.000000e+00, align 32, !dbg !0, !dbg !24 @.BSS3.1 = internal unnamed_addr global double 0.000000e+00, align 32, !dbg !26, !dbg !27 @.BSS3.2 = internal unnamed_addr global double 0.000000e+00, align 16, !dbg !28
Since original memory chunk is broken into three (each of size 64bits), the variable "bar1" (of size 96=64+32) spreads across @.BSS3.0 (completely) and @.BSS3.1 (partially). So below DebugInfo should be generated.
@.BSS3.0 = internal unnamed_addr global double 0.000000e+00, align 32, !dbg !0, !dbg !24 @.BSS3.1 = internal unnamed_addr global double 0.000000e+00, align 32, !dbg !25, !dbg !26, !dbg !27 @.BSS3.2 = internal unnamed_addr global double 0.000000e+00, align 16, !dbg !28 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 0, 64)) !1 = distinct !DIGlobalVariable(name: "bar1", scope: !2, file: !4, type: !13, isLocal: true, isDefinition: true) !25 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 64, 32))
But currently it was wrongly generating DW_OP_LLVM_fragment DIExpression with incorrect second argument (64 in place of 32).
fragment is larger than or outside of variable !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 0, 64)) !26 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_LLVM_fragment, 64, 64))
Later the verification fails as variable size is less than fragment. Which leads a crash.
Breakpoint 2, (anonymous namespace)::Verifier::verifyFragmentExpression<llvm::DIGlobalVariableExpression const> (this=0x7fffffffb790, V=..., Fragment=..., Desc=0x555555712450) at /tmp/llvm-project/llvm/lib/IR/Verifier.cpp:6135 6135 CheckDI(FragSize + FragOffset <= *VarSize, 6136 "fragment is larger than or outside of variable", Desc, &V);
Now the function transferSRADebugInfo is modified to handle such cases.
Why initialize to zero and then again here?