1 # RUN: llc -run-pass=livedebugvalues -march=x86-64 -o /dev/null %s | FileCheck %s 2 3 # Test the extension of debug ranges from predecessors. 4 # Generated from the source file LiveDebugValues.c: 5 # #include <stdio.h> 6 # int m; 7 # extern int inc(int n); 8 # extern int change(int n); 9 # extern int modify(int n); 10 # int main(int argc, char **argv) { 11 # int n; 12 # if (argc != 2) 13 # n = 2; 14 # else 15 # n = atoi(argv[1]); 16 # n = change(n); 17 # if (n > 10) { 18 # m = modify(n); 19 # m = m + n; // var `m' doesn't has a dbg.value 20 # } 21 # else 22 # m = inc(n); // var `m' doesn't has a dbg.value 23 # printf("m(main): %d\n", m); 24 # return 0; 25 # } 26 # with clang -g -O3 -c -emit-llvm LiveDebugValues.c -S -o live-debug-values.ll 27 # then llc -stop-after stackmap-liveness live-debug-values.ll -o /dev/null > live-debug-values.mir 28 # This case will also produce multiple locations but only the debug range 29 # extension is tested here. This test case is tested with DWARF information under 30 # llvm/test/DebugInfo/live-debug-values.ll and present here for testing under 31 # MIR->MIR serialization. 32 33 # DBG_VALUE for variable "n" is extended into BB#5 from its predecessors BB#3 34 # and BB#4. 35 # CHECK: bb.5.if.end.7: 36 # CHECK: DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22 37 # CHECK-NEXT: DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33 38 39 40 --- | 41 ; ModuleID = 'live-debug-values.ll' 42 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 43 target triple = "x86_64-unknown-linux-gnu" 44 45 @m = common global i32 0, align 4 46 @.str = private unnamed_addr constant [13 x i8] c"m(main): %d\0A\00", align 1 47 48 ; Function Attrs: nounwind uwtable 49 define i32 @main(i32 %argc, i8** nocapture readonly %argv) #0 !dbg !4 { 50 entry: 51 tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !12, metadata !20), !dbg !21 52 tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !13, metadata !20), !dbg !22 53 %cmp = icmp eq i32 %argc, 2, !dbg !24 54 br i1 %cmp, label %if.else, label %if.end, !dbg !26 55 56 if.else: ; preds = %entry 57 %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1, !dbg !27 58 %0 = load i8*, i8** %arrayidx, align 8, !dbg !27, !tbaa !28 59 %call = tail call i32 (i8*, ...) bitcast (i32 (...)* @atoi to i32 (i8*, ...)*)(i8* %0) #4, !dbg !32 60 tail call void @llvm.dbg.value(metadata i32 %call, i64 0, metadata !14, metadata !20), !dbg !33 61 br label %if.end 62 63 if.end: ; preds = %if.else, %entry 64 %n.0 = phi i32 [ %call, %if.else ], [ 2, %entry ] 65 %call1 = tail call i32 @change(i32 %n.0) #4, !dbg !34 66 tail call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !14, metadata !20), !dbg !33 67 %cmp2 = icmp sgt i32 %call1, 10, !dbg !35 68 br i1 %cmp2, label %if.then.3, label %if.else.5, !dbg !37 69 70 if.then.3: ; preds = %if.end 71 %call4 = tail call i32 @modify(i32 %call1) #4, !dbg !38 72 %add = add nsw i32 %call4, %call1, !dbg !40 73 br label %if.end.7, !dbg !41 74 75 if.else.5: ; preds = %if.end 76 %call6 = tail call i32 @inc(i32 %call1) #4, !dbg !42 77 br label %if.end.7 78 79 if.end.7: ; preds = %if.else.5, %if.then.3 80 %storemerge = phi i32 [ %call6, %if.else.5 ], [ %add, %if.then.3 ] 81 store i32 %storemerge, i32* @m, align 4, !dbg !43, !tbaa !44 82 %call8 = tail call i32 (i8*, ...) @printf(i8* nonnull getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i32 %storemerge) #4, !dbg !46 83 ret i32 0, !dbg !47 84 } 85 86 declare i32 @atoi(...) #1 87 88 declare i32 @change(i32) #1 89 90 declare i32 @modify(i32) #1 91 92 declare i32 @inc(i32) #1 93 94 ; Function Attrs: nounwind 95 declare i32 @printf(i8* nocapture readonly, ...) #2 96 97 ; Function Attrs: nounwind readnone 98 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #3 99 100 attributes #0 = { nounwind uwtable } 101 attributes #1 = { nounwind } 102 attributes #2 = { nounwind } 103 attributes #3 = { nounwind readnone } 104 attributes #4 = { nounwind } 105 106 !llvm.dbg.cu = !{!0} 107 !llvm.module.flags = !{!17, !18} 108 !llvm.ident = !{!19} 109 110 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 253049) ", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !15) 111 !1 = !DIFile(filename: "LiveDebugValues.c", directory: "/home/vt/julia/test/tvvikram") 112 !2 = !{} 113 !3 = !{!4} 114 !4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !5, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: true, variables: !11) 115 !5 = !DISubroutineType(types: !6) 116 !6 = !{!7, !7, !8} 117 !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) 118 !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64, align: 64) 119 !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64) 120 !10 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) 121 !11 = !{!12, !13, !14} 122 !12 = !DILocalVariable(name: "argc", arg: 1, scope: !4, file: !1, line: 6, type: !7) 123 !13 = !DILocalVariable(name: "argv", arg: 2, scope: !4, file: !1, line: 6, type: !8) 124 !14 = !DILocalVariable(name: "n", scope: !4, file: !1, line: 7, type: !7) 125 !15 = !{!16} 126 !16 = !DIGlobalVariable(name: "m", scope: !0, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true, variable: i32* @m) 127 !17 = !{i32 2, !"Dwarf Version", i32 4} 128 !18 = !{i32 2, !"Debug Info Version", i32 3} 129 !19 = !{!"clang version 3.8.0 (trunk 253049)"} 130 !20 = !DIExpression() 131 !21 = !DILocation(line: 6, column: 14, scope: !4) 132 !22 = !DILocation(line: 6, column: 27, scope: !23) 133 !23 = !DILexicalBlockFile(scope: !4, file: !1, discriminator: 1) 134 !24 = !DILocation(line: 8, column: 12, scope: !25) 135 !25 = distinct !DILexicalBlock(scope: !4, file: !1, line: 8, column: 7) 136 !26 = !DILocation(line: 8, column: 7, scope: !4) 137 !27 = !DILocation(line: 11, column: 14, scope: !25) 138 !28 = !{!29, !29, i64 0} 139 !29 = !{!"any pointer", !30, i64 0} 140 !30 = !{!"omnipotent char", !31, i64 0} 141 !31 = !{!"Simple C/C++ TBAA"} 142 !32 = !DILocation(line: 11, column: 9, scope: !25) 143 !33 = !DILocation(line: 7, column: 7, scope: !23) 144 !34 = !DILocation(line: 12, column: 7, scope: !4) 145 !35 = !DILocation(line: 13, column: 9, scope: !36) 146 !36 = distinct !DILexicalBlock(scope: !4, file: !1, line: 13, column: 7) 147 !37 = !DILocation(line: 13, column: 7, scope: !4) 148 !38 = !DILocation(line: 14, column: 9, scope: !39) 149 !39 = distinct !DILexicalBlock(scope: !36, file: !1, line: 13, column: 15) 150 !40 = !DILocation(line: 15, column: 11, scope: !39) 151 !41 = !DILocation(line: 16, column: 3, scope: !39) 152 !42 = !DILocation(line: 18, column: 9, scope: !36) 153 !43 = !DILocation(line: 15, column: 7, scope: !39) 154 !44 = !{!45, !45, i64 0} 155 !45 = !{!"int", !30, i64 0} 156 !46 = !DILocation(line: 19, column: 3, scope: !4) 157 !47 = !DILocation(line: 20, column: 3, scope: !4) 158 159 ... 160 --- 161 name: main 162 alignment: 4 163 exposesReturnsTwice: false 164 hasInlineAsm: false 165 isSSA: false 166 tracksRegLiveness: true 167 tracksSubRegLiveness: false 168 liveins: 169 - { reg: '%edi' } 170 - { reg: '%rsi' } 171 calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', 172 '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15', 173 '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', 174 '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] 175 frameInfo: 176 isFrameAddressTaken: false 177 isReturnAddressTaken: false 178 hasStackMap: false 179 hasPatchPoint: false 180 stackSize: 8 181 offsetAdjustment: 0 182 maxAlignment: 0 183 adjustsStack: true 184 hasCalls: true 185 maxCallFrameSize: 0 186 hasOpaqueSPAdjustment: false 187 hasVAStart: false 188 hasMustTailInVarArgFunc: false 189 fixedStack: 190 - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '%rbx' } 191 body: | 192 bb.0.entry: 193 successors: %bb.1.if.else(16), %bb.2.if.end(16) 194 liveins: %edi, %rsi, %rbx 195 196 frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp 197 CFI_INSTRUCTION .cfi_def_cfa_offset 16 198 CFI_INSTRUCTION .cfi_offset %rbx, -16 199 DBG_VALUE debug-use %edi, debug-use _, !12, !20, debug-location !21 200 DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22 201 %eax = MOV32rr %edi 202 DBG_VALUE debug-use %eax, debug-use _, !12, !20, debug-location !21 203 %edi = MOV32ri 2 204 CMP32ri8 killed %eax, 2, implicit-def %eflags, debug-location !26 205 JNE_1 %bb.2.if.end, implicit %eflags 206 207 bb.1.if.else: 208 successors: %bb.2.if.end(0) 209 liveins: %rsi 210 211 DBG_VALUE debug-use %rsi, debug-use _, !13, !20, debug-location !22 212 %rdi = MOV64rm killed %rsi, 1, _, 8, _, debug-location !27 :: (load 8 from %ir.arrayidx, !tbaa !28) 213 dead %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, implicit-def %al, debug-location !32 214 CALL64pcrel32 @atoi, csr_64, implicit %rsp, implicit %rdi, implicit %al, implicit-def %rsp, implicit-def %eax, debug-location !32 215 %edi = MOV32rr %eax, debug-location !32 216 DBG_VALUE debug-use %edi, debug-use _, !14, !20, debug-location !33 217 218 bb.2.if.end: 219 successors: %bb.3.if.then.3(16), %bb.4.if.else.5(16) 220 liveins: %edi 221 222 CALL64pcrel32 @change, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !34 223 %ebx = MOV32rr %eax, debug-location !34 224 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33 225 CMP32ri8 %ebx, 11, implicit-def %eflags, debug-location !37 226 JL_1 %bb.4.if.else.5, implicit killed %eflags, debug-location !37 227 228 bb.3.if.then.3: 229 successors: %bb.5.if.end.7(0) 230 liveins: %ebx 231 232 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33 233 %edi = MOV32rr %ebx, debug-location !38 234 CALL64pcrel32 @modify, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !38 235 %ecx = MOV32rr %eax, debug-location !38 236 %ecx = ADD32rr killed %ecx, killed %ebx, implicit-def dead %eflags, debug-location !40 237 JMP_1 %bb.5.if.end.7 238 239 bb.4.if.else.5: 240 successors: %bb.5.if.end.7(0) 241 liveins: %ebx 242 243 DBG_VALUE debug-use %ebx, debug-use _, !14, !20, debug-location !33 244 %edi = MOV32rr killed %ebx, debug-location !42 245 CALL64pcrel32 @inc, csr_64, implicit %rsp, implicit %edi, implicit-def %rsp, implicit-def %eax, debug-location !42 246 %ecx = MOV32rr %eax, debug-location !42 247 248 bb.5.if.end.7: 249 liveins: %ecx 250 251 MOV32mr %rip, 1, _, @m, _, %ecx, debug-location !43 :: (store 4 into @m, !tbaa !44) 252 dead undef %edi = MOV32ri64 @.str, implicit-def %rdi, debug-location !46 253 dead %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, implicit-def %al, debug-location !47 254 %esi = MOV32rr killed %ecx, debug-location !46 255 CALL64pcrel32 @printf, csr_64, implicit %rsp, implicit %rdi, implicit %esi, implicit %al, implicit-def %rsp, implicit-def dead %eax, debug-location !46 256 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags, debug-location !47 257 %rbx = POP64r implicit-def %rsp, implicit %rsp, debug-location !47 258 RETQ %eax, debug-location !47 259 260 ... 261