1# RUN: llc %s -start-before=livedebugvalues -o - | \ 2# RUN: FileCheck %s --implicit-check-not=prologue_end 3# 4## When picking a "backup" location of the first non-trivial instruction in 5## a function, don't select a location outside of the entry block. We have to 6## give it the function's scope-line, and installing that outside of the entry 7## block is liable to be misleading. 8## 9## Produced from the C below with "clang -O2 -g -mllvm 10## -stop-before=livedebugvalues", then modified to unrotate and shift early 11## insts into the loop block. This means the MIR is meaningless, we only test 12## whether the scope-line will leak into the loop block or not. 13## 14## int glob = 0; 15## int foo(int arg, int sum) { 16## arg += sum; 17## while (arg) { 18## glob--; 19## arg %= glob; 20## } 21## return 0; 22## } 23# 24# CHECK-LABEL: foo: 25# CHECK: .loc 0 2 0 26# CHECK: # %bb.0: 27# CHECK-NEXT: movl %edi, %edx 28# CHECK-NEXT: .loc 0 0 0 is_stmt 0 29# CHECK-NEXT: .Ltmp0: 30# CHECK-NEXT: .p2align 4 31# CHECK-NEXT: .LBB0_1: 32# CHECK-LABEL: addl %esi, %edx 33 34## Second function in this file: test that we don't crash when having trailing 35## empty blocks and no location for a prologue. Test that a .loc is produced, 36## with an implicit-not check for there being no prologue_end. 37# 38# CHECK-LABEL: f: 39# CHECK: .loc 0 1234 0 40 41 42--- | 43 ; ModuleID = 'out2.ll' 44 source_filename = "foo.c" 45 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" 46 target triple = "x86_64-unknown-linux-gnu" 47 48 @glob = dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 49 50 define dso_local noundef i32 @foo(i32 noundef %arg, i32 noundef %sum) local_unnamed_addr !dbg !9 { 51 entry: 52 %add = add nsw i32 %sum, %arg 53 br label %while.body.preheader 54 55 while.body.preheader: ; preds = %entry 56 %glob.promoted = load i32, ptr @glob, align 4 57 br label %while.body, !dbg !13 58 59 while.body: ; preds = %while.body, %while.body.preheader 60 %arg.addr.06 = phi i32 [ %rem, %while.body ], [ %add, %while.body.preheader ] 61 %dec35 = phi i32 [ %dec, %while.body ], [ %glob.promoted, %while.body.preheader ] 62 %dec = add nsw i32 %dec35, -1, !dbg !14 63 %0 = add i32 %dec35, -1, !dbg !16 64 %rem = srem i32 %arg.addr.06, %0, !dbg !16 65 %tobool.not = icmp eq i32 %rem, 0, !dbg !13 66 br i1 %tobool.not, label %while.cond.while.end_crit_edge, label %while.body, !dbg !13 67 68 while.cond.while.end_crit_edge: ; preds = %while.body 69 store i32 %dec, ptr @glob, align 4, !dbg !14 70 br label %while.end, !dbg !13 71 72 while.end: ; preds = %while.cond.while.end_crit_edge 73 ret i32 0, !dbg !17 74 } 75 76 define void @f() !dbg !18 { 77 entry: 78 %0 = call ptr @llvm.returnaddress(i32 0) 79 br label %do.body 80 81 do.body: 82 unreachable 83 } 84 85 declare ptr @llvm.returnaddress(i32 immarg) 86 87 !llvm.dbg.cu = !{!2} 88 !llvm.module.flags = !{!6, !7} 89 !llvm.ident = !{!8} 90 91 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 92 !1 = distinct !DIGlobalVariable(name: "glob", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) 93 !2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) 94 !3 = !DIFile(filename: "foo.c", directory: "") 95 !4 = !{!0} 96 !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 97 !6 = !{i32 7, !"Dwarf Version", i32 5} 98 !7 = !{i32 2, !"Debug Info Version", i32 3} 99 !8 = !{!"clang"} 100 !9 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !10, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !12) 101 !10 = !DISubroutineType(types: !11) 102 !11 = !{!5, !5, !5} 103 !12 = !{} 104 !13 = !DILocation(line: 4, column: 3, scope: !9) 105 !14 = !DILocation(line: 5, column: 9, scope: !15) 106 !15 = distinct !DILexicalBlock(scope: !9, file: !3, line: 4, column: 15) 107 !16 = !DILocation(line: 6, column: 9, scope: !15) 108 !17 = !DILocation(line: 8, column: 3, scope: !9) 109 !18 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 37, type: !10, scopeLine: 1234, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2) 110 111... 112--- 113name: foo 114alignment: 16 115tracksRegLiveness: true 116debugInstrRef: true 117tracksDebugUserValues: true 118liveins: 119 - { reg: '$edi' } 120 - { reg: '$esi' } 121frameInfo: 122 maxAlignment: 1 123 maxCallFrameSize: 0 124 isCalleeSavedInfoValid: true 125machineFunctionInfo: 126 amxProgModel: None 127body: | 128 bb.0.entry: 129 liveins: $edi, $esi 130 131 $edx = MOV32rr $edi 132 133 bb.1.while.body (align 16): 134 successors: %bb.2(0x04000000), %bb.1(0x7c000000) 135 liveins: $ecx, $edx, $esi 136 137 renamable $edx = nsw ADD32rr killed renamable $edx, renamable $esi, implicit-def dead $eflags 138 renamable $ecx = MOV32rm $rip, 1, $noreg, @glob, $noreg :: (dereferenceable load (s32) from @glob) 139 renamable $ecx = DEC32r killed renamable $ecx, implicit-def dead $eflags 140 $eax = MOV32rr killed $edx 141 CDQ implicit-def $eax, implicit-def $edx, implicit $eax 142 IDIV32r renamable $ecx, implicit-def dead $eax, implicit-def $edx, implicit-def dead $eflags, implicit $eax, implicit $edx 143 TEST32rr renamable $edx, renamable $edx, implicit-def $eflags 144 JCC_1 %bb.1, 5, implicit killed $eflags 145 146 bb.2.while.cond.while.end_crit_edge: 147 liveins: $ecx, $esi 148 149 MOV32mr $rip, 1, $noreg, @glob, $noreg, killed renamable $ecx, debug-location !14 :: (store (s32) into @glob) 150 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, debug-location !17 151 RET64 $eax, debug-location !17 152 153... 154--- 155name: f 156alignment: 16 157tracksRegLiveness: true 158noPhis: true 159isSSA: false 160noVRegs: true 161hasFakeUses: false 162tracksDebugUserValues: true 163frameInfo: 164 stackSize: 8 165 offsetAdjustment: -8 166 maxAlignment: 1 167 maxCallFrameSize: 0 168 isCalleeSavedInfoValid: true 169fixedStack: 170 - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16 } 171machineFunctionInfo: 172 amxProgModel: None 173body: | 174 bb.0.entry: 175 frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp 176 frame-setup CFI_INSTRUCTION def_cfa_offset 16 177 frame-setup CFI_INSTRUCTION offset $rbp, -16 178 $rbp = frame-setup MOV64rr $rsp 179 frame-setup CFI_INSTRUCTION def_cfa_register $rbp 180 181 bb.1.do.body: 182 183... 184