1; RUN: opt %s -instcombine -S | FileCheck %s 2 3; Test sinking of dbg.values when instcombine sinks associated instructions. 4 5declare void @llvm.dbg.value(metadata, metadata, metadata) 6 7; This GEP is sunk, but can be folded into a DIExpression. Check that it 8; gets folded. The dbg.value should be duplicated in the block its sunk 9; into, to maximise liveness. 10; 11; CHECK-LABEL: define i32 @foo(i32* 12; CHECK: call void @llvm.dbg.value(metadata i32* %a, metadata !{{[0-9]+}}, 13; CHECK-SAME: metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value)) 14; CHECK-NEXT: br label %sink1 15 16define i32 @foo(i32 *%a) !dbg !7 { 17entry: 18 %gep = getelementptr i32, i32 *%a, i32 1 19 call void @llvm.dbg.value(metadata i32 *%gep, metadata !16, metadata !12), !dbg !15 20 br label %sink1 21 22sink1: 23; CHECK-LABEL: sink1: 24; CHECK: call void @llvm.dbg.value(metadata i32* %gep, 25; CHECK-SAME: metadata !{{[0-9]+}}, metadata !DIExpression()) 26; CHECK-NEXT: load 27 %0 = load i32, i32* %gep, align 4, !dbg !15 28 ret i32 %0, !dbg !15 29} 30 31; In this example the GEP cannot (yet) be salvaged. Check that not only is the 32; dbg.value sunk, but an undef dbg.value is left to terminate any earlier 33; value range. 34 35; CHECK-LABEL: define i32 @bar( 36; CHECK: call void @llvm.dbg.value(metadata <vscale x 4 x i32>* undef, 37; CHECK-NEXT: br label %sink2 38 39define i32 @bar(<vscale x 4 x i32>* %a, i32 %b) !dbg !70 { 40entry: 41 %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i32 %b 42 call void @llvm.dbg.value(metadata <vscale x 4 x i32>* %gep, metadata !73, metadata !12), !dbg !74 43 br label %sink2 44 45sink2: 46; CHECK-LABEL: sink2: 47; CHECK: call void @llvm.dbg.value(metadata <vscale x 4 x i32>* %gep, 48; CHECK-SAME: metadata !{{[0-9]+}}, metadata !DIExpression()) 49; CHECK-NEXT: load 50; CHECK-NEXT: extractelement 51; CHECK-NEXT: ret 52 %0 = load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep 53 %extract = extractelement <vscale x 4 x i32> %0, i32 1 54 ret i32 %extract 55} 56 57; This GEP is sunk, and has multiple debug uses in the same block. Check that 58; only the last use is cloned into the sunk block, and that both of the 59; original dbg.values are salvaged. 60; 61; CHECK-LABEL: define i32 @baz(i32* 62; CHECK: call void @llvm.dbg.value(metadata i32* %a, metadata !{{[0-9]+}}, 63; CHECK-SAME: metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value)) 64; CHECK-NEXT: call void @llvm.dbg.value(metadata i32* %a, metadata !{{[0-9]+}}, 65; CHECK-SAME: metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_plus_uconst, 5, DW_OP_stack_value)) 66; CHECK-NEXT: br label %sink1 67 68define i32 @baz(i32 *%a) !dbg !80 { 69entry: 70 %gep = getelementptr i32, i32 *%a, i32 1 71 call void @llvm.dbg.value(metadata i32 *%gep, metadata !83, metadata !12), !dbg !84 72 call void @llvm.dbg.value(metadata i32 *%gep, metadata !83, metadata !DIExpression(DW_OP_plus_uconst, 5)), !dbg !85 73 br label %sink1 74 75sink1: 76; CHECK-LABEL: sink1: 77; CHECK: call void @llvm.dbg.value(metadata i32* %gep, 78; CHECK-SAME: metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_plus_uconst, 5)) 79; CHECK-NEXT: load 80 %0 = load i32, i32* %gep, align 4, !dbg !85 81 ret i32 %0, !dbg !85 82} 83 84!llvm.dbg.cu = !{!0} 85!llvm.module.flags = !{!3, !4, !5} 86!llvm.ident = !{!6} 87 88!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) 89!1 = !DIFile(filename: "a.c", directory: ".") 90!2 = !{} 91!3 = !{i32 2, !"Dwarf Version", i32 4} 92!4 = !{i32 2, !"Debug Info Version", i32 3} 93!5 = !{i32 1, !"PIC Level", i32 2} 94!6 = !{!"clang"} 95!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) 96!8 = !DISubroutineType(types: !9) 97!9 = !{!10, !10} 98!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 99!11 = !DILocalVariable(name: "j", scope: !7, file: !1, line: 2, type: !10) 100!12 = !DIExpression() 101!15 = !DILocation(line: 5, column: 3, scope: !7) 102!16 = !DILocalVariable(name: "h", scope: !7, file: !1, line: 4, type: !10) 103!70 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !71, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) 104!71 = !DISubroutineType(types: !72) 105!72 = !{!10, !10, !10} 106!73 = !DILocalVariable(name: "k", scope: !70, file: !1, line: 2, type: !10) 107!74 = !DILocation(line: 5, column: 3, scope: !70) 108!80 = distinct !DISubprogram(name: "baz", scope: !1, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) 109!83 = !DILocalVariable(name: "l", scope: !80, file: !1, line: 2, type: !10) 110!84 = !DILocation(line: 5, column: 3, scope: !80) 111!85 = !DILocation(line: 6, column: 3, scope: !80) 112