TryToSinkInstruction() has a bug: While updating debug info for sunk instruction, it could clone dbg.declare intrinsic. That is wrong. There could be only one dbg.declare. The fix is to not clone dbg.declare intrinsic and to update it`s arguments, to not to point to sunk instruction.
before instcombine :
entry:
%result = alloca i64, align 8 %tmpcast = bitcast i64* %result to %struct.S1* %0 = bitcast i64* %result to i8*, !dbg !24 call void @llvm.dbg.declare(metadata %struct.S1* %tmpcast, metadata !12, metadata !DIExpression()), !dbg !24 %p1 = bitcast i64* %result to i32*, !dbg !35 store i32 2, i32* %p1, align 8, !dbg !35
after instcombine:
%result = alloca i64, align 8 %0 = bitcast i64* %result to i8*, !dbg !24 call void @llvm.dbg.declare(metadata i64* %result, metadata !12, metadata !DIExpression()), !dbg !24 %tmpcast = bitcast i64* %result to %struct.S1* call void @llvm.dbg.declare(metadata %struct.S1* %tmpcast, metadata !12, metadata !DIExpression()), !dbg !24 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cloned llvm.dbg.declare
"should" rather than "could"? Also, IMO "be left at original" should be "be left in the original"