summaryrefslogtreecommitdiffstats
path: root/llvm/test/DebugInfo/COFF
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/DebugInfo/COFF')
-rw-r--r--llvm/test/DebugInfo/COFF/asm.ll2
-rw-r--r--llvm/test/DebugInfo/COFF/frameproc-flags.ll379
-rw-r--r--llvm/test/DebugInfo/COFF/local-variables.ll45
-rw-r--r--llvm/test/DebugInfo/COFF/multifile.ll4
-rw-r--r--llvm/test/DebugInfo/COFF/multifunction.ll86
-rw-r--r--llvm/test/DebugInfo/COFF/pieces.ll10
-rw-r--r--llvm/test/DebugInfo/COFF/simple.ll34
-rw-r--r--llvm/test/DebugInfo/COFF/types-array.ll7
-rw-r--r--llvm/test/DebugInfo/COFF/vframe-fpo.ll264
9 files changed, 772 insertions, 59 deletions
diff --git a/llvm/test/DebugInfo/COFF/asm.ll b/llvm/test/DebugInfo/COFF/asm.ll
index fa2a25894f6..ed71b246f3c 100644
--- a/llvm/test/DebugInfo/COFF/asm.ll
+++ b/llvm/test/DebugInfo/COFF/asm.ll
@@ -99,7 +99,7 @@
; OBJ64: DisplayName: f
; OBJ64: LinkageName: f
; OBJ64: }
-; OBJ64-NEXT: ProcEnd {
+; OBJ64: ProcEnd {
; OBJ64: }
; OBJ64-NEXT: ]
; OBJ64: FunctionLineTable [
diff --git a/llvm/test/DebugInfo/COFF/frameproc-flags.ll b/llvm/test/DebugInfo/COFF/frameproc-flags.ll
new file mode 100644
index 00000000000..a9d0fe067da
--- /dev/null
+++ b/llvm/test/DebugInfo/COFF/frameproc-flags.ll
@@ -0,0 +1,379 @@
+; RUN: llc -filetype=obj %s -o %t.obj
+; RUN: llvm-pdbutil dump %t.obj -symbols | FileCheck %s
+
+; A fairly exhaustive test of S_FRAMEPROC flags. Use the source below to compare
+; the flags we set with MSVC.
+
+; extern "C" {
+;
+; void *_alloca(size_t);
+; struct __declspec(align(16)) _jmp_buf_str {
+; unsigned __int64 Part[2];
+; };
+; typedef struct _jmp_buf_str jmp_buf[16];
+; int __cdecl _setjmp(jmp_buf _Buf);
+;
+; void may_throw(void);
+; void use_intptr(int *);
+;
+; void use_alloca(int n) {
+; int *p = (int*)_alloca(n * sizeof(int));
+; use_intptr(p);
+; }
+;
+; jmp_buf g_jbuf;
+; void call_setjmp(int n) {
+; if (!_setjmp(g_jbuf))
+; use_intptr(nullptr);
+; }
+;
+; void use_inlineasm() {
+; __asm nop
+; }
+;
+; void cpp_eh() {
+; try {
+; may_throw();
+; } catch (...) {
+; }
+; }
+;
+; static inline int is_marked_inline(int x, int y) {
+; return x + y;
+; }
+; int (*use_inline())(int x, int y) {
+; return &is_marked_inline;
+; }
+;
+; void seh() {
+; __try {
+; may_throw();
+; } __except (1) {
+; }
+; }
+;
+; void __declspec(naked) use_naked() {
+; __asm ret
+; }
+;
+; void stack_guard() {
+; int arr[12] = {0};
+; use_intptr(&arr[0]);
+; }
+; }
+
+; CHECK-LABEL: S_GPROC32_ID [size = 50] `use_alloca`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = VFRAME, param fp reg = EBP
+; CHECK: flags = has alloca | secure checks | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 51] `call_setjmp`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = NONE, param fp reg = NONE
+; CHECK: flags = has setjmp | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 53] `use_inlineasm`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = NONE, param fp reg = NONE
+; CHECK: flags = has inline asm | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 46] `cpp_eh`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = EBP, param fp reg = EBP
+; CHECK: flags = has eh | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 50] `use_inline`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = NONE, param fp reg = NONE
+; CHECK: flags = opt speed
+; CHECK-LABEL: S_LPROC32_ID [size = 56] `is_marked_inline`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = NONE, param fp reg = NONE
+; CHECK: flags = marked inline | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 43] `seh`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = EBP, param fp reg = EBP
+; CHECK: flags = has seh | opt speed
+; CHECK-LABEL: S_LPROC32_ID [size = 55] `?filt$0@0@seh@@`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = EBP, param fp reg = EBP
+; CHECK: flags = opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 49] `use_naked`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = NONE, param fp reg = NONE
+; CHECK: flags = has inline asm | naked | opt speed
+; CHECK-LABEL: S_GPROC32_ID [size = 51] `stack_guard`
+; CHECK: S_FRAMEPROC [size = 30]
+; CHECK: local fp reg = VFRAME, param fp reg = EBP
+; CHECK: flags = secure checks | opt speed
+
+; ModuleID = 'frameproc-flags.cpp'
+source_filename = "frameproc-flags.cpp"
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i386-pc-windows-msvc19.14.26433"
+
+%struct._jmp_buf_str = type { [2 x i64] }
+
+@g_jbuf = dso_local global [16 x %struct._jmp_buf_str] zeroinitializer, align 16, !dbg !0
+
+define dso_local void @use_alloca(i32 %n) local_unnamed_addr #0 !dbg !25 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %n, metadata !29, metadata !DIExpression()), !dbg !31
+ %mul = shl i32 %n, 2, !dbg !32
+ %0 = alloca i8, i32 %mul, align 16, !dbg !32
+ %1 = bitcast i8* %0 to i32*, !dbg !32
+ call void @llvm.dbg.value(metadata i32* %1, metadata !30, metadata !DIExpression()), !dbg !32
+ call void @use_intptr(i32* nonnull %1), !dbg !33
+ ret void, !dbg !34
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #2
+
+declare dso_local void @use_intptr(i32*) local_unnamed_addr #3
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #2
+
+define dso_local void @call_setjmp(i32 %n) local_unnamed_addr #0 !dbg !35 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %n, metadata !37, metadata !DIExpression()), !dbg !38
+ %0 = call i32 (i8*, i32, ...) @_setjmp3(i8* bitcast ([16 x %struct._jmp_buf_str]* @g_jbuf to i8*), i32 0) #4, !dbg !39
+ %tobool = icmp eq i32 %0, 0, !dbg !39
+ br i1 %tobool, label %if.then, label %if.end, !dbg !39
+
+if.then: ; preds = %entry
+ call void @use_intptr(i32* null), !dbg !40
+ br label %if.end, !dbg !40
+
+if.end: ; preds = %entry, %if.then
+ ret void, !dbg !42
+}
+
+; Function Attrs: returns_twice
+declare dso_local i32 @_setjmp3(i8*, i32, ...) local_unnamed_addr #4
+
+; Function Attrs: nounwind
+define dso_local void @use_inlineasm() local_unnamed_addr #5 !dbg !43 {
+entry:
+ tail call void asm sideeffect inteldialect "nop", "~{dirflag},~{fpsr},~{flags}"() #10, !dbg !46, !srcloc !47
+ ret void, !dbg !48
+}
+
+define dso_local void @cpp_eh() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) !dbg !49 {
+entry:
+ invoke void @may_throw()
+ to label %try.cont unwind label %catch.dispatch, !dbg !50
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %catch] unwind to caller, !dbg !52
+
+catch: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* null, i32 64, i8* null], !dbg !52
+ catchret from %1 to label %try.cont, !dbg !53
+
+try.cont: ; preds = %entry, %catch
+ ret void, !dbg !55
+}
+
+declare dso_local void @may_throw() local_unnamed_addr #3
+
+declare dso_local i32 @__CxxFrameHandler3(...)
+
+; Function Attrs: norecurse nounwind readnone
+define dso_local nonnull i32 (i32, i32)* @use_inline() local_unnamed_addr #6 !dbg !56 {
+entry:
+ ret i32 (i32, i32)* @"?is_marked_inline@@YAHHH@Z", !dbg !62
+}
+
+; Function Attrs: inlinehint nounwind readnone
+define internal i32 @"?is_marked_inline@@YAHHH@Z"(i32 %x, i32 %y) #7 !dbg !63 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %y, metadata !65, metadata !DIExpression()), !dbg !67
+ call void @llvm.dbg.value(metadata i32 %x, metadata !66, metadata !DIExpression()), !dbg !67
+ %add = add nsw i32 %y, %x, !dbg !68
+ ret i32 %add, !dbg !68
+}
+
+define dso_local void @seh() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) !dbg !69 {
+entry:
+ %__exception_code = alloca i32, align 4
+ call void (...) @llvm.localescape(i32* nonnull %__exception_code)
+ invoke void @may_throw() #12
+ to label %__try.cont unwind label %catch.dispatch, !dbg !70
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %__except.ret] unwind to caller, !dbg !72
+
+__except.ret: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* bitcast (i32 ()* @"?filt$0@0@seh@@" to i8*)], !dbg !72
+ catchret from %1 to label %__try.cont, !dbg !72
+
+__try.cont: ; preds = %entry, %__except.ret
+ ret void, !dbg !73
+}
+
+; Function Attrs: nounwind
+define internal i32 @"?filt$0@0@seh@@"() #8 !dbg !74 {
+entry:
+ %0 = tail call i8* @llvm.frameaddress(i32 1)
+ %1 = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @seh to i8*), i8* %0)
+ %2 = tail call i8* @llvm.localrecover(i8* bitcast (void ()* @seh to i8*), i8* %1, i32 0)
+ %__exception_code = bitcast i8* %2 to i32*
+ %3 = getelementptr inbounds i8, i8* %0, i32 -20, !dbg !76
+ %4 = bitcast i8* %3 to { i32*, i8* }**, !dbg !76
+ %5 = load { i32*, i8* }*, { i32*, i8* }** %4, align 4, !dbg !76
+ %6 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %5, i32 0, i32 0, !dbg !76
+ %7 = load i32*, i32** %6, align 4, !dbg !76
+ %8 = load i32, i32* %7, align 4, !dbg !76
+ store i32 %8, i32* %__exception_code, align 4, !dbg !76
+ ret i32 1, !dbg !76
+}
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.frameaddress(i32) #9
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) #9
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.localrecover(i8*, i8*, i32) #9
+
+declare dso_local i32 @_except_handler3(...)
+
+; Function Attrs: nounwind
+declare void @llvm.localescape(...) #10
+
+; Function Attrs: naked noinline nounwind
+define dso_local void @use_naked() #11 !dbg !77 {
+entry:
+ tail call void asm sideeffect inteldialect "ret", "~{dirflag},~{fpsr},~{flags}"() #10, !dbg !78, !srcloc !79
+ unreachable, !dbg !80
+}
+
+define dso_local void @stack_guard() local_unnamed_addr #0 !dbg !81 {
+entry:
+ %arr = alloca [12 x i32], align 4
+ %0 = bitcast [12 x i32]* %arr to i8*, !dbg !87
+ call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull %0) #10, !dbg !87
+ call void @llvm.dbg.declare(metadata [12 x i32]* %arr, metadata !83, metadata !DIExpression()), !dbg !87
+ call void @llvm.memset.p0i8.i32(i8* nonnull align 4 %0, i8 0, i32 48, i1 false), !dbg !87
+ %arrayidx = getelementptr inbounds [12 x i32], [12 x i32]* %arr, i32 0, i32 0, !dbg !88
+ call void @use_intptr(i32* nonnull %arrayidx), !dbg !88
+ call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull %0) #10, !dbg !89
+ ret void, !dbg !89
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1) #2
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #0 = { sspstrong "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone speculatable }
+attributes #2 = { argmemonly nounwind }
+attributes #3 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #4 = { returns_twice }
+attributes #5 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #6 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #7 = { inlinehint nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #8 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #9 = { nounwind readnone }
+attributes #10 = { nounwind }
+attributes #11 = { naked noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #12 = { noinline }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!20, !21, !22, !23}
+!llvm.ident = !{!24}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g_jbuf", scope: !2, file: !3, line: 18, type: !9, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !8, nameTableKind: None)
+!3 = !DIFile(filename: "frameproc-flags.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "1dd66a71668512c95552767c3a35300a")
+!4 = !{}
+!5 = !{!6}
+!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32)
+!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!8 = !{!0}
+!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "jmp_buf", file: !3, line: 7, baseType: !10)
+!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 2048, elements: !18)
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_jmp_buf_str", file: !3, line: 4, size: 128, align: 128, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !12, identifier: ".?AU_jmp_buf_str@@")
+!12 = !{!13}
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "Part", scope: !11, file: !3, line: 5, baseType: !14, size: 128)
+!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 128, elements: !16)
+!15 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
+!16 = !{!17}
+!17 = !DISubrange(count: 2)
+!18 = !{!19}
+!19 = !DISubrange(count: 16)
+!20 = !{i32 1, !"NumRegisterParameters", i32 0}
+!21 = !{i32 2, !"CodeView", i32 1}
+!22 = !{i32 2, !"Debug Info Version", i32 3}
+!23 = !{i32 1, !"wchar_size", i32 2}
+!24 = !{!"clang version 8.0.0 "}
+!25 = distinct !DISubprogram(name: "use_alloca", scope: !3, file: !3, line: 13, type: !26, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !28)
+!26 = !DISubroutineType(types: !27)
+!27 = !{null, !7}
+!28 = !{!29, !30}
+!29 = !DILocalVariable(name: "n", arg: 1, scope: !25, file: !3, line: 13, type: !7)
+!30 = !DILocalVariable(name: "p", scope: !25, file: !3, line: 14, type: !6)
+!31 = !DILocation(line: 13, scope: !25)
+!32 = !DILocation(line: 14, scope: !25)
+!33 = !DILocation(line: 15, scope: !25)
+!34 = !DILocation(line: 16, scope: !25)
+!35 = distinct !DISubprogram(name: "call_setjmp", scope: !3, file: !3, line: 19, type: !26, isLocal: false, isDefinition: true, scopeLine: 19, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !36)
+!36 = !{!37}
+!37 = !DILocalVariable(name: "n", arg: 1, scope: !35, file: !3, line: 19, type: !7)
+!38 = !DILocation(line: 19, scope: !35)
+!39 = !DILocation(line: 20, scope: !35)
+!40 = !DILocation(line: 21, scope: !41)
+!41 = distinct !DILexicalBlock(scope: !35, file: !3, line: 20)
+!42 = !DILocation(line: 22, scope: !35)
+!43 = distinct !DISubprogram(name: "use_inlineasm", scope: !3, file: !3, line: 24, type: !44, isLocal: false, isDefinition: true, scopeLine: 24, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!44 = !DISubroutineType(types: !45)
+!45 = !{null}
+!46 = !DILocation(line: 25, scope: !43)
+!47 = !{i32 445}
+!48 = !DILocation(line: 26, scope: !43)
+!49 = distinct !DISubprogram(name: "cpp_eh", scope: !3, file: !3, line: 28, type: !44, isLocal: false, isDefinition: true, scopeLine: 28, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!50 = !DILocation(line: 30, scope: !51)
+!51 = distinct !DILexicalBlock(scope: !49, file: !3, line: 29)
+!52 = !DILocation(line: 31, scope: !51)
+!53 = !DILocation(line: 32, scope: !54)
+!54 = distinct !DILexicalBlock(scope: !49, file: !3, line: 31)
+!55 = !DILocation(line: 33, scope: !49)
+!56 = distinct !DISubprogram(name: "use_inline", scope: !3, file: !3, line: 38, type: !57, isLocal: false, isDefinition: true, scopeLine: 38, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!57 = !DISubroutineType(types: !58)
+!58 = !{!59}
+!59 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !60, size: 32)
+!60 = !DISubroutineType(types: !61)
+!61 = !{!7, !7, !7}
+!62 = !DILocation(line: 39, scope: !56)
+!63 = distinct !DISubprogram(name: "is_marked_inline", linkageName: "?is_marked_inline@@YAHHH@Z", scope: !3, file: !3, line: 35, type: !60, isLocal: true, isDefinition: true, scopeLine: 35, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !64)
+!64 = !{!65, !66}
+!65 = !DILocalVariable(name: "y", arg: 2, scope: !63, file: !3, line: 35, type: !7)
+!66 = !DILocalVariable(name: "x", arg: 1, scope: !63, file: !3, line: 35, type: !7)
+!67 = !DILocation(line: 35, scope: !63)
+!68 = !DILocation(line: 36, scope: !63)
+!69 = distinct !DISubprogram(name: "seh", scope: !3, file: !3, line: 42, type: !44, isLocal: false, isDefinition: true, scopeLine: 42, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!70 = !DILocation(line: 44, scope: !71)
+!71 = distinct !DILexicalBlock(scope: !69, file: !3, line: 43)
+!72 = !DILocation(line: 45, scope: !71)
+!73 = !DILocation(line: 47, scope: !69)
+!74 = distinct !DISubprogram(linkageName: "?filt$0@0@seh@@", scope: !3, file: !3, line: 45, type: !75, isLocal: true, isDefinition: true, scopeLine: 45, flags: DIFlagArtificial, isOptimized: true, unit: !2, retainedNodes: !4)
+!75 = !DISubroutineType(types: !4)
+!76 = !DILocation(line: 45, scope: !74)
+!77 = distinct !DISubprogram(name: "use_naked", scope: !3, file: !3, line: 49, type: !44, isLocal: false, isDefinition: true, scopeLine: 49, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4)
+!78 = !DILocation(line: 50, scope: !77)
+!79 = !{i32 765}
+!80 = !DILocation(line: 51, scope: !77)
+!81 = distinct !DISubprogram(name: "stack_guard", scope: !3, file: !3, line: 53, type: !44, isLocal: false, isDefinition: true, scopeLine: 53, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !82)
+!82 = !{!83}
+!83 = !DILocalVariable(name: "arr", scope: !81, file: !3, line: 54, type: !84)
+!84 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 384, elements: !85)
+!85 = !{!86}
+!86 = !DISubrange(count: 12)
+!87 = !DILocation(line: 54, scope: !81)
+!88 = !DILocation(line: 55, scope: !81)
+!89 = !DILocation(line: 56, scope: !81)
diff --git a/llvm/test/DebugInfo/COFF/local-variables.ll b/llvm/test/DebugInfo/COFF/local-variables.ll
index 683b438d396..085ced17262 100644
--- a/llvm/test/DebugInfo/COFF/local-variables.ll
+++ b/llvm/test/DebugInfo/COFF/local-variables.ll
@@ -71,30 +71,30 @@
; ASM: .long 116 # TypeIndex
; ASM: .short 1 # Flags
; ASM: .asciz "param"
-; ASM: .cv_def_range [[prologue_end]] [[param_end]], "E\021O\001\000\0004\000\000\000"
+; ASM: .cv_def_range [[prologue_end]] [[param_end]], "B\0214\000\000\000"
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .long 116 # TypeIndex
; ASM: .short 0 # Flags
; ASM: .asciz "a"
-; ASM: .cv_def_range [[if_start]] [[else_start]], "E\021O\001\000\000(\000\000\000"
+; ASM: .cv_def_range [[if_start]] [[else_start]], "B\021(\000\000\000"
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .long 116 # TypeIndex
; ASM: .short 0 # Flags
; ASM: .asciz "b"
-; ASM: .cv_def_range [[else_start]] [[else_end]], "E\021O\001\000\000$\000\000\000"
+; ASM: .cv_def_range [[else_start]] [[else_end]], "B\021$\000\000\000"
; ASM: .short 4429 # Record kind: S_INLINESITE
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .long 116 # TypeIndex
; ASM: .short 0 # Flags
; ASM: .asciz "v"
-; ASM: .cv_def_range [[inline_site1]] [[else_start]], "E\021O\001\000\000,\000\000\000"
+; ASM: .cv_def_range [[inline_site1]] [[else_start]], "B\021,\000\000\000"
; ASM: .short 4430 # Record kind: S_INLINESITE_END
; ASM: .short 4429 # Record kind: S_INLINESITE
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .long 116 # TypeIndex
; ASM: .short 0 # Flags
; ASM: .asciz "v"
-; ASM: .cv_def_range [[inline_site2]] [[else_end]], "E\021O\001\000\0000\000\000\000"
+; ASM: .cv_def_range [[inline_site2]] [[else_end]], "B\0210\000\000\000"
; ASM: .short 4430 # Record kind: S_INLINESITE_END
; OBJ: Subsection [
@@ -110,11 +110,8 @@
; OBJ: ]
; OBJ: VarName: param
; OBJ: }
-; OBJ: DefRangeRegisterRelSym {
-; OBJ: BaseRegister: RSP (0x14F)
-; OBJ: HasSpilledUDTMember: No
-; OBJ: OffsetInParent: 0
-; OBJ: BasePointerOffset: 52
+; OBJ: DefRangeFramePointerRelSym {
+; OBJ: Offset: 52
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x8
; OBJ: ISectStart: 0x0
@@ -127,11 +124,8 @@
; OBJ: ]
; OBJ: VarName: a
; OBJ: }
-; OBJ: DefRangeRegisterRelSym {
-; OBJ: BaseRegister: RSP (0x14F)
-; OBJ: HasSpilledUDTMember: No
-; OBJ: OffsetInParent: 0
-; OBJ: BasePointerOffset: 40
+; OBJ: DefRangeFramePointerRelSym {
+; OBJ: Offset: 40
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0xC
; OBJ: ISectStart: 0x0
@@ -144,11 +138,8 @@
; OBJ: ]
; OBJ: VarName: b
; OBJ: }
-; OBJ: DefRangeRegisterRelSym {
-; OBJ: BaseRegister: RSP (0x14F)
-; OBJ: HasSpilledUDTMember: No
-; OBJ: OffsetInParent: 0
-; OBJ: BasePointerOffset: 36
+; OBJ: DefRangeFramePointerRelSym {
+; OBJ: Offset: 36
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x2D
; OBJ: ISectStart: 0x0
@@ -172,11 +163,8 @@
; OBJ: ]
; OBJ: VarName: v
; OBJ: }
-; OBJ: DefRangeRegisterRelSym {
-; OBJ: BaseRegister: RSP (0x14F)
-; OBJ: HasSpilledUDTMember: No
-; OBJ: OffsetInParent: 0
-; OBJ: BasePointerOffset: 44
+; OBJ: DefRangeFramePointerRelSym {
+; OBJ: Offset: 44
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x14
; OBJ: ISectStart: 0x0
@@ -202,11 +190,8 @@
; OBJ: ]
; OBJ: VarName: v
; OBJ: }
-; OBJ: DefRangeRegisterRelSym {
-; OBJ: BaseRegister: RSP (0x14F)
-; OBJ: HasSpilledUDTMember: No
-; OBJ: OffsetInParent: 0
-; OBJ: BasePointerOffset: 48
+; OBJ: DefRangeFramePointerRelSym {
+; OBJ: Offset: 48
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x35
; OBJ: ISectStart: 0x0
diff --git a/llvm/test/DebugInfo/COFF/multifile.ll b/llvm/test/DebugInfo/COFF/multifile.ll
index ea6e758a243..cb281ea7a4d 100644
--- a/llvm/test/DebugInfo/COFF/multifile.ll
+++ b/llvm/test/DebugInfo/COFF/multifile.ll
@@ -48,7 +48,7 @@
; OBJ32: DisplayName: f
; OBJ32: LinkageName: _f
; OBJ32: }
-; OBJ32-NEXT: ProcEnd {
+; OBJ32: ProcEnd {
; OBJ32: }
; OBJ32-NEXT: ]
; OBJ32: Subsection [
@@ -136,7 +136,7 @@
; OBJ64: DisplayName: f
; OBJ64: LinkageName: f
; OBJ64: }
-; OBJ64-NEXT: ProcEnd {
+; OBJ64: ProcEnd {
; OBJ64: }
; OBJ64-NEXT: ]
; OBJ64: Subsection [
diff --git a/llvm/test/DebugInfo/COFF/multifunction.ll b/llvm/test/DebugInfo/COFF/multifunction.ll
index c675edab5aa..c74b332d8b8 100644
--- a/llvm/test/DebugInfo/COFF/multifunction.ll
+++ b/llvm/test/DebugInfo/COFF/multifunction.ll
@@ -81,6 +81,17 @@
; X86-NEXT: .byte 0
; X86-NEXT: .asciz "x"
; X86-NEXT: [[PROC_SEGMENT_END]]:
+; X86-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X86-NEXT: [[FPROC_BEG]]:
+; X86-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X86-NEXT: .long 0 # FrameSize
+; X86-NEXT: .long 0 # Padding
+; X86-NEXT: .long 0 # Offset of padding
+; X86-NEXT: .long 0 # Bytes of callee saved registers
+; X86-NEXT: .long 0 # Exception handler offset
+; X86-NEXT: .short 0 # Exception handler section
+; X86-NEXT: .long 0 # Flags (defines frame register)
+; X86-NEXT: [[FPROC_END]]:
; X86-NEXT: .short 2
; X86-NEXT: .short 4431
; X86-NEXT: [[F1_END]]:
@@ -107,6 +118,17 @@
; X86-NEXT: .byte 0
; X86-NEXT: .asciz "y"
; X86-NEXT: [[PROC_SEGMENT_END]]:
+; X86-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X86-NEXT: [[FPROC_BEG]]:
+; X86-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X86-NEXT: .long 0 # FrameSize
+; X86-NEXT: .long 0 # Padding
+; X86-NEXT: .long 0 # Offset of padding
+; X86-NEXT: .long 0 # Bytes of callee saved registers
+; X86-NEXT: .long 0 # Exception handler offset
+; X86-NEXT: .short 0 # Exception handler section
+; X86-NEXT: .long 0 # Flags (defines frame register)
+; X86-NEXT: [[FPROC_END]]:
; X86-NEXT: .short 2
; X86-NEXT: .short 4431
; X86-NEXT: [[COMPILE_END]]:
@@ -133,6 +155,17 @@
; X86-NEXT: .byte 0
; X86-NEXT: .asciz "f"
; X86-NEXT: [[PROC_SEGMENT_END]]:
+; X86-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X86-NEXT: [[FPROC_BEG]]:
+; X86-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X86-NEXT: .long 0 # FrameSize
+; X86-NEXT: .long 0 # Padding
+; X86-NEXT: .long 0 # Offset of padding
+; X86-NEXT: .long 0 # Bytes of callee saved registers
+; X86-NEXT: .long 0 # Exception handler offset
+; X86-NEXT: .short 0 # Exception handler section
+; X86-NEXT: .long 0 # Flags (defines frame register)
+; X86-NEXT: [[FPROC_END]]:
; X86-NEXT: .short 2
; X86-NEXT: .short 4431
; X86-NEXT: [[COMPILE_END]]:
@@ -354,6 +387,17 @@
; X64-NEXT: .byte 0
; X64-NEXT: .asciz "x"
; X64-NEXT: [[PROC_SEGMENT_END]]:
+; X64-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X64-NEXT: [[FPROC_BEG]]:
+; X64-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X64-NEXT: .long 40 # FrameSize
+; X64-NEXT: .long 0 # Padding
+; X64-NEXT: .long 0 # Offset of padding
+; X64-NEXT: .long 0 # Bytes of callee saved registers
+; X64-NEXT: .long 0 # Exception handler offset
+; X64-NEXT: .short 0 # Exception handler section
+; X64-NEXT: .long 81920 # Flags (defines frame register)
+; X64-NEXT: [[FPROC_END]]:
; X64-NEXT: .short 2
; X64-NEXT: .short 4431
; X64-NEXT: [[F1_END]]:
@@ -379,6 +423,17 @@
; X64-NEXT: .byte 0
; X64-NEXT: .asciz "y"
; X64-NEXT: [[PROC_SEGMENT_END]]:
+; X64-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X64-NEXT: [[FPROC_BEG]]:
+; X64-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X64-NEXT: .long 40 # FrameSize
+; X64-NEXT: .long 0 # Padding
+; X64-NEXT: .long 0 # Offset of padding
+; X64-NEXT: .long 0 # Bytes of callee saved registers
+; X64-NEXT: .long 0 # Exception handler offset
+; X64-NEXT: .short 0 # Exception handler section
+; X64-NEXT: .long 81920 # Flags (defines frame register)
+; X64-NEXT: [[FPROC_END]]:
; X64-NEXT: .short 2
; X64-NEXT: .short 4431
; X64-NEXT: [[COMPILE_END]]:
@@ -404,6 +459,17 @@
; X64-NEXT: .byte 0
; X64-NEXT: .asciz "f"
; X64-NEXT: [[PROC_SEGMENT_END]]:
+; X64-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X64-NEXT: [[FPROC_BEG]]:
+; X64-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X64-NEXT: .long 40 # FrameSize
+; X64-NEXT: .long 0 # Padding
+; X64-NEXT: .long 0 # Offset of padding
+; X64-NEXT: .long 0 # Bytes of callee saved registers
+; X64-NEXT: .long 0 # Exception handler offset
+; X64-NEXT: .short 0 # Exception handler section
+; X64-NEXT: .long 81920 # Flags (defines frame register)
+; X64-NEXT: [[FPROC_END]]:
; X64-NEXT: .short 2
; X64-NEXT: .short 4431
; X64-NEXT: [[COMPILE_END]]:
@@ -422,16 +488,16 @@
; OBJ64: Relocations [
; OBJ64-NEXT: 0x64 IMAGE_REL_AMD64_SECREL x
; OBJ64-NEXT: 0x68 IMAGE_REL_AMD64_SECTION x
-; OBJ64-NEXT: 0x7C IMAGE_REL_AMD64_SECREL x
-; OBJ64-NEXT: 0x80 IMAGE_REL_AMD64_SECTION x
-; OBJ64-NEXT: 0xE0 IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT: 0xE4 IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT: 0xF8 IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT: 0xFC IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT: 0x15C IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT: 0x160 IMAGE_REL_AMD64_SECTION f
-; OBJ64-NEXT: 0x174 IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT: 0x178 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT: 0x98 IMAGE_REL_AMD64_SECREL x
+; OBJ64-NEXT: 0x9C IMAGE_REL_AMD64_SECTION x
+; OBJ64-NEXT: 0xFC IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT: 0x100 IMAGE_REL_AMD64_SECTION y
+; OBJ64-NEXT: 0x130 IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT: 0x134 IMAGE_REL_AMD64_SECTION y
+; OBJ64-NEXT: 0x194 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT: 0x198 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT: 0x1C8 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT: 0x1CC IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
diff --git a/llvm/test/DebugInfo/COFF/pieces.ll b/llvm/test/DebugInfo/COFF/pieces.ll
index ab3794dd0b7..10a81e17d92 100644
--- a/llvm/test/DebugInfo/COFF/pieces.ll
+++ b/llvm/test/DebugInfo/COFF/pieces.ll
@@ -108,7 +108,7 @@
; ASM: .cv_def_range [[oy_start]] [[oy_end]], "C\021\027\000\000\000\004\000\000\000"
-; OBJ-LABEL: {{.*}}Proc{{.*}}Sym {
+; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
; OBJ: DisplayName: loop_csr
; OBJ: }
@@ -138,7 +138,7 @@
; ASM: .asciz "o"
; ASM: .cv_def_range .Lfunc_begin1 .Ltmp8, "C\021\021\000\000\000\004\000\000\000"
-; OBJ-LABEL: {{.*}}Proc{{.*}}Sym {
+; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
; OBJ: DisplayName: pad_right
; OBJ: }
@@ -161,7 +161,7 @@
; ASM: .asciz "o"
; ASM: .cv_def_range .Lfunc_begin2 .Ltmp10, "C\021\021\000\000\000\000\000\000\000"
-; OBJ-LABEL: {{.*}}Proc{{.*}}Sym {
+; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
; OBJ: DisplayName: pad_left
; OBJ: }
@@ -187,7 +187,7 @@
; ASM: .asciz "p"
; ASM: .cv_def_range [[p_start]] .Lfunc_end3, "C\021\021\000\000\000\004\000\000\000"
-; OBJ-LABEL: {{.*}}Proc{{.*}}Sym {
+; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
; OBJ: DisplayName: nested
; OBJ: }
@@ -223,7 +223,7 @@
; ASM: .asciz "o"
; ASM: .cv_def_range [[spill_o_x_start]] [[spill_o_x_end]], "E\021O\001A\000$\000\000\000"
-; OBJ-LABEL: {{.*}}Proc{{.*}}Sym {
+; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
; OBJ: DisplayName: bitpiece_spill
; OBJ: }
diff --git a/llvm/test/DebugInfo/COFF/simple.ll b/llvm/test/DebugInfo/COFF/simple.ll
index 175be1ab424..3c495a33b8a 100644
--- a/llvm/test/DebugInfo/COFF/simple.ll
+++ b/llvm/test/DebugInfo/COFF/simple.ll
@@ -59,6 +59,17 @@
; X86-NEXT: .byte 0
; X86-NEXT: .asciz "f"
; X86-NEXT: [[PROC_SEGMENT_END]]:
+; X86-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X86-NEXT: [[FPROC_BEG]]:
+; X86-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X86-NEXT: .long 0 # FrameSize
+; X86-NEXT: .long 0 # Padding
+; X86-NEXT: .long 0 # Offset of padding
+; X86-NEXT: .long 0 # Bytes of callee saved registers
+; X86-NEXT: .long 0 # Exception handler offset
+; X86-NEXT: .short 0 # Exception handler section
+; X86-NEXT: .long 0 # Flags (defines frame register)
+; X86-NEXT: [[FPROC_END]]:
; X86-NEXT: .short 2
; X86-NEXT: .short 4431
; X86-NEXT: [[F1_END]]:
@@ -78,8 +89,8 @@
; OBJ32-NEXT: 0x44 IMAGE_REL_I386_DIR32NB _f
; OBJ32-NEXT: 0x90 IMAGE_REL_I386_SECREL _f
; OBJ32-NEXT: 0x94 IMAGE_REL_I386_SECTION _f
-; OBJ32-NEXT: 0xA8 IMAGE_REL_I386_SECREL _f
-; OBJ32-NEXT: 0xAC IMAGE_REL_I386_SECTION _f
+; OBJ32-NEXT: 0xC4 IMAGE_REL_I386_SECREL _f
+; OBJ32-NEXT: 0xC8 IMAGE_REL_I386_SECTION _f
; OBJ32-NEXT: ]
; OBJ32: Subsection [
; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
@@ -95,7 +106,7 @@
; OBJ32: DisplayName: f
; OBJ32: LinkageName: _f
; OBJ32: }
-; OBJ32-NEXT: ProcEnd {
+; OBJ32: ProcEnd {
; OBJ32: }
; OBJ32-NEXT: ]
; OBJ32: Subsection [
@@ -174,6 +185,17 @@
; X64-NEXT: .byte 0
; X64-NEXT: .asciz "f"
; X64-NEXT: [[PROC_SEGMENT_END]]:
+; X64-NEXT: .short [[FPROC_END:[^ ]*]]-[[FPROC_BEG:[^ ]*]] # Record length
+; X64-NEXT: [[FPROC_BEG]]:
+; X64-NEXT: .short 4114 # Record kind: S_FRAMEPROC
+; X64-NEXT: .long 40 # FrameSize
+; X64-NEXT: .long 0 # Padding
+; X64-NEXT: .long 0 # Offset of padding
+; X64-NEXT: .long 0 # Bytes of callee saved registers
+; X64-NEXT: .long 0 # Exception handler offset
+; X64-NEXT: .short 0 # Exception handler section
+; X64-NEXT: .long 81920 # Flags (defines frame register)
+; X64-NEXT: [[FPROC_END]]:
; X64-NEXT: .short 2
; X64-NEXT: .short 4431
; X64-NEXT: [[F1_END]]:
@@ -192,8 +214,8 @@
; OBJ64: Relocations [
; OBJ64-NEXT: 0x64 IMAGE_REL_AMD64_SECREL f
; OBJ64-NEXT: 0x68 IMAGE_REL_AMD64_SECTION f
-; OBJ64-NEXT: 0x7C IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT: 0x80 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT: 0x98 IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT: 0x9C IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
@@ -202,7 +224,7 @@
; OBJ64: DisplayName: f
; OBJ64: LinkageName: f
; OBJ64: }
-; OBJ64-NEXT: ProcEnd {
+; OBJ64: ProcEnd {
; OBJ64: }
; OBJ64-NEXT: ]
; OBJ64: Subsection [
diff --git a/llvm/test/DebugInfo/COFF/types-array.ll b/llvm/test/DebugInfo/COFF/types-array.ll
index 10ae42653fa..16298dafbd4 100644
--- a/llvm/test/DebugInfo/COFF/types-array.ll
+++ b/llvm/test/DebugInfo/COFF/types-array.ll
@@ -67,11 +67,8 @@
; CHECK: ]
; CHECK: VarName: a
; CHECK: }
-; CHECK: DefRangeRegisterRelSym {
-; CHECK: BaseRegister: EBP (0x16)
-; CHECK: HasSpilledUDTMember: No
-; CHECK: OffsetInParent: 0
-; CHECK: BasePointerOffset: -20
+; CHECK: DefRangeFramePointerRelSym {
+; CHECK: Offset: -20
; CHECK: LocalVariableAddrRange {
; CHECK: OffsetStart: .text+0x6
; CHECK: ISectStart: 0x0
diff --git a/llvm/test/DebugInfo/COFF/vframe-fpo.ll b/llvm/test/DebugInfo/COFF/vframe-fpo.ll
new file mode 100644
index 00000000000..b3b71530214
--- /dev/null
+++ b/llvm/test/DebugInfo/COFF/vframe-fpo.ll
@@ -0,0 +1,264 @@
+; RUN: llc < %s | FileCheck %s --check-prefix=ASM
+; RUN: llc < %s -filetype=obj | llvm-readobj -codeview | FileCheck %s --check-prefix=CODEVIEW
+
+; This test checks that for 32-bit x86 we use VFRAME and
+; S_DEFRANGE_FRAMEPOINTER_REL with the right offsets. The test has two function
+; calls with different stack depths, which makes it impossible to correctly
+; describe locals in memory as being ESP-relative.
+
+; The following source can be used with a debugger to check that locals are
+; displayed correctly:
+; $ cat fpo.cpp
+; #if 0
+; void __attribute__((optnone)) __declspec(noinline) f(int &a, int &b) {
+; __debugbreak();
+; a += b;
+; }
+; void __attribute__((optnone)) __declspec(noinline) g(int &a, int &b, int &c) {
+; __debugbreak();
+; a += b;
+; a += c;
+; }
+; #endif
+; void f(int &a, int &b);
+; void g(int &a, int &b, int &c);
+; int main() {
+; int a = 1;
+; int b = 2;
+; int c = 3;
+; f(a, b);
+; g(a, b, c);
+; return a + b + c;
+; }
+; $ clang -S -g -gcodeview t.cpp -emit-llvm -o vframe-fpo.ll -Os
+
+; ASM-LABEL: _main:
+; ASM: # %bb.0: # %entry
+; ASM-NEXT: pushl %ebx
+; ASM-NEXT: .cv_fpo_pushreg %ebx
+; ASM-NEXT: pushl %edi
+; ASM-NEXT: .cv_fpo_pushreg %edi
+; ASM-NEXT: pushl %esi
+; ASM-NEXT: .cv_fpo_pushreg %esi
+; ASM-NEXT: subl $12, %esp
+; ASM-NEXT: .cv_fpo_stackalloc 12
+; ASM-NEXT: .cv_fpo_endprologue
+
+; Store locals.
+; ASM: movl $1, {{.*}}
+; ASM: movl $2, {{.*}}
+; ASM: movl $3, {{.*}}
+
+; ASM that store-to-push conversion fires.
+; ASM: pushl
+; ASM-NEXT: pushl
+; ASM-NEXT: calll "?f@@YAXAAH0@Z"
+; ASM-NEXT: addl $8, %esp
+; ASM: pushl
+; ASM-NEXT: pushl
+; ASM-NEXT: pushl
+; ASM-NEXT: calll "?g@@YAXAAH00@Z"
+
+; CODEVIEW: CodeViewDebugInfo [
+; CODEVIEW-NEXT: Section: .debug$S (4)
+; CODEVIEW-NEXT: Magic: 0x4
+; CODEVIEW-NEXT: Subsection [
+; CODEVIEW-NEXT: SubSectionType: Symbols (0xF1)
+; CODEVIEW-NEXT: SubSectionSize: 0x2F
+; CODEVIEW-NEXT: Compile3Sym {
+; CODEVIEW-NEXT: Kind: S_COMPILE3 (0x113C)
+; CODEVIEW: }
+; CODEVIEW: ]
+; CODEVIEW: Subsection [
+; CODEVIEW-NEXT: SubSectionType: FrameData (0xF5)
+; CODEVIEW-NEXT: SubSectionSize: 0xA4
+; CODEVIEW-NEXT: LinkageName: _main
+; CODEVIEW: FrameData {
+; CODEVIEW: }
+; CODEVIEW: FrameData {
+; CODEVIEW: }
+; CODEVIEW: FrameData {
+; CODEVIEW: }
+; CODEVIEW: FrameData {
+; CODEVIEW: }
+; CODEVIEW: FrameData {
+; CODEVIEW-NEXT: RvaStart:
+; CODEVIEW-NEXT: CodeSize:
+; CODEVIEW-NEXT: LocalSize: 0xC
+; CODEVIEW-NEXT: ParamsSize: 0x0
+; CODEVIEW-NEXT: MaxStackSize: 0x0
+; CODEVIEW-NEXT: PrologSize:
+; CODEVIEW-NEXT: SavedRegsSize: 0xC
+; CODEVIEW-NEXT: Flags [ (0x0)
+; CODEVIEW-NEXT: ]
+
+; $T0 is the CFA, the address of the return address, and our defranges are
+; relative to it.
+; CODEVIEW-NEXT: FrameFunc [
+; CODEVIEW-NEXT: $T0 .raSearch =
+; CODEVIEW-NEXT: $eip $T0 ^ =
+; CODEVIEW-NEXT: $esp $T0 4 + =
+; CODEVIEW-NEXT: $ebx $T0 4 - ^ =
+; CODEVIEW-NEXT: $edi $T0 8 - ^ =
+; CODEVIEW-NEXT: $esi $T0 12 - ^ =
+; CODEVIEW-NEXT: ]
+; CODEVIEW-NEXT: }
+
+; We push 16 bytes in the prologue, so our local variables are at offsets -16,
+; -20, and -24.
+
+; CODEVIEW: Subsection [
+; CODEVIEW-NEXT: SubSectionType: Symbols (0xF1)
+; CODEVIEW-NEXT: SubSectionSize: 0xA2
+; CODEVIEW-NEXT: GlobalProcIdSym {
+; CODEVIEW-NEXT: Kind: S_GPROC32_ID (0x1147)
+; CODEVIEW: DisplayName: main
+; CODEVIEW: LinkageName: _main
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: FrameProcSym {
+; CODEVIEW-NEXT: Kind: S_FRAMEPROC (0x1012)
+; CODEVIEW-NEXT: TotalFrameBytes: 0xC
+; CODEVIEW-NEXT: PaddingFrameBytes: 0x0
+; CODEVIEW-NEXT: OffsetToPadding: 0x0
+; CODEVIEW-NEXT: BytesOfCalleeSavedRegisters: 0xC
+; CODEVIEW-NEXT: OffsetOfExceptionHandler: 0x0
+; CODEVIEW-NEXT: SectionIdOfExceptionHandler: 0x0
+; CODEVIEW-NEXT: Flags [ (0x14000)
+; CODEVIEW-NEXT: ]
+; CODEVIEW-NEXT: LocalFramePtrReg: VFRAME (0x7536)
+; CODEVIEW-NEXT: ParamFramePtrReg: VFRAME (0x7536)
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: LocalSym {
+; CODEVIEW-NEXT: Kind: S_LOCAL (0x113E)
+; CODEVIEW: VarName: a
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: DefRangeFramePointerRelSym {
+; CODEVIEW-NEXT: Kind: S_DEFRANGE_FRAMEPOINTER_REL (0x1142)
+; CODEVIEW-NEXT: Offset: -16
+; CODEVIEW-NEXT: LocalVariableAddrRange {
+; CODEVIEW-NEXT: OffsetStart:
+; CODEVIEW-NEXT: ISectStart:
+; CODEVIEW-NEXT: Range:
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: LocalSym {
+; CODEVIEW-NEXT: Kind: S_LOCAL (0x113E)
+; CODEVIEW: VarName: b
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: DefRangeFramePointerRelSym {
+; CODEVIEW-NEXT: Kind: S_DEFRANGE_FRAMEPOINTER_REL (0x1142)
+; CODEVIEW-NEXT: Offset: -20
+; CODEVIEW-NEXT: LocalVariableAddrRange {
+; CODEVIEW-NEXT: OffsetStart:
+; CODEVIEW-NEXT: ISectStart:
+; CODEVIEW-NEXT: Range:
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: LocalSym {
+; CODEVIEW-NEXT: Kind: S_LOCAL (0x113E)
+; CODEVIEW: VarName: c
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: DefRangeFramePointerRelSym {
+; CODEVIEW-NEXT: Kind: S_DEFRANGE_FRAMEPOINTER_REL (0x1142)
+; CODEVIEW-NEXT: Offset: -24
+; CODEVIEW-NEXT: LocalVariableAddrRange {
+; CODEVIEW-NEXT: OffsetStart:
+; CODEVIEW-NEXT: ISectStart:
+; CODEVIEW-NEXT: Range:
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: ProcEnd {
+; CODEVIEW-NEXT: Kind: S_PROC_ID_END (0x114F)
+; CODEVIEW-NEXT: }
+; CODEVIEW-NEXT: ]
+
+
+; ModuleID = 'fpo.cpp'
+source_filename = "fpo.cpp"
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i386-pc-windows-msvc19.14.26433"
+
+; Function Attrs: norecurse optsize
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !8 {
+entry:
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %c = alloca i32, align 4
+ %0 = bitcast i32* %a to i8*, !dbg !16
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #4, !dbg !16
+ call void @llvm.dbg.declare(metadata i32* %a, metadata !13, metadata !DIExpression()), !dbg !16
+ store i32 1, i32* %a, align 4, !dbg !16, !tbaa !17
+ %1 = bitcast i32* %b to i8*, !dbg !21
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %1) #4, !dbg !21
+ call void @llvm.dbg.declare(metadata i32* %b, metadata !14, metadata !DIExpression()), !dbg !21
+ store i32 2, i32* %b, align 4, !dbg !21, !tbaa !17
+ %2 = bitcast i32* %c to i8*, !dbg !22
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %2) #4, !dbg !22
+ call void @llvm.dbg.declare(metadata i32* %c, metadata !15, metadata !DIExpression()), !dbg !22
+ store i32 3, i32* %c, align 4, !dbg !22, !tbaa !17
+ call void @"?f@@YAXAAH0@Z"(i32* nonnull dereferenceable(4) %a, i32* nonnull dereferenceable(4) %b) #5, !dbg !23
+ call void @"?g@@YAXAAH00@Z"(i32* nonnull dereferenceable(4) %a, i32* nonnull dereferenceable(4) %b, i32* nonnull dereferenceable(4) %c) #5, !dbg !24
+ %3 = load i32, i32* %a, align 4, !dbg !25, !tbaa !17
+ %4 = load i32, i32* %b, align 4, !dbg !25, !tbaa !17
+ %add = add nsw i32 %4, %3, !dbg !25
+ %5 = load i32, i32* %c, align 4, !dbg !25, !tbaa !17
+ %add1 = add nsw i32 %add, %5, !dbg !25
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %2) #4, !dbg !26
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %1) #4, !dbg !26
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #4, !dbg !26
+ ret i32 %add1, !dbg !25
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+
+; Function Attrs: optsize
+declare dso_local void @"?f@@YAXAAH0@Z"(i32* dereferenceable(4), i32* dereferenceable(4)) local_unnamed_addr #3
+
+; Function Attrs: optsize
+declare dso_local void @"?g@@YAXAAH00@Z"(i32* dereferenceable(4), i32* dereferenceable(4), i32* dereferenceable(4)) local_unnamed_addr #3
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+attributes #0 = { norecurse optsize "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { argmemonly nounwind }
+attributes #2 = { nounwind readnone speculatable }
+attributes #3 = { optsize "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #4 = { nounwind }
+attributes #5 = { optsize }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "fpo.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "d0bb7e43f4e54936a94da008319a7de3")
+!2 = !{}
+!3 = !{i32 1, !"NumRegisterParameters", i32 0}
+!4 = !{i32 2, !"CodeView", i32 1}
+!5 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{i32 1, !"wchar_size", i32 2}
+!7 = !{!"clang version 8.0.0 "}
+!8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !9, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !12)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{!13, !14, !15}
+!13 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 15, type: !11)
+!14 = !DILocalVariable(name: "b", scope: !8, file: !1, line: 16, type: !11)
+!15 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 17, type: !11)
+!16 = !DILocation(line: 15, scope: !8)
+!17 = !{!18, !18, i64 0}
+!18 = !{!"int", !19, i64 0}
+!19 = !{!"omnipotent char", !20, i64 0}
+!20 = !{!"Simple C++ TBAA"}
+!21 = !DILocation(line: 16, scope: !8)
+!22 = !DILocation(line: 17, scope: !8)
+!23 = !DILocation(line: 18, scope: !8)
+!24 = !DILocation(line: 19, scope: !8)
+!25 = !DILocation(line: 20, scope: !8)
+!26 = !DILocation(line: 21, scope: !8)
OpenPOWER on IntegriCloud