1; RUN: opt %s -S -passes=instcombine -o - \ 2; RUN: | FileCheck %s 3; RUN: opt --try-experimental-debuginfo-iterators %s -S -passes=instcombine -o - \ 4; RUN: | FileCheck %s 5 6;; Check that when instcombine sinks an instruction used by a dbg.assign, the 7;; usual debug intrinsic updating doesn't take place (i.e. do not 8;; clone-and-sink a dbg.assign). Assignment tracking should be able to handle 9;; this gracefully for variables that still have a stack home. For fully 10;; promoted variables we may need to revisit this. 11 12;; $ cat test.c 13;; struct a { 14;; char *b; 15;; } c() __attribute__((noreturn)); 16;; int d; 17;; int e(); 18;; int f() { 19;; if (e()) 20;; return d; 21;; c(); 22;; } 23;; void g(); 24;; void h() { 25;; struct a i; 26;; i.b = 0; 27;; f(); 28;; i.b = 0; 29;; g(&i); 30;; } 31;; $ clang -O2 -g -Xclang -fexperimental-assignment-tracking 32 33; CHECK: f.exit: 34; CHECK-NEXT: store ptr null, ptr %i, align 8,{{.+}}, !DIAssignID ![[ID:[0-9]+]] 35; CHECK-NEXT: #dbg_assign({{.+}}, {{.+}}, {{.+}}, ![[ID]], ptr %i, {{.+}}, 36 37%struct.a = type { ptr } 38 39@d = dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 40 41; Function Attrs: nounwind uwtable 42define dso_local i32 @f() local_unnamed_addr #0 !dbg !11 { 43entry: 44 %call = tail call i32 (...) @e() #5, !dbg !14 45 %tobool.not = icmp eq i32 %call, 0, !dbg !14 46 br i1 %tobool.not, label %if.end, label %if.then, !dbg !16 47 48if.then: ; preds = %entry 49 %0 = load i32, ptr @d, align 4, !dbg !17 50 ret i32 %0, !dbg !22 51 52if.end: ; preds = %entry 53 %call1 = tail call ptr (...) @c() #6, !dbg !23 54 unreachable, !dbg !23 55} 56 57declare !dbg !24 dso_local i32 @e(...) local_unnamed_addr #1 58 59; Function Attrs: noreturn 60declare !dbg !27 dso_local ptr @c(...) local_unnamed_addr #2 61 62; Function Attrs: nounwind uwtable 63define dso_local void @h() local_unnamed_addr #0 !dbg !35 { 64entry: 65 %i = alloca %struct.a, align 8, !DIAssignID !40 66 call void @llvm.dbg.assign(metadata i1 undef, metadata !39, metadata !DIExpression(), metadata !40, metadata ptr %i, metadata !DIExpression()), !dbg !41 67 %0 = bitcast ptr %i to ptr, !dbg !42 68 call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %0) #5, !dbg !42 69 %b = getelementptr inbounds %struct.a, ptr %i, i64 0, i32 0, !dbg !43 70 call void @llvm.dbg.assign(metadata ptr null, metadata !39, metadata !DIExpression(), metadata !44, metadata ptr %b, metadata !DIExpression()), !dbg !41 71 %call.i = tail call i32 (...) @e() #5, !dbg !45 72 %tobool.not.i = icmp eq i32 %call.i, 0, !dbg !45 73 br i1 %tobool.not.i, label %if.end.i, label %f.exit, !dbg !47 74 75if.end.i: ; preds = %entry 76 %call1.i = tail call ptr (...) @c() #6, !dbg !48 77 unreachable, !dbg !48 78 79f.exit: ; preds = %entry 80 store ptr null, ptr %b, align 8, !dbg !49, !DIAssignID !53 81 call void @llvm.dbg.assign(metadata ptr null, metadata !39, metadata !DIExpression(), metadata !53, metadata ptr %b, metadata !DIExpression()), !dbg !41 82 call void @g(ptr nonnull %i) #5, !dbg !54 83 call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %0) #5, !dbg !55 84 ret void, !dbg !55 85} 86 87declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3 88declare dso_local void @g(...) local_unnamed_addr #1 89declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3 90declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) #4 91 92!llvm.dbg.cu = !{!2} 93!llvm.module.flags = !{!7, !8, !9, !1000} 94!llvm.ident = !{!10} 95 96!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 97!1 = distinct !DIGlobalVariable(name: "d", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) 98!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) 99!3 = !DIFile(filename: "test.c", directory: "/") 100!4 = !{} 101!5 = !{!0} 102!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 103!7 = !{i32 7, !"Dwarf Version", i32 4} 104!8 = !{i32 2, !"Debug Info Version", i32 3} 105!9 = !{i32 1, !"wchar_size", i32 4} 106!10 = !{!"clang version 12.0.0"} 107!11 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 6, type: !12, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) 108!12 = !DISubroutineType(types: !13) 109!13 = !{!6} 110!14 = !DILocation(line: 7, column: 7, scope: !15) 111!15 = distinct !DILexicalBlock(scope: !11, file: !3, line: 7, column: 7) 112!16 = !DILocation(line: 7, column: 7, scope: !11) 113!17 = !DILocation(line: 8, column: 12, scope: !15) 114!22 = !DILocation(line: 8, column: 5, scope: !15) 115!23 = !DILocation(line: 9, column: 3, scope: !11) 116!24 = !DISubprogram(name: "e", scope: !3, file: !3, line: 5, type: !25, spFlags: DISPFlagOptimized, retainedNodes: !4) 117!25 = !DISubroutineType(types: !26) 118!26 = !{!6, null} 119!27 = !DISubprogram(name: "c", scope: !3, file: !3, line: 3, type: !28, flags: DIFlagNoReturn, spFlags: DISPFlagOptimized, retainedNodes: !4) 120!28 = !DISubroutineType(types: !29) 121!29 = !{!30, null} 122!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "a", file: !3, line: 1, size: 64, elements: !31) 123!31 = !{!32} 124!32 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !30, file: !3, line: 2, baseType: !33, size: 64) 125!33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !34, size: 64) 126!34 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) 127!35 = distinct !DISubprogram(name: "h", scope: !3, file: !3, line: 12, type: !36, scopeLine: 12, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !38) 128!36 = !DISubroutineType(types: !37) 129!37 = !{null} 130!38 = !{!39} 131!39 = !DILocalVariable(name: "i", scope: !35, file: !3, line: 13, type: !30) 132!40 = distinct !DIAssignID() 133!41 = !DILocation(line: 0, scope: !35) 134!42 = !DILocation(line: 13, column: 3, scope: !35) 135!43 = !DILocation(line: 14, column: 5, scope: !35) 136!44 = distinct !DIAssignID() 137!45 = !DILocation(line: 7, column: 7, scope: !15, inlinedAt: !46) 138!46 = distinct !DILocation(line: 15, column: 3, scope: !35) 139!47 = !DILocation(line: 7, column: 7, scope: !11, inlinedAt: !46) 140!48 = !DILocation(line: 9, column: 3, scope: !11, inlinedAt: !46) 141!49 = !DILocation(line: 16, column: 7, scope: !35) 142!53 = distinct !DIAssignID() 143!54 = !DILocation(line: 17, column: 3, scope: !35) 144!55 = !DILocation(line: 18, column: 1, scope: !35) 145!1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true} 146