SROA pass processes debug info incorrecly if applied twice.
Specifically, after SROA works first time, instcombine converts dbg.declare
intrinsics into dbg.value. Inlining creates new opportunities for SROA,
so it is called again. This time it does not handle correctly previously
inserted dbg.value intrinsics.
That is IR coming to SROA pass before applied second time :
%result = alloca %struct.S1, align 4 %0 = bitcast %struct.S1* %result to i8*, !dbg !21 call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3, !dbg !21 %call = call i32 @_Z3foov(), !dbg !22 %coerce.dive = getelementptr inbounds %struct.S1, %struct.S1* %result, i64 0, i32 0, !dbg !22 store i32 %call, i32* %coerce.dive, align 4, !dbg !22 call void @llvm.dbg.value(metadata %struct.S1* %result, metadata !12, metadata !DIExpression(DW_OP_deref)), !dbg !23 call void @llvm.dbg.value(metadata %struct.S1* %result, metadata !24, metadata !DIExpression()), !dbg !28 %cmp.i = icmp eq i32 %call, 0, !dbg !31 br i1 %cmp.i, label %if.then, label %if.end, !dbg !32
note it has llvm.dbg.value.
That is the output of SROA pass after applied second time:
%call = call i32 @_Z3foov(), !dbg !21 call void @llvm.dbg.value(metadata %struct.S1* undef, metadata !12, metadata !DIExpression(DW_OP_deref)), !dbg !22 call void @llvm.dbg.value(metadata %struct.S1* undef, metadata !23, metadata !DIExpression()), !dbg !27 %cmp.i = icmp eq i32 %call, 0, !dbg !30 br i1 %cmp.i, label %if.then, label %if.end, !dbg !31
That is the correct output:
%call = call i32 @_Z3foov(), !dbg !21 call void @llvm.dbg.value(metadata i32 %call, metadata !12, metadata !DIExpression()), !dbg !22 %cmp.i = icmp eq i32 %call, 0, !dbg !23 br i1 %cmp.i, label %if.then, label %if.end, !dbg !30
The fix is to remove llvm.dbg.value and insert dbg.declare for new fragments.