diff options
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/DebugInfo/COFF/asan-module-ctor.ll | 2 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/fpo-argsize.ll | 454 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/fpo-csrs.ll | 559 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/fpo-realign-alloca.ll | 110 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/fpo-shrink-wrap.ll | 154 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/fpo-stack-protect.ll | 114 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/multifunction.ll | 16 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/COFF/simple.ll | 17 | ||||
| -rw-r--r-- | llvm/test/MC/COFF/cv-fpo-csrs.s | 141 | ||||
| -rw-r--r-- | llvm/test/MC/COFF/cv-fpo-errors.s | 47 | ||||
| -rw-r--r-- | llvm/test/MC/COFF/cv-fpo-setframe.s | 144 |
11 files changed, 1753 insertions, 5 deletions
diff --git a/llvm/test/DebugInfo/COFF/asan-module-ctor.ll b/llvm/test/DebugInfo/COFF/asan-module-ctor.ll index ec495647a89..31e68adfb56 100644 --- a/llvm/test/DebugInfo/COFF/asan-module-ctor.ll +++ b/llvm/test/DebugInfo/COFF/asan-module-ctor.ll @@ -10,7 +10,7 @@ ; The module ctor has no debug info. All we have to do is don't crash. ; X86: _asan.module_ctor: ; X86-NEXT: L{{.*}}: -; X86-NEXT: # BB +; X86: # BB ; X86-NEXT: calll ___asan_init_v3 ; X86-NEXT: retl diff --git a/llvm/test/DebugInfo/COFF/fpo-argsize.ll b/llvm/test/DebugInfo/COFF/fpo-argsize.ll new file mode 100644 index 00000000000..53b2e5d34b5 --- /dev/null +++ b/llvm/test/DebugInfo/COFF/fpo-argsize.ll @@ -0,0 +1,454 @@ +; RUN: llc < %s | grep cv_fpo_proc | FileCheck %s + +; C++ source: +; extern "C" { +; extern int g; +; +; void cdecl1(int a) { g += a; } +; void cdecl2(int a, int b) { g += a + b; } +; void cdecl3(int a, int b, int c) { g += a + b + c; } +; +; void __fastcall fastcall1(int a) { g += a; } +; void __fastcall fastcall2(int a, int b) { g += a + b; } +; void __fastcall fastcall3(int a, int b, int c) { g += a + b + c; } +; +; void __stdcall stdcall1(int a) { g += a; } +; void __stdcall stdcall2(int a, int b) { g += a + b; } +; void __stdcall stdcall3(int a, int b, int c) { g += a + b + c; } +; } +; +; struct Foo { +; void thiscall1(int a); +; void thiscall2(int a, int b); +; void thiscall3(int a, int b, int c); +; }; +; +; void Foo::thiscall1(int a) { g += a; } +; void Foo::thiscall2(int a, int b) { g += a + b; } +; void Foo::thiscall3(int a, int b, int c) { g += a + b + c; } + +; CHECK: .cv_fpo_proc _cdecl1 4 +; CHECK: .cv_fpo_proc _cdecl2 8 +; CHECK: .cv_fpo_proc _cdecl3 12 + +; First two args are in registers and don't count. +; CHECK: .cv_fpo_proc @fastcall1@4 0 +; CHECK: .cv_fpo_proc @fastcall2@8 0 +; CHECK: .cv_fpo_proc @fastcall3@12 4 + +; CHECK: .cv_fpo_proc _stdcall1@4 4 +; CHECK: .cv_fpo_proc _stdcall2@8 8 +; CHECK: .cv_fpo_proc _stdcall3@12 12 + +; 'this' is in ecx and doesn't count. +; CHECK: .cv_fpo_proc "?thiscall1@Foo@@QAEXH@Z" 4 +; CHECK: .cv_fpo_proc "?thiscall2@Foo@@QAEXHH@Z" 8 +; CHECK: .cv_fpo_proc "?thiscall3@Foo@@QAEXHHH@Z" 12 + +; ModuleID = 't.c' +source_filename = "t.c" +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.11.25508" + +%struct.Foo = type { i8 } + +@g = external global i32, align 4 + +; Function Attrs: noinline nounwind optnone +define void @cdecl1(i32 %a) #0 !dbg !8 { +entry: + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !12, metadata !DIExpression()), !dbg !13 + %0 = load i32, i32* %a.addr, align 4, !dbg !14 + %1 = load i32, i32* @g, align 4, !dbg !15 + %add = add nsw i32 %1, %0, !dbg !15 + store i32 %add, i32* @g, align 4, !dbg !15 + ret void, !dbg !16 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind optnone +define void @cdecl2(i32 %a, i32 %b) #0 !dbg !17 { +entry: + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !20, metadata !DIExpression()), !dbg !21 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !22, metadata !DIExpression()), !dbg !23 + %0 = load i32, i32* %a.addr, align 4, !dbg !24 + %1 = load i32, i32* %b.addr, align 4, !dbg !25 + %add = add nsw i32 %0, %1, !dbg !26 + %2 = load i32, i32* @g, align 4, !dbg !27 + %add1 = add nsw i32 %2, %add, !dbg !27 + store i32 %add1, i32* @g, align 4, !dbg !27 + ret void, !dbg !28 +} + +; Function Attrs: noinline nounwind optnone +define void @cdecl3(i32 %a, i32 %b, i32 %c) #0 !dbg !29 { +entry: + %c.addr = alloca i32, align 4 + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %c, i32* %c.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %c.addr, metadata !32, metadata !DIExpression()), !dbg !33 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !34, metadata !DIExpression()), !dbg !35 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !36, metadata !DIExpression()), !dbg !37 + %0 = load i32, i32* %a.addr, align 4, !dbg !38 + %1 = load i32, i32* %b.addr, align 4, !dbg !39 + %add = add nsw i32 %0, %1, !dbg !40 + %2 = load i32, i32* %c.addr, align 4, !dbg !41 + %add1 = add nsw i32 %add, %2, !dbg !42 + %3 = load i32, i32* @g, align 4, !dbg !43 + %add2 = add nsw i32 %3, %add1, !dbg !43 + store i32 %add2, i32* @g, align 4, !dbg !43 + ret void, !dbg !44 +} + +; Function Attrs: noinline nounwind optnone +define x86_fastcallcc void @"\01@fastcall1@4"(i32 inreg %a) #0 !dbg !45 { +entry: + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !47, metadata !DIExpression()), !dbg !48 + %0 = load i32, i32* %a.addr, align 4, !dbg !49 + %1 = load i32, i32* @g, align 4, !dbg !50 + %add = add nsw i32 %1, %0, !dbg !50 + store i32 %add, i32* @g, align 4, !dbg !50 + ret void, !dbg !51 +} + +; Function Attrs: noinline nounwind optnone +define x86_fastcallcc void @"\01@fastcall2@8"(i32 inreg %a, i32 inreg %b) #0 !dbg !52 { +entry: + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !54, metadata !DIExpression()), !dbg !55 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !56, metadata !DIExpression()), !dbg !57 + %0 = load i32, i32* %a.addr, align 4, !dbg !58 + %1 = load i32, i32* %b.addr, align 4, !dbg !59 + %add = add nsw i32 %0, %1, !dbg !60 + %2 = load i32, i32* @g, align 4, !dbg !61 + %add1 = add nsw i32 %2, %add, !dbg !61 + store i32 %add1, i32* @g, align 4, !dbg !61 + ret void, !dbg !62 +} + +; Function Attrs: noinline nounwind optnone +define x86_fastcallcc void @"\01@fastcall3@12"(i32 inreg %a, i32 inreg %b, i32 %c) #0 !dbg !63 { +entry: + %c.addr = alloca i32, align 4 + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %c, i32* %c.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %c.addr, metadata !65, metadata !DIExpression()), !dbg !66 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !67, metadata !DIExpression()), !dbg !68 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !69, metadata !DIExpression()), !dbg !70 + %0 = load i32, i32* %a.addr, align 4, !dbg !71 + %1 = load i32, i32* %b.addr, align 4, !dbg !72 + %add = add nsw i32 %0, %1, !dbg !73 + %2 = load i32, i32* %c.addr, align 4, !dbg !74 + %add1 = add nsw i32 %add, %2, !dbg !75 + %3 = load i32, i32* @g, align 4, !dbg !76 + %add2 = add nsw i32 %3, %add1, !dbg !76 + store i32 %add2, i32* @g, align 4, !dbg !76 + ret void, !dbg !77 +} + +; Function Attrs: noinline nounwind optnone +define x86_stdcallcc void @"\01_stdcall1@4"(i32 %a) #0 !dbg !78 { +entry: + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !80, metadata !DIExpression()), !dbg !81 + %0 = load i32, i32* %a.addr, align 4, !dbg !82 + %1 = load i32, i32* @g, align 4, !dbg !83 + %add = add nsw i32 %1, %0, !dbg !83 + store i32 %add, i32* @g, align 4, !dbg !83 + ret void, !dbg !84 +} + +; Function Attrs: noinline nounwind optnone +define x86_stdcallcc void @"\01_stdcall2@8"(i32 %a, i32 %b) #0 !dbg !85 { +entry: + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !87, metadata !DIExpression()), !dbg !88 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !89, metadata !DIExpression()), !dbg !90 + %0 = load i32, i32* %a.addr, align 4, !dbg !91 + %1 = load i32, i32* %b.addr, align 4, !dbg !92 + %add = add nsw i32 %0, %1, !dbg !93 + %2 = load i32, i32* @g, align 4, !dbg !94 + %add1 = add nsw i32 %2, %add, !dbg !94 + store i32 %add1, i32* @g, align 4, !dbg !94 + ret void, !dbg !95 +} + +; Function Attrs: noinline nounwind optnone +define x86_stdcallcc void @"\01_stdcall3@12"(i32 %a, i32 %b, i32 %c) #0 !dbg !96 { +entry: + %c.addr = alloca i32, align 4 + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + store i32 %c, i32* %c.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %c.addr, metadata !98, metadata !DIExpression()), !dbg !99 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !100, metadata !DIExpression()), !dbg !101 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !102, metadata !DIExpression()), !dbg !103 + %0 = load i32, i32* %a.addr, align 4, !dbg !104 + %1 = load i32, i32* %b.addr, align 4, !dbg !105 + %add = add nsw i32 %0, %1, !dbg !106 + %2 = load i32, i32* %c.addr, align 4, !dbg !107 + %add1 = add nsw i32 %add, %2, !dbg !108 + %3 = load i32, i32* @g, align 4, !dbg !109 + %add2 = add nsw i32 %3, %add1, !dbg !109 + store i32 %add2, i32* @g, align 4, !dbg !109 + ret void, !dbg !110 +} + +; Function Attrs: noinline nounwind optnone +define x86_thiscallcc void @"\01?thiscall1@Foo@@QAEXH@Z"(%struct.Foo* %this, i32 %a) #0 align 2 !dbg !111 { +entry: + %a.addr = alloca i32, align 4 + %this.addr = alloca %struct.Foo*, align 4 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !124, metadata !DIExpression()), !dbg !125 + store %struct.Foo* %this, %struct.Foo** %this.addr, align 4 + call void @llvm.dbg.declare(metadata %struct.Foo** %this.addr, metadata !126, metadata !DIExpression()), !dbg !128 + %this1 = load %struct.Foo*, %struct.Foo** %this.addr, align 4 + %0 = load i32, i32* %a.addr, align 4, !dbg !129 + %1 = load i32, i32* @g, align 4, !dbg !130 + %add = add nsw i32 %1, %0, !dbg !130 + store i32 %add, i32* @g, align 4, !dbg !130 + ret void, !dbg !131 +} + +; Function Attrs: noinline nounwind optnone +define x86_thiscallcc void @"\01?thiscall2@Foo@@QAEXHH@Z"(%struct.Foo* %this, i32 %a, i32 %b) #0 align 2 !dbg !132 { +entry: + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + %this.addr = alloca %struct.Foo*, align 4 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !133, metadata !DIExpression()), !dbg !134 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !135, metadata !DIExpression()), !dbg !136 + store %struct.Foo* %this, %struct.Foo** %this.addr, align 4 + call void @llvm.dbg.declare(metadata %struct.Foo** %this.addr, metadata !137, metadata !DIExpression()), !dbg !138 + %this1 = load %struct.Foo*, %struct.Foo** %this.addr, align 4 + %0 = load i32, i32* %a.addr, align 4, !dbg !139 + %1 = load i32, i32* %b.addr, align 4, !dbg !140 + %add = add nsw i32 %0, %1, !dbg !141 + %2 = load i32, i32* @g, align 4, !dbg !142 + %add2 = add nsw i32 %2, %add, !dbg !142 + store i32 %add2, i32* @g, align 4, !dbg !142 + ret void, !dbg !143 +} + +; Function Attrs: noinline nounwind optnone +define x86_thiscallcc void @"\01?thiscall3@Foo@@QAEXHHH@Z"(%struct.Foo* %this, i32 %a, i32 %b, i32 %c) #0 align 2 !dbg !144 { +entry: + %c.addr = alloca i32, align 4 + %b.addr = alloca i32, align 4 + %a.addr = alloca i32, align 4 + %this.addr = alloca %struct.Foo*, align 4 + store i32 %c, i32* %c.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %c.addr, metadata !145, metadata !DIExpression()), !dbg !146 + store i32 %b, i32* %b.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %b.addr, metadata !147, metadata !DIExpression()), !dbg !148 + store i32 %a, i32* %a.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %a.addr, metadata !149, metadata !DIExpression()), !dbg !150 + store %struct.Foo* %this, %struct.Foo** %this.addr, align 4 + call void @llvm.dbg.declare(metadata %struct.Foo** %this.addr, metadata !151, metadata !DIExpression()), !dbg !152 + %this1 = load %struct.Foo*, %struct.Foo** %this.addr, align 4 + %0 = load i32, i32* %a.addr, align 4, !dbg !153 + %1 = load i32, i32* %b.addr, align 4, !dbg !154 + %add = add nsw i32 %0, %1, !dbg !155 + %2 = load i32, i32* %c.addr, align 4, !dbg !156 + %add2 = add nsw i32 %add, %2, !dbg !157 + %3 = load i32, i32* @g, align 4, !dbg !158 + %add3 = add nsw i32 %3, %add2, !dbg !158 + store i32 %add3, i32* @g, align 4, !dbg !158 + ret void, !dbg !159 +} + +attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "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 } + +!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 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "0ce3e4edcf2f8511157da4edb99fcdf4") +!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 6.0.0 "} +!8 = distinct !DISubprogram(name: "cdecl1", scope: !1, file: !1, line: 4, type: !9, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!9 = !DISubroutineType(types: !10) +!10 = !{null, !11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 4, type: !11) +!13 = !DILocation(line: 4, column: 17, scope: !8) +!14 = !DILocation(line: 4, column: 27, scope: !8) +!15 = !DILocation(line: 4, column: 24, scope: !8) +!16 = !DILocation(line: 4, column: 30, scope: !8) +!17 = distinct !DISubprogram(name: "cdecl2", scope: !1, file: !1, line: 5, type: !18, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!18 = !DISubroutineType(types: !19) +!19 = !{null, !11, !11} +!20 = !DILocalVariable(name: "b", arg: 2, scope: !17, file: !1, line: 5, type: !11) +!21 = !DILocation(line: 5, column: 24, scope: !17) +!22 = !DILocalVariable(name: "a", arg: 1, scope: !17, file: !1, line: 5, type: !11) +!23 = !DILocation(line: 5, column: 17, scope: !17) +!24 = !DILocation(line: 5, column: 34, scope: !17) +!25 = !DILocation(line: 5, column: 38, scope: !17) +!26 = !DILocation(line: 5, column: 36, scope: !17) +!27 = !DILocation(line: 5, column: 31, scope: !17) +!28 = !DILocation(line: 5, column: 41, scope: !17) +!29 = distinct !DISubprogram(name: "cdecl3", scope: !1, file: !1, line: 6, type: !30, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!30 = !DISubroutineType(types: !31) +!31 = !{null, !11, !11, !11} +!32 = !DILocalVariable(name: "c", arg: 3, scope: !29, file: !1, line: 6, type: !11) +!33 = !DILocation(line: 6, column: 31, scope: !29) +!34 = !DILocalVariable(name: "b", arg: 2, scope: !29, file: !1, line: 6, type: !11) +!35 = !DILocation(line: 6, column: 24, scope: !29) +!36 = !DILocalVariable(name: "a", arg: 1, scope: !29, file: !1, line: 6, type: !11) +!37 = !DILocation(line: 6, column: 17, scope: !29) +!38 = !DILocation(line: 6, column: 41, scope: !29) +!39 = !DILocation(line: 6, column: 45, scope: !29) +!40 = !DILocation(line: 6, column: 43, scope: !29) +!41 = !DILocation(line: 6, column: 49, scope: !29) +!42 = !DILocation(line: 6, column: 47, scope: !29) +!43 = !DILocation(line: 6, column: 38, scope: !29) +!44 = !DILocation(line: 6, column: 52, scope: !29) +!45 = distinct !DISubprogram(name: "fastcall1", linkageName: "\01@fastcall1@4", scope: !1, file: !1, line: 8, type: !46, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!46 = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: !10) +!47 = !DILocalVariable(name: "a", arg: 1, scope: !45, file: !1, line: 8, type: !11) +!48 = !DILocation(line: 8, column: 31, scope: !45) +!49 = !DILocation(line: 8, column: 41, scope: !45) +!50 = !DILocation(line: 8, column: 38, scope: !45) +!51 = !DILocation(line: 8, column: 44, scope: !45) +!52 = distinct !DISubprogram(name: "fastcall2", linkageName: "\01@fastcall2@8", scope: !1, file: !1, line: 9, type: !53, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!53 = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: !19) +!54 = !DILocalVariable(name: "b", arg: 2, scope: !52, file: !1, line: 9, type: !11) +!55 = !DILocation(line: 9, column: 38, scope: !52) +!56 = !DILocalVariable(name: "a", arg: 1, scope: !52, file: !1, line: 9, type: !11) +!57 = !DILocation(line: 9, column: 31, scope: !52) +!58 = !DILocation(line: 9, column: 48, scope: !52) +!59 = !DILocation(line: 9, column: 52, scope: !52) +!60 = !DILocation(line: 9, column: 50, scope: !52) +!61 = !DILocation(line: 9, column: 45, scope: !52) +!62 = !DILocation(line: 9, column: 55, scope: !52) +!63 = distinct !DISubprogram(name: "fastcall3", linkageName: "\01@fastcall3@12", scope: !1, file: !1, line: 10, type: !64, isLocal: false, isDefinition: true, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!64 = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: !31) +!65 = !DILocalVariable(name: "c", arg: 3, scope: !63, file: !1, line: 10, type: !11) +!66 = !DILocation(line: 10, column: 45, scope: !63) +!67 = !DILocalVariable(name: "b", arg: 2, scope: !63, file: !1, line: 10, type: !11) +!68 = !DILocation(line: 10, column: 38, scope: !63) +!69 = !DILocalVariable(name: "a", arg: 1, scope: !63, file: !1, line: 10, type: !11) +!70 = !DILocation(line: 10, column: 31, scope: !63) +!71 = !DILocation(line: 10, column: 55, scope: !63) +!72 = !DILocation(line: 10, column: 59, scope: !63) +!73 = !DILocation(line: 10, column: 57, scope: !63) +!74 = !DILocation(line: 10, column: 63, scope: !63) +!75 = !DILocation(line: 10, column: 61, scope: !63) +!76 = !DILocation(line: 10, column: 52, scope: !63) +!77 = !DILocation(line: 10, column: 66, scope: !63) +!78 = distinct !DISubprogram(name: "stdcall1", linkageName: "\01_stdcall1@4", scope: !1, file: !1, line: 12, type: !79, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!79 = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: !10) +!80 = !DILocalVariable(name: "a", arg: 1, scope: !78, file: !1, line: 12, type: !11) +!81 = !DILocation(line: 12, column: 29, scope: !78) +!82 = !DILocation(line: 12, column: 39, scope: !78) +!83 = !DILocation(line: 12, column: 36, scope: !78) +!84 = !DILocation(line: 12, column: 42, scope: !78) +!85 = distinct !DISubprogram(name: "stdcall2", linkageName: "\01_stdcall2@8", scope: !1, file: !1, line: 13, type: !86, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!86 = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: !19) +!87 = !DILocalVariable(name: "b", arg: 2, scope: !85, file: !1, line: 13, type: !11) +!88 = !DILocation(line: 13, column: 36, scope: !85) +!89 = !DILocalVariable(name: "a", arg: 1, scope: !85, file: !1, line: 13, type: !11) +!90 = !DILocation(line: 13, column: 29, scope: !85) +!91 = !DILocation(line: 13, column: 46, scope: !85) +!92 = !DILocation(line: 13, column: 50, scope: !85) +!93 = !DILocation(line: 13, column: 48, scope: !85) +!94 = !DILocation(line: 13, column: 43, scope: !85) +!95 = !DILocation(line: 13, column: 53, scope: !85) +!96 = distinct !DISubprogram(name: "stdcall3", linkageName: "\01_stdcall3@12", scope: !1, file: !1, line: 14, type: !97, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!97 = !DISubroutineType(cc: DW_CC_BORLAND_stdcall, types: !31) +!98 = !DILocalVariable(name: "c", arg: 3, scope: !96, file: !1, line: 14, type: !11) +!99 = !DILocation(line: 14, column: 43, scope: !96) +!100 = !DILocalVariable(name: "b", arg: 2, scope: !96, file: !1, line: 14, type: !11) +!101 = !DILocation(line: 14, column: 36, scope: !96) +!102 = !DILocalVariable(name: "a", arg: 1, scope: !96, file: !1, line: 14, type: !11) +!103 = !DILocation(line: 14, column: 29, scope: !96) +!104 = !DILocation(line: 14, column: 53, scope: !96) +!105 = !DILocation(line: 14, column: 57, scope: !96) +!106 = !DILocation(line: 14, column: 55, scope: !96) +!107 = !DILocation(line: 14, column: 61, scope: !96) +!108 = !DILocation(line: 14, column: 59, scope: !96) +!109 = !DILocation(line: 14, column: 50, scope: !96) +!110 = !DILocation(line: 14, column: 64, scope: !96) +!111 = distinct !DISubprogram(name: "thiscall1", linkageName: "\01?thiscall1@Foo@@QAEXH@Z", scope: !112, file: !1, line: 23, type: !115, isLocal: false, isDefinition: true, scopeLine: 23, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !114, variables: !2) +!112 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 17, size: 8, elements: !113, identifier: ".?AUFoo@@") +!113 = !{!114, !118, !121} +!114 = !DISubprogram(name: "thiscall1", linkageName: "\01?thiscall1@Foo@@QAEXH@Z", scope: !112, file: !1, line: 18, type: !115, isLocal: false, isDefinition: false, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false) +!115 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !116) +!116 = !{null, !117, !11} +!117 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !112, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer) +!118 = !DISubprogram(name: "thiscall2", linkageName: "\01?thiscall2@Foo@@QAEXHH@Z", scope: !112, file: !1, line: 19, type: !119, isLocal: false, isDefinition: false, scopeLine: 19, flags: DIFlagPrototyped, isOptimized: false) +!119 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !120) +!120 = !{null, !117, !11, !11} +!121 = !DISubprogram(name: "thiscall3", linkageName: "\01?thiscall3@Foo@@QAEXHHH@Z", scope: !112, file: !1, line: 20, type: !122, isLocal: false, isDefinition: false, scopeLine: 20, flags: DIFlagPrototyped, isOptimized: false) +!122 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !123) +!123 = !{null, !117, !11, !11, !11} +!124 = !DILocalVariable(name: "a", arg: 2, scope: !111, file: !1, line: 23, type: !11) +!125 = !DILocation(line: 23, column: 25, scope: !111) +!126 = !DILocalVariable(name: "this", arg: 1, scope: !111, type: !127, flags: DIFlagArtificial | DIFlagObjectPointer) +!127 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !112, size: 32) +!128 = !DILocation(line: 0, scope: !111) +!129 = !DILocation(line: 23, column: 35, scope: !111) +!130 = !DILocation(line: 23, column: 32, scope: !111) +!131 = !DILocation(line: 23, column: 38, scope: !111) +!132 = distinct !DISubprogram(name: "thiscall2", linkageName: "\01?thiscall2@Foo@@QAEXHH@Z", scope: !112, file: !1, line: 24, type: !119, isLocal: false, isDefinition: true, scopeLine: 24, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !118, variables: !2) +!133 = !DILocalVariable(name: "b", arg: 3, scope: !132, file: !1, line: 24, type: !11) +!134 = !DILocation(line: 24, column: 32, scope: !132) +!135 = !DILocalVariable(name: "a", arg: 2, scope: !132, file: !1, line: 24, type: !11) +!136 = !DILocation(line: 24, column: 25, scope: !132) +!137 = !DILocalVariable(name: "this", arg: 1, scope: !132, type: !127, flags: DIFlagArtificial | DIFlagObjectPointer) +!138 = !DILocation(line: 0, scope: !132) +!139 = !DILocation(line: 24, column: 42, scope: !132) +!140 = !DILocation(line: 24, column: 46, scope: !132) +!141 = !DILocation(line: 24, column: 44, scope: !132) +!142 = !DILocation(line: 24, column: 39, scope: !132) +!143 = !DILocation(line: 24, column: 49, scope: !132) +!144 = distinct !DISubprogram(name: "thiscall3", linkageName: "\01?thiscall3@Foo@@QAEXHHH@Z", scope: !112, file: !1, line: 25, type: !122, isLocal: false, isDefinition: true, scopeLine: 25, flags: DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !121, variables: !2) +!145 = !DILocalVariable(name: "c", arg: 4, scope: !144, file: !1, line: 25, type: !11) +!146 = !DILocation(line: 25, column: 39, scope: !144) +!147 = !DILocalVariable(name: "b", arg: 3, scope: !144, file: !1, line: 25, type: !11) +!148 = !DILocation(line: 25, column: 32, scope: !144) +!149 = !DILocalVariable(name: "a", arg: 2, scope: !144, file: !1, line: 25, type: !11) +!150 = !DILocation(line: 25, column: 25, scope: !144) +!151 = !DILocalVariable(name: "this", arg: 1, scope: !144, type: !127, flags: DIFlagArtificial | DIFlagObjectPointer) +!152 = !DILocation(line: 0, scope: !144) +!153 = !DILocation(line: 25, column: 49, scope: !144) +!154 = !DILocation(line: 25, column: 53, scope: !144) +!155 = !DILocation(line: 25, column: 51, scope: !144) +!156 = !DILocation(line: 25, column: 57, scope: !144) +!157 = !DILocation(line: 25, column: 55, scope: !144) +!158 = !DILocation(line: 25, column: 46, scope: !144) +!159 = !DILocation(line: 25, column: 60, scope: !144) diff --git a/llvm/test/DebugInfo/COFF/fpo-csrs.ll b/llvm/test/DebugInfo/COFF/fpo-csrs.ll new file mode 100644 index 00000000000..5c5ca888d14 --- /dev/null +++ b/llvm/test/DebugInfo/COFF/fpo-csrs.ll @@ -0,0 +1,559 @@ +; RUN: llc < %s | FileCheck %s --check-prefix=ASM +; RUN: llc -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s --check-prefix=OBJ + +; C source: +; int getval(void); +; void usevals(int, ...); +; int csr1() { +; int a = getval(); +; usevals(a); +; usevals(a); +; return a; +; } +; int csr2() { +; int a = getval(); +; int b = getval(); +; usevals(a, b); +; usevals(a, b); +; return a; +; } +; int csr3() { +; int a = getval(); +; int b = getval(); +; int c = getval(); +; usevals(a, b, c); +; usevals(a, b, c); +; return a; +; } +; int csr4() { +; int a = getval(); +; int b = getval(); +; int c = getval(); +; int d = getval(); +; usevals(a, b, c, d); +; usevals(a, b, c, d); +; return a; +; } +; int spill() { +; int a = getval(); +; int b = getval(); +; int c = getval(); +; int d = getval(); +; int e = getval(); +; usevals(a, b, c, d, e); +; usevals(a, b, c, d, e); +; return a; +; } + +; ModuleID = 't.c' +source_filename = "t.c" +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.11.25508" + +; Function Attrs: nounwind +define i32 @csr1() local_unnamed_addr #0 !dbg !8 { +entry: + %call = tail call i32 @getval() #3, !dbg !14 + tail call void @llvm.dbg.value(metadata i32 %call, metadata !13, metadata !DIExpression()), !dbg !15 + tail call void (i32, ...) @usevals(i32 %call) #3, !dbg !16 + tail call void (i32, ...) @usevals(i32 %call) #3, !dbg !17 + ret i32 %call, !dbg !18 +} + +; ASM-LABEL: _csr1: # @csr1 +; ASM: .cv_fpo_proc _csr1 +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: .cv_fpo_endprologue +; ASM: #DEBUG_VALUE: csr1:a <- %ESI +; ASM: retl +; ASM: .cv_fpo_endproc + +; OBJ-LABEL: SubSectionType: FrameData (0xF5) +; OBJ-NEXT: SubSectionSize: +; OBJ-NEXT: LinkageName: _csr1 +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x0 +; OBJ-NEXT: CodeSize: 0x1E +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ-NEXT: PrologSize: 0x1 +; OBJ-NEXT: SavedRegsSize: 0x0 +; OBJ-NEXT: Flags [ (0x4) +; OBJ-NEXT: IsFunctionStart (0x4) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x1 +; OBJ-NEXT: CodeSize: 0x1D +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $esi $T0 4 - ^ = +; OBJ-NEXT: PrologSize: 0x0 +; OBJ-NEXT: SavedRegsSize: 0x4 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NOT: FrameData + +declare i32 @getval() local_unnamed_addr #1 + +declare void @usevals(i32, ...) local_unnamed_addr #1 + +; Function Attrs: nounwind +define i32 @csr2() local_unnamed_addr #0 !dbg !19 { +entry: + %call = tail call i32 @getval() #3, !dbg !23 + tail call void @llvm.dbg.value(metadata i32 %call, metadata !21, metadata !DIExpression()), !dbg !24 + %call1 = tail call i32 @getval() #3, !dbg !25 + tail call void @llvm.dbg.value(metadata i32 %call1, metadata !22, metadata !DIExpression()), !dbg !26 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1) #3, !dbg !27 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1) #3, !dbg !28 + ret i32 %call, !dbg !29 +} + +; ASM-LABEL: _csr2: # @csr2 +; ASM: .cv_fpo_proc _csr2 +; ASM: pushl %edi +; ASM: .cv_fpo_pushreg %edi +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: .cv_fpo_endprologue +; ASM: #DEBUG_VALUE: csr2:a <- %ESI +; ASM: #DEBUG_VALUE: csr2:b <- %EDI +; ASM: retl +; ASM: .cv_fpo_endproc + +; OBJ-LABEL: SubSectionType: FrameData (0xF5) +; OBJ-NEXT: SubSectionSize: +; OBJ-NEXT: LinkageName: _csr2 +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x0 +; OBJ-NEXT: CodeSize: 0x29 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ-NEXT: PrologSize: 0x2 +; OBJ-NEXT: SavedRegsSize: 0x0 +; OBJ-NEXT: Flags [ (0x4) +; OBJ-NEXT: IsFunctionStart (0x4) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x1 +; OBJ-NEXT: CodeSize: 0x28 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $edi $T0 4 - ^ = +; OBJ-NEXT: PrologSize: 0x1 +; OBJ-NEXT: SavedRegsSize: 0x4 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x2 +; OBJ-NEXT: CodeSize: 0x27 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $edi $T0 4 - ^ = $esi $T0 8 - ^ = +; OBJ-NEXT: PrologSize: 0x0 +; OBJ-NEXT: SavedRegsSize: 0x8 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NOT: FrameData + +; Function Attrs: nounwind +define i32 @csr3() local_unnamed_addr #0 !dbg !30 { +entry: + %call = tail call i32 @getval() #3, !dbg !35 + tail call void @llvm.dbg.value(metadata i32 %call, metadata !32, metadata !DIExpression()), !dbg !36 + %call1 = tail call i32 @getval() #3, !dbg !37 + tail call void @llvm.dbg.value(metadata i32 %call1, metadata !33, metadata !DIExpression()), !dbg !38 + %call2 = tail call i32 @getval() #3, !dbg !39 + tail call void @llvm.dbg.value(metadata i32 %call2, metadata !34, metadata !DIExpression()), !dbg !40 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2) #3, !dbg !41 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2) #3, !dbg !42 + ret i32 %call, !dbg !43 +} + +; ASM-LABEL: _csr3: # @csr3 +; ASM: .cv_fpo_proc _csr3 +; ASM: pushl %ebx +; ASM: .cv_fpo_pushreg %ebx +; ASM: pushl %edi +; ASM: .cv_fpo_pushreg %edi +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: .cv_fpo_endprologue +; ASM: #DEBUG_VALUE: csr3:a <- %ESI +; ASM: #DEBUG_VALUE: csr3:b <- %EDI +; ASM: #DEBUG_VALUE: csr3:c <- %EBX +; ASM: retl +; ASM: .cv_fpo_endproc + +; OBJ-LABEL: SubSectionType: FrameData (0xF5) +; OBJ-NEXT: SubSectionSize: +; OBJ-NEXT: LinkageName: _csr3 +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x0 +; OBJ-NEXT: CodeSize: 0x34 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ-NEXT: PrologSize: 0x3 +; OBJ-NEXT: SavedRegsSize: 0x0 +; OBJ-NEXT: Flags [ (0x4) +; OBJ-NEXT: IsFunctionStart (0x4) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x1 +; OBJ-NEXT: CodeSize: 0x33 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +; OBJ-NEXT: PrologSize: 0x2 +; OBJ-NEXT: SavedRegsSize: 0x4 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x2 +; OBJ-NEXT: CodeSize: 0x32 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = $edi $T0 8 - ^ = +; OBJ-NEXT: PrologSize: 0x1 +; OBJ-NEXT: SavedRegsSize: 0x8 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x3 +; OBJ-NEXT: CodeSize: 0x31 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = $edi $T0 8 - ^ = $esi $T0 12 - ^ = +; OBJ-NEXT: PrologSize: 0x0 +; OBJ-NEXT: SavedRegsSize: 0xC +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NOT: FrameData + +; Function Attrs: nounwind +define i32 @csr4() local_unnamed_addr #0 !dbg !44 { +entry: + %call = tail call i32 @getval() #3, !dbg !50 + tail call void @llvm.dbg.value(metadata i32 %call, metadata !46, metadata !DIExpression()), !dbg !51 + %call1 = tail call i32 @getval() #3, !dbg !52 + tail call void @llvm.dbg.value(metadata i32 %call1, metadata !47, metadata !DIExpression()), !dbg !53 + %call2 = tail call i32 @getval() #3, !dbg !54 + tail call void @llvm.dbg.value(metadata i32 %call2, metadata !48, metadata !DIExpression()), !dbg !55 + %call3 = tail call i32 @getval() #3, !dbg !56 + tail call void @llvm.dbg.value(metadata i32 %call3, metadata !49, metadata !DIExpression()), !dbg !57 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2, i32 %call3) #3, !dbg !58 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2, i32 %call3) #3, !dbg !59 + ret i32 %call, !dbg !60 +} + +; ASM-LABEL: _csr4: # @csr4 +; ASM: .cv_fpo_proc _csr4 +; ASM: pushl %ebp +; ASM: .cv_fpo_pushreg %ebp +; ASM: pushl %ebx +; ASM: .cv_fpo_pushreg %ebx +; ASM: pushl %edi +; ASM: .cv_fpo_pushreg %edi +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: .cv_fpo_endprologue +; ASM: #DEBUG_VALUE: csr4:a <- %ESI +; ASM: #DEBUG_VALUE: csr4:b <- %EDI +; ASM: #DEBUG_VALUE: csr4:c <- %EBX +; ASM: #DEBUG_VALUE: csr4:d <- %EBP +; ASM: retl +; ASM: .cv_fpo_endproc + +; OBJ-LABEL: SubSectionType: FrameData (0xF5) +; OBJ-NEXT: SubSectionSize: +; OBJ-NEXT: LinkageName: _csr4 +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x0 +; OBJ-NEXT: CodeSize: 0x3F +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ-NEXT: PrologSize: 0x4 +; OBJ-NEXT: SavedRegsSize: 0x0 +; OBJ-NEXT: Flags [ (0x4) +; OBJ-NEXT: IsFunctionStart (0x4) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x1 +; OBJ-NEXT: CodeSize: 0x3E +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +; OBJ-NEXT: PrologSize: 0x3 +; OBJ-NEXT: SavedRegsSize: 0x4 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x2 +; OBJ-NEXT: CodeSize: 0x3D +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = +; OBJ-NEXT: PrologSize: 0x2 +; OBJ-NEXT: SavedRegsSize: 0x8 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x3 +; OBJ-NEXT: CodeSize: 0x3C +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = +; OBJ-NEXT: PrologSize: 0x1 +; OBJ-NEXT: SavedRegsSize: 0xC +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x4 +; OBJ-NEXT: CodeSize: 0x3B +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +; OBJ-NEXT: PrologSize: 0x0 +; OBJ-NEXT: SavedRegsSize: 0x10 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NOT: FrameData + +; Function Attrs: nounwind +define i32 @spill() local_unnamed_addr #0 !dbg !61 { +entry: + %call = tail call i32 @getval() #3, !dbg !68 + tail call void @llvm.dbg.value(metadata i32 %call, metadata !63, metadata !DIExpression()), !dbg !69 + %call1 = tail call i32 @getval() #3, !dbg !70 + tail call void @llvm.dbg.value(metadata i32 %call1, metadata !64, metadata !DIExpression()), !dbg !71 + %call2 = tail call i32 @getval() #3, !dbg !72 + tail call void @llvm.dbg.value(metadata i32 %call2, metadata !65, metadata !DIExpression()), !dbg !73 + %call3 = tail call i32 @getval() #3, !dbg !74 + tail call void @llvm.dbg.value(metadata i32 %call3, metadata !66, metadata !DIExpression()), !dbg !75 + %call4 = tail call i32 @getval() #3, !dbg !76 + tail call void @llvm.dbg.value(metadata i32 %call4, metadata !67, metadata !DIExpression()), !dbg !77 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2, i32 %call3, i32 %call4) #3, !dbg !78 + tail call void (i32, ...) @usevals(i32 %call, i32 %call1, i32 %call2, i32 %call3, i32 %call4) #3, !dbg !79 + ret i32 %call, !dbg !80 +} + +; ASM-LABEL: _spill: # @spill +; ASM: .cv_fpo_proc _spill +; ASM: pushl %ebp +; ASM: .cv_fpo_pushreg %ebp +; ASM: pushl %ebx +; ASM: .cv_fpo_pushreg %ebx +; ASM: pushl %edi +; ASM: .cv_fpo_pushreg %edi +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: subl $8, %esp +; ASM: .cv_fpo_stackalloc 8 +; ASM: .cv_fpo_endprologue +; ASM: retl +; ASM: .cv_fpo_endproc + +; OBJ-LABEL: SubSectionType: FrameData (0xF5) +; OBJ-NEXT: SubSectionSize: +; OBJ-NEXT: LinkageName: _spill +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x0 +; OBJ-NEXT: CodeSize: 0x5A +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ-NEXT: PrologSize: 0x7 +; OBJ-NEXT: SavedRegsSize: 0x0 +; OBJ-NEXT: Flags [ (0x4) +; OBJ-NEXT: IsFunctionStart (0x4) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x1 +; OBJ-NEXT: CodeSize: 0x59 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +; OBJ-NEXT: PrologSize: 0x6 +; OBJ-NEXT: SavedRegsSize: 0x4 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x2 +; OBJ-NEXT: CodeSize: 0x58 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = +; OBJ-NEXT: PrologSize: 0x5 +; OBJ-NEXT: SavedRegsSize: 0x8 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x3 +; OBJ-NEXT: CodeSize: 0x57 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = +; OBJ-NEXT: PrologSize: 0x4 +; OBJ-NEXT: SavedRegsSize: 0xC +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x4 +; OBJ-NEXT: CodeSize: 0x56 +; OBJ-NEXT: LocalSize: 0x0 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +; OBJ-NEXT: PrologSize: 0x3 +; OBJ-NEXT: SavedRegsSize: 0x10 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NEXT: FrameData { +; OBJ-NEXT: RvaStart: 0x7 +; OBJ-NEXT: CodeSize: 0x53 +; OBJ-NEXT: LocalSize: 0x8 +; OBJ-NEXT: ParamsSize: 0x0 +; OBJ-NEXT: MaxStackSize: 0x0 +; OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +; OBJ-NEXT: PrologSize: 0x0 +; OBJ-NEXT: SavedRegsSize: 0x10 +; OBJ-NEXT: Flags [ (0x0) +; OBJ-NEXT: ] +; OBJ-NEXT: } +; OBJ-NOT: FrameData + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { 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 #1 = { "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 #2 = { nounwind readnone speculatable } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "0b1c85f8a0bfb41380df1fcaeadde306") +!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 6.0.0 "} +!8 = distinct !DISubprogram(name: "csr1", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13} +!13 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 4, type: !11) +!14 = !DILocation(line: 4, column: 11, scope: !8) +!15 = !DILocation(line: 4, column: 7, scope: !8) +!16 = !DILocation(line: 5, column: 3, scope: !8) +!17 = !DILocation(line: 6, column: 3, scope: !8) +!18 = !DILocation(line: 7, column: 3, scope: !8) +!19 = distinct !DISubprogram(name: "csr2", scope: !1, file: !1, line: 9, type: !9, isLocal: false, isDefinition: true, scopeLine: 9, isOptimized: true, unit: !0, variables: !20) +!20 = !{!21, !22} +!21 = !DILocalVariable(name: "a", scope: !19, file: !1, line: 10, type: !11) +!22 = !DILocalVariable(name: "b", scope: !19, file: !1, line: 11, type: !11) +!23 = !DILocation(line: 10, column: 11, scope: !19) +!24 = !DILocation(line: 10, column: 7, scope: !19) +!25 = !DILocation(line: 11, column: 11, scope: !19) +!26 = !DILocation(line: 11, column: 7, scope: !19) +!27 = !DILocation(line: 12, column: 3, scope: !19) +!28 = !DILocation(line: 13, column: 3, scope: !19) +!29 = !DILocation(line: 14, column: 3, scope: !19) +!30 = distinct !DISubprogram(name: "csr3", scope: !1, file: !1, line: 16, type: !9, isLocal: false, isDefinition: true, scopeLine: 16, isOptimized: true, unit: !0, variables: !31) +!31 = !{!32, !33, !34} +!32 = !DILocalVariable(name: "a", scope: !30, file: !1, line: 17, type: !11) +!33 = !DILocalVariable(name: "b", scope: !30, file: !1, line: 18, type: !11) +!34 = !DILocalVariable(name: "c", scope: !30, file: !1, line: 19, type: !11) +!35 = !DILocation(line: 17, column: 11, scope: !30) +!36 = !DILocation(line: 17, column: 7, scope: !30) +!37 = !DILocation(line: 18, column: 11, scope: !30) +!38 = !DILocation(line: 18, column: 7, scope: !30) +!39 = !DILocation(line: 19, column: 11, scope: !30) +!40 = !DILocation(line: 19, column: 7, scope: !30) +!41 = !DILocation(line: 20, column: 3, scope: !30) +!42 = !DILocation(line: 21, column: 3, scope: !30) +!43 = !DILocation(line: 22, column: 3, scope: !30) +!44 = distinct !DISubprogram(name: "csr4", scope: !1, file: !1, line: 24, type: !9, isLocal: false, isDefinition: true, scopeLine: 24, isOptimized: true, unit: !0, variables: !45) +!45 = !{!46, !47, !48, !49} +!46 = !DILocalVariable(name: "a", scope: !44, file: !1, line: 25, type: !11) +!47 = !DILocalVariable(name: "b", scope: !44, file: !1, line: 26, type: !11) +!48 = !DILocalVariable(name: "c", scope: !44, file: !1, line: 27, type: !11) +!49 = !DILocalVariable(name: "d", scope: !44, file: !1, line: 28, type: !11) +!50 = !DILocation(line: 25, column: 11, scope: !44) +!51 = !DILocation(line: 25, column: 7, scope: !44) +!52 = !DILocation(line: 26, column: 11, scope: !44) +!53 = !DILocation(line: 26, column: 7, scope: !44) +!54 = !DILocation(line: 27, column: 11, scope: !44) +!55 = !DILocation(line: 27, column: 7, scope: !44) +!56 = !DILocation(line: 28, column: 11, scope: !44) +!57 = !DILocation(line: 28, column: 7, scope: !44) +!58 = !DILocation(line: 29, column: 3, scope: !44) +!59 = !DILocation(line: 30, column: 3, scope: !44) +!60 = !DILocation(line: 31, column: 3, scope: !44) +!61 = distinct !DISubprogram(name: "spill", scope: !1, file: !1, line: 33, type: !9, isLocal: false, isDefinition: true, scopeLine: 33, isOptimized: true, unit: !0, variables: !62) +!62 = !{!63, !64, !65, !66, !67} +!63 = !DILocalVariable(name: "a", scope: !61, file: !1, line: 34, type: !11) +!64 = !DILocalVariable(name: "b", scope: !61, file: !1, line: 35, type: !11) +!65 = !DILocalVariable(name: "c", scope: !61, file: !1, line: 36, type: !11) +!66 = !DILocalVariable(name: "d", scope: !61, file: !1, line: 37, type: !11) +!67 = !DILocalVariable(name: "e", scope: !61, file: !1, line: 38, type: !11) +!68 = !DILocation(line: 34, column: 11, scope: !61) +!69 = !DILocation(line: 34, column: 7, scope: !61) +!70 = !DILocation(line: 35, column: 11, scope: !61) +!71 = !DILocation(line: 35, column: 7, scope: !61) +!72 = !DILocation(line: 36, column: 11, scope: !61) +!73 = !DILocation(line: 36, column: 7, scope: !61) +!74 = !DILocation(line: 37, column: 11, scope: !61) +!75 = !DILocation(line: 37, column: 7, scope: !61) +!76 = !DILocation(line: 38, column: 11, scope: !61) +!77 = !DILocation(line: 38, column: 7, scope: !61) +!78 = !DILocation(line: 39, column: 3, scope: !61) +!79 = !DILocation(line: 40, column: 3, scope: !61) +!80 = !DILocation(line: 41, column: 3, scope: !61) diff --git a/llvm/test/DebugInfo/COFF/fpo-realign-alloca.ll b/llvm/test/DebugInfo/COFF/fpo-realign-alloca.ll new file mode 100644 index 00000000000..7acb501120a --- /dev/null +++ b/llvm/test/DebugInfo/COFF/fpo-realign-alloca.ll @@ -0,0 +1,110 @@ +; RUN: llc < %s | FileCheck %s + +; C source: +; void usethings(double *, void *p); +; int realign_and_alloca(int n) { +; double d = 0; +; void *p = __builtin_alloca(n); +; usethings(&d, p); +; return 0; +; } + +; CHECK: _realign_and_alloca: # @realign_and_alloca +; CHECK: .cv_fpo_proc _realign_and_alloca 4 +; CHECK: pushl %ebp +; CHECK: .cv_fpo_pushreg %ebp +; CHECK: movl %esp, %ebp +; CHECK: .cv_fpo_setframe %ebp +; CHECK: pushl %esi +; CHECK: .cv_fpo_pushreg %esi +; We don't seem to need to describe this AND because at this point CSRs +; are stored relative to EBP, but it's suspicious. +; CHECK: andl $-16, %esp +; CHECK: subl $32, %esp +; CHECK: .cv_fpo_stackalloc 32 +; CHECK: .cv_fpo_endprologue +; CHECK: movl %esp, %esi +; CHECK: leal 8(%esi), +; CHECK: calll _usethings +; CHECK: addl $8, %esp +; CHECK: xorl %eax, %eax +; CHECK: leal -4(%ebp), %esp +; CHECK: popl %esi +; CHECK: popl %ebp +; CHECK: retl +; CHECK: .cv_fpo_endproc + + +; ModuleID = 't.c' +source_filename = "t.c" +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.11.25508" + +; Function Attrs: nounwind +define i32 @realign_and_alloca(i32 %n) local_unnamed_addr #0 !dbg !8 { +entry: + %d = alloca double, align 8 + tail call void @llvm.dbg.value(metadata i32 %n, metadata !13, metadata !DIExpression()), !dbg !18 + %0 = bitcast double* %d to i8*, !dbg !19 + call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !19 + tail call void @llvm.dbg.value(metadata double 0.000000e+00, metadata !14, metadata !DIExpression()), !dbg !20 + store double 0.000000e+00, double* %d, align 8, !dbg !20, !tbaa !21 + %1 = alloca i8, i32 %n, align 16, !dbg !25 + tail call void @llvm.dbg.value(metadata i8* %1, metadata !16, metadata !DIExpression()), !dbg !26 + tail call void @llvm.dbg.value(metadata double* %d, metadata !14, metadata !DIExpression()), !dbg !20 + call void @usethings(double* nonnull %d, i8* nonnull %1) #4, !dbg !27 + call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !28 + ret i32 0, !dbg !29 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 + +declare void @usethings(double*, i8*) local_unnamed_addr #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #3 + +attributes #0 = { 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 #1 = { argmemonly nounwind } +attributes #2 = { "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 #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "cfdc2deff5dc50f95e287f877660d4dd") +!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 6.0.0 "} +!8 = distinct !DISubprogram(name: "realign_and_alloca", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13, !14, !16} +!13 = !DILocalVariable(name: "n", arg: 1, scope: !8, file: !1, line: 2, type: !11) +!14 = !DILocalVariable(name: "d", scope: !8, file: !1, line: 3, type: !15) +!15 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float) +!16 = !DILocalVariable(name: "p", scope: !8, file: !1, line: 4, type: !17) +!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 32) +!18 = !DILocation(line: 2, column: 28, scope: !8) +!19 = !DILocation(line: 3, column: 3, scope: !8) +!20 = !DILocation(line: 3, column: 10, scope: !8) +!21 = !{!22, !22, i64 0} +!22 = !{!"double", !23, i64 0} +!23 = !{!"omnipotent char", !24, i64 0} +!24 = !{!"Simple C/C++ TBAA"} +!25 = !DILocation(line: 4, column: 13, scope: !8) +!26 = !DILocation(line: 4, column: 9, scope: !8) +!27 = !DILocation(line: 5, column: 3, scope: !8) +!28 = !DILocation(line: 7, column: 1, scope: !8) +!29 = !DILocation(line: 6, column: 3, scope: !8) diff --git a/llvm/test/DebugInfo/COFF/fpo-shrink-wrap.ll b/llvm/test/DebugInfo/COFF/fpo-shrink-wrap.ll new file mode 100644 index 00000000000..3d16a28c106 --- /dev/null +++ b/llvm/test/DebugInfo/COFF/fpo-shrink-wrap.ll @@ -0,0 +1,154 @@ +; RUN: llc -enable-shrink-wrap=true < %s | FileCheck %s --check-prefix=ASM +; RUN: llc -enable-shrink-wrap=true -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s --check-prefix=OBJ + +; C source: +; int doSomething(int*); +; int __fastcall shrink_wrap_basic(int a, int b, int c, int d) { +; if (a < b) +; return a; +; for (int i = c; i < d; ++i) +; doSomething(&c); +; return doSomething(&c); +; } + +; ASM: @shrink_wrap_basic@16: # @"\01@shrink_wrap_basic@16" +; ASM: .cv_fpo_proc @shrink_wrap_basic@16 8 +; ASM: .cv_loc 0 1 3 9 # t.c:3:9 +; ASM: movl %ecx, %eax +; ASM: cmpl %edx, %eax +; ASM: jl [[EPILOGUE:LBB0_[0-9]+]] + +; ASM: pushl %ebx +; ASM: .cv_fpo_pushreg %ebx +; ASM: pushl %edi +; ASM: .cv_fpo_pushreg %edi +; ASM: pushl %esi +; ASM: .cv_fpo_pushreg %esi +; ASM: .cv_fpo_endprologue + +; ASM: calll _doSomething + +; ASM: popl %esi +; ASM: popl %edi +; ASM: popl %ebx +; ASM: [[EPILOGUE]]: # %return +; ASM: retl $8 +; ASM: Ltmp11: +; ASM: .cv_fpo_endproc + +; Note how RvaStart advances 7 bytes to skip the shrink-wrapped portion. +; OBJ: SubSectionType: FrameData (0xF5) +; OBJ: FrameData { +; OBJ: RvaStart: 0x0 +; OBJ: CodeSize: 0x34 +; OBJ: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +; OBJ: PrologSize: 0x9 +; OBJ: } +; OBJ: FrameData { +; OBJ: RvaStart: 0x7 +; OBJ: CodeSize: 0x2D +; OBJ: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = +; OBJ: PrologSize: 0x2 +; OBJ: } +; OBJ: FrameData { +; OBJ: RvaStart: 0x8 +; OBJ: CodeSize: 0x2C +; OBJ: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = $edi $T0 8 - ^ = +; OBJ: PrologSize: 0x1 +; OBJ: } +; OBJ: FrameData { +; OBJ: RvaStart: 0x9 +; OBJ: CodeSize: 0x2B +; OBJ: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebx $T0 4 - ^ = $edi $T0 8 - ^ = $esi $T0 12 - ^ = +; OBJ: PrologSize: 0x0 +; OBJ: } +; OBJ-NOT: FrameData + +; ModuleID = 't.c' +source_filename = "t.c" +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.11.25508" + +; Function Attrs: nounwind +define x86_fastcallcc i32 @"\01@shrink_wrap_basic@16"(i32 inreg %a, i32 inreg %b, i32 %c, i32 %d) local_unnamed_addr #0 !dbg !8 { +entry: + %c.addr = alloca i32, align 4 + tail call void @llvm.dbg.value(metadata i32 %d, metadata !13, metadata !DIExpression()), !dbg !19 + tail call void @llvm.dbg.value(metadata i32 %c, metadata !14, metadata !DIExpression()), !dbg !20 + store i32 %c, i32* %c.addr, align 4, !tbaa !21 + tail call void @llvm.dbg.value(metadata i32 %b, metadata !15, metadata !DIExpression()), !dbg !25 + tail call void @llvm.dbg.value(metadata i32 %a, metadata !16, metadata !DIExpression()), !dbg !26 + %cmp = icmp slt i32 %a, %b, !dbg !27 + br i1 %cmp, label %return, label %for.cond.preheader, !dbg !29 + +for.cond.preheader: ; preds = %entry + br label %for.cond, !dbg !30 + +for.cond: ; preds = %for.cond.preheader, %for.cond + %i.0 = phi i32 [ %inc, %for.cond ], [ %c, %for.cond.preheader ] + call void @llvm.dbg.value(metadata i32 %i.0, metadata !17, metadata !DIExpression()), !dbg !32 + %cmp1 = icmp slt i32 %i.0, %d, !dbg !30 + call void @llvm.dbg.value(metadata i32* %c.addr, metadata !14, metadata !DIExpression()), !dbg !20 + %call = call i32 @doSomething(i32* nonnull %c.addr) #3, !dbg !33 + %inc = add nsw i32 %i.0, 1, !dbg !34 + call void @llvm.dbg.value(metadata i32 %inc, metadata !17, metadata !DIExpression()), !dbg !32 + br i1 %cmp1, label %for.cond, label %return, !dbg !35, !llvm.loop !36 + +return: ; preds = %for.cond, %entry + %retval.0 = phi i32 [ %a, %entry ], [ %call, %for.cond ] + ret i32 %retval.0, !dbg !38 +} + +declare i32 @doSomething(i32*) local_unnamed_addr #1 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +attributes #0 = { 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 #1 = { "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 #2 = { nounwind readnone speculatable } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "32f118fd5dd7e65ff7733c49b2f804ef") +!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 6.0.0 "} +!8 = distinct !DISubprogram(name: "shrink_wrap_basic", linkageName: "\01@shrink_wrap_basic@16", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12) +!9 = !DISubroutineType(cc: DW_CC_BORLAND_msfastcall, types: !10) +!10 = !{!11, !11, !11, !11, !11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13, !14, !15, !16, !17} +!13 = !DILocalVariable(name: "d", arg: 4, scope: !8, file: !1, line: 2, type: !11) +!14 = !DILocalVariable(name: "c", arg: 3, scope: !8, file: !1, line: 2, type: !11) +!15 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 2, type: !11) +!16 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 2, type: !11) +!17 = !DILocalVariable(name: "i", scope: !18, file: !1, line: 5, type: !11) +!18 = distinct !DILexicalBlock(scope: !8, file: !1, line: 5, column: 3) +!19 = !DILocation(line: 2, column: 59, scope: !8) +!20 = !DILocation(line: 2, column: 52, scope: !8) +!21 = !{!22, !22, i64 0} +!22 = !{!"int", !23, i64 0} +!23 = !{!"omnipotent char", !24, i64 0} +!24 = !{!"Simple C/C++ TBAA"} +!25 = !DILocation(line: 2, column: 45, scope: !8) +!26 = !DILocation(line: 2, column: 38, scope: !8) +!27 = !DILocation(line: 3, column: 9, scope: !28) +!28 = distinct !DILexicalBlock(scope: !8, file: !1, line: 3, column: 7) +!29 = !DILocation(line: 3, column: 7, scope: !8) +!30 = !DILocation(line: 5, column: 21, scope: !31) +!31 = distinct !DILexicalBlock(scope: !18, file: !1, line: 5, column: 3) +!32 = !DILocation(line: 5, column: 12, scope: !18) +!33 = !DILocation(line: 0, scope: !8) +!34 = !DILocation(line: 5, column: 26, scope: !31) +!35 = !DILocation(line: 5, column: 3, scope: !18) +!36 = distinct !{!36, !35, !37} +!37 = !DILocation(line: 6, column: 19, scope: !18) +!38 = !DILocation(line: 8, column: 1, scope: !8) diff --git a/llvm/test/DebugInfo/COFF/fpo-stack-protect.ll b/llvm/test/DebugInfo/COFF/fpo-stack-protect.ll new file mode 100644 index 00000000000..24d99c51308 --- /dev/null +++ b/llvm/test/DebugInfo/COFF/fpo-stack-protect.ll @@ -0,0 +1,114 @@ +; RUN: llc < %s | FileCheck %s + +; C source: +; void escape(int *); +; int ssp(int a) { +; int arr[4] = {a, a, a, a}; +; escape(&arr[0]); +; return a; +; } + +; CHECK: _ssp: # @ssp +; CHECK: .cv_fpo_proc _ssp 4 +; CHECK: pushl %esi +; CHECK: .cv_fpo_pushreg %esi +; CHECK: subl $20, %esp +; CHECK: .cv_fpo_stackalloc 20 +; CHECK: .cv_fpo_endprologue +; CHECK: ___security_cookie + +; CHECK: movl 28(%esp), %esi +; CHECK: movl %esi, {{[0-9]*}}(%esp) +; CHECK: movl %esi, {{[0-9]*}}(%esp) +; CHECK: movl %esi, {{[0-9]*}}(%esp) +; CHECK: movl %esi, {{[0-9]*}}(%esp) + +; CHECK: calll _escape +; CHECK: calll @__security_check_cookie@4 + +; CHECK: movl %esi, %eax +; CHECK: addl $20, %esp +; CHECK: popl %esi +; CHECK: retl +; CHECK: Ltmp2: +; CHECK: .cv_fpo_endproc + +; ModuleID = 't.c' +source_filename = "t.c" +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.11.25508" + +; Function Attrs: nounwind sspstrong +define i32 @ssp(i32 returned %a) local_unnamed_addr #0 !dbg !8 { +entry: + %arr = alloca [4 x i32], align 4 + tail call void @llvm.dbg.value(metadata i32 %a, metadata !13, metadata !DIExpression()), !dbg !18 + %0 = bitcast [4 x i32]* %arr to i8*, !dbg !19 + call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %0) #4, !dbg !19 + tail call void @llvm.dbg.declare(metadata [4 x i32]* %arr, metadata !14, metadata !DIExpression()), !dbg !20 + %arrayinit.begin = getelementptr inbounds [4 x i32], [4 x i32]* %arr, i32 0, i32 0, !dbg !21 + store i32 %a, i32* %arrayinit.begin, align 4, !dbg !21, !tbaa !22 + %arrayinit.element = getelementptr inbounds [4 x i32], [4 x i32]* %arr, i32 0, i32 1, !dbg !21 + store i32 %a, i32* %arrayinit.element, align 4, !dbg !21, !tbaa !22 + %arrayinit.element1 = getelementptr inbounds [4 x i32], [4 x i32]* %arr, i32 0, i32 2, !dbg !21 + store i32 %a, i32* %arrayinit.element1, align 4, !dbg !21, !tbaa !22 + %arrayinit.element2 = getelementptr inbounds [4 x i32], [4 x i32]* %arr, i32 0, i32 3, !dbg !21 + store i32 %a, i32* %arrayinit.element2, align 4, !dbg !21, !tbaa !22 + call void @escape(i32* nonnull %arrayinit.begin) #4, !dbg !26 + call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %0) #4, !dbg !27 + ret i32 %a, !dbg !28 +} + +; 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 void @escape(i32*) local_unnamed_addr #3 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #2 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind 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 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "t.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "df0c1a43acd19a1255d45a3f2802cf9f") +!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 6.0.0 "} +!8 = distinct !DISubprogram(name: "ssp", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13, !14} +!13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 2, type: !11) +!14 = !DILocalVariable(name: "arr", scope: !8, file: !1, line: 3, type: !15) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 128, elements: !16) +!16 = !{!17} +!17 = !DISubrange(count: 4) +!18 = !DILocation(line: 2, column: 13, scope: !8) +!19 = !DILocation(line: 3, column: 3, scope: !8) +!20 = !DILocation(line: 3, column: 7, scope: !8) +!21 = !DILocation(line: 3, column: 16, scope: !8) +!22 = !{!23, !23, i64 0} +!23 = !{!"int", !24, i64 0} +!24 = !{!"omnipotent char", !25, i64 0} +!25 = !{!"Simple C/C++ TBAA"} +!26 = !DILocation(line: 4, column: 3, scope: !8) +!27 = !DILocation(line: 6, column: 1, scope: !8) +!28 = !DILocation(line: 5, column: 3, scope: !8) diff --git a/llvm/test/DebugInfo/COFF/multifunction.ll b/llvm/test/DebugInfo/COFF/multifunction.ll index 87db2a20eaa..4d14a61ceb3 100644 --- a/llvm/test/DebugInfo/COFF/multifunction.ll +++ b/llvm/test/DebugInfo/COFF/multifunction.ll @@ -61,6 +61,7 @@ ; X86-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] # ; X86: [[COMPILE_END]]: ; X86-NEXT: .p2align 2 +; X86-NEXT: .cv_fpo_data _x ; Symbol subsection for x ; X86-NEXT: .long 241 ; X86-NEXT: .long [[F1_END:.*]]-[[F1_START:.*]] # @@ -87,6 +88,7 @@ ; Line table subsection for x ; X86: .cv_linetable 0, _x, [[END_OF_X]] ; Symbol subsection for y +; X86-NEXT: .cv_fpo_data _y ; X86-NEXT: .long 241 ; X86-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] # ; X86-NEXT: [[COMPILE_START]]: @@ -112,6 +114,7 @@ ; Line table subsection for y ; X86: .cv_linetable 1, _y, [[END_OF_Y]] ; Symbol subsection for f +; X86-NEXT: .cv_fpo_data _f ; X86-NEXT: .long 241 ; X86-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] # ; X86-NEXT: [[COMPILE_START]]: @@ -145,6 +148,13 @@ ; OBJ32: ] ; OBJ32: Subsection [ ; OBJ32-NEXT: SubSectionType: Symbols (0xF1) +; OBJ32: Compile3Sym +; OBJ32: ] +; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: FrameData (0xF5) +; OBJ32: ] +; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: Symbols (0xF1) ; OBJ32: {{.*}}Proc{{.*}}Sym { ; OBJ32: Kind: S_LPROC32_ID (0x1146) ; OBJ32: CodeSize: 0x6 @@ -158,6 +168,9 @@ ; OBJ32-NEXT: SubSectionType: Lines (0xF2) ; OBJ32: ] ; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: FrameData (0xF5) +; OBJ32: ] +; OBJ32: Subsection [ ; OBJ32-NEXT: SubSectionType: Symbols (0xF1) ; OBJ32: {{.*}}Proc{{.*}}Sym { ; OBJ32: Kind: S_GPROC32_ID (0x1147) @@ -172,6 +185,9 @@ ; OBJ32-NEXT: SubSectionType: Lines (0xF2) ; OBJ32: ] ; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: FrameData (0xF5) +; OBJ32: ] +; OBJ32: Subsection [ ; OBJ32-NEXT: SubSectionType: Symbols (0xF1) ; OBJ32: {{.*}}Proc{{.*}}Sym { ; OBJ32: Kind: S_GPROC32_ID (0x1147) diff --git a/llvm/test/DebugInfo/COFF/simple.ll b/llvm/test/DebugInfo/COFF/simple.ll index 71733d1844b..90a973b4c3f 100644 --- a/llvm/test/DebugInfo/COFF/simple.ll +++ b/llvm/test/DebugInfo/COFF/simple.ll @@ -36,6 +36,7 @@ ; X86: [[C1_END]]: ; X86-NEXT: [[COMPILE_END]]: ; X86-NEXT: .p2align 2 +; X86-NEXT: .cv_fpo_data _f ; X86-NEXT: .long 241 # Symbol subsection for f ; X86-NEXT: .long [[F1_END:.*]]-[[F1_START:.*]] # Subsection size ; X86-NEXT: [[F1_START]]: @@ -70,13 +71,21 @@ ; OBJ32: Characteristics [ (0x42300040) ; OBJ32: ] ; OBJ32: Relocations [ -; OBJ32-NEXT: 0x64 IMAGE_REL_I386_SECREL _f -; OBJ32-NEXT: 0x68 IMAGE_REL_I386_SECTION _f -; OBJ32-NEXT: 0x7C IMAGE_REL_I386_SECREL _f -; OBJ32-NEXT: 0x80 IMAGE_REL_I386_SECTION _f +; 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: ] ; OBJ32: Subsection [ ; OBJ32-NEXT: SubSectionType: Symbols (0xF1) +; OBJ32: Compile3Sym +; OBJ32: ] +; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: FrameData (0xF5) +; OBJ32: ] +; OBJ32: Subsection [ +; OBJ32-NEXT: SubSectionType: Symbols (0xF1) ; OBJ32: {{.*}}Proc{{.*}}Sym { ; OBJ32: CodeSize: 0x6 ; OBJ32: DisplayName: f diff --git a/llvm/test/MC/COFF/cv-fpo-csrs.s b/llvm/test/MC/COFF/cv-fpo-csrs.s new file mode 100644 index 00000000000..fef7e786078 --- /dev/null +++ b/llvm/test/MC/COFF/cv-fpo-csrs.s @@ -0,0 +1,141 @@ +# RUN: llvm-mc -filetype=asm < %s -triple i686-windows-msvc | FileCheck %s --check-prefix=ASM +# RUN: llvm-mc -filetype=obj < %s -triple i686-windows-msvc | llvm-readobj -codeview | FileCheck %s --check-prefix=OBJ + +.globl _foo +_foo: + .cv_fpo_proc _foo 4 + pushl %ebp + .cv_fpo_pushreg ebp # Test without % + pushl %ebx + .cv_fpo_pushreg %ebx + pushl %edi + .cv_fpo_pushreg %edi + pushl %esi + .cv_fpo_pushreg esi + subl $20, %esp + .cv_fpo_stackalloc 20 + .cv_fpo_endprologue + + # ASM: .cv_fpo_proc _foo 4 + # ASM: pushl %ebp + # ASM: .cv_fpo_pushreg %ebp + # ASM: pushl %ebx + # ASM: .cv_fpo_pushreg %ebx + # ASM: pushl %edi + # ASM: .cv_fpo_pushreg %edi + # ASM: pushl %esi + # ASM: .cv_fpo_pushreg %esi + # ASM: subl $20, %esp + # ASM: .cv_fpo_stackalloc 20 + # ASM: .cv_fpo_endprologue + + # Clobbers + xorl %ebp, %ebp + xorl %ebx, %ebx + xorl %edi, %edi + xorl %esi, %esi + # Use that stack memory + leal 4(%esp), %eax + movl %eax, (%esp) + calll _bar + + # ASM: calll _bar + + # Epilogue + # FIXME: Get FPO data for this once we get it for DWARF. + addl $20, %esp + popl %esi + popl %edi + popl %ebx + popl %ebp + retl + .cv_fpo_endproc + + # ASM: .cv_fpo_endproc + + .section .debug$S,"dr" + .p2align 2 + .long 4 # Debug section magic + .cv_fpo_data _foo + .cv_stringtable + + # ASM: .cv_fpo_data + +# OBJ: Subsection [ +# OBJ-NEXT: SubSectionType: FrameData (0xF5) +# OBJ-NEXT: SubSectionSize: 0xC4 +# OBJ-NEXT: LinkageName: _foo +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x0 +# OBJ-NEXT: CodeSize: 0x23 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +# OBJ-NEXT: PrologSize: 0x7 +# OBJ-NEXT: SavedRegsSize: 0x0 +# OBJ-NEXT: Flags [ (0x4) +# OBJ-NEXT: IsFunctionStart (0x4) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x1 +# OBJ-NEXT: CodeSize: 0x22 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +# OBJ-NEXT: PrologSize: 0x6 +# OBJ-NEXT: SavedRegsSize: 0x4 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x2 +# OBJ-NEXT: CodeSize: 0x21 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = +# OBJ-NEXT: PrologSize: 0x5 +# OBJ-NEXT: SavedRegsSize: 0x8 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x3 +# OBJ-NEXT: CodeSize: 0x20 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = +# OBJ-NEXT: PrologSize: 0x4 +# OBJ-NEXT: SavedRegsSize: 0xC +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x4 +# OBJ-NEXT: CodeSize: 0x1F +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +# OBJ-NEXT: PrologSize: 0x3 +# OBJ-NEXT: SavedRegsSize: 0x10 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x7 +# OBJ-NEXT: CodeSize: 0x1C +# OBJ-NEXT: LocalSize: 0x14 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +# OBJ-NEXT: PrologSize: 0x0 +# OBJ-NEXT: SavedRegsSize: 0x10 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NOT: FrameData diff --git a/llvm/test/MC/COFF/cv-fpo-errors.s b/llvm/test/MC/COFF/cv-fpo-errors.s new file mode 100644 index 00000000000..baa2fa0d937 --- /dev/null +++ b/llvm/test/MC/COFF/cv-fpo-errors.s @@ -0,0 +1,47 @@ +# RUN: not llvm-mc < %s -triple i686-windows-msvc -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: + +.globl _foo +_foo: + .cv_fpo_proc + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected symbol name + .cv_fpo_proc 1 + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected symbol name + .cv_fpo_proc _foo extra + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected parameter byte count + .cv_fpo_proc _foo 4 extra + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected tokens in '.cv_fpo_proc' directive + .cv_fpo_proc _foo 4 + + pushl %ebp + .cv_fpo_pushreg 1 + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: invalid register name in '.cv_fpo_pushreg' directive + .cv_fpo_pushreg ebp + + subl $20, %esp + .cv_fpo_stackalloc asdf + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected offset in '.cv_fpo_stackalloc' directive + .cv_fpo_stackalloc 20 asdf + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected tokens in '.cv_fpo_stackalloc' directive + .cv_fpo_stackalloc 20 + .cv_fpo_endprologue asdf + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected tokens in '.cv_fpo_endprologue' directive + .cv_fpo_endprologue + + addl $20, %esp + popl %ebp + retl + .cv_fpo_endproc asdf + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected tokens in '.cv_fpo_endproc' directive + .cv_fpo_endproc + + .section .debug$S,"dr" + .p2align 2 + .long 4 # Debug section magic + .cv_fpo_data + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected symbol name + .cv_fpo_data 1 + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: expected symbol name + .cv_fpo_data _foo asdf + # CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected tokens in '.cv_fpo_data' directive + .cv_fpo_data _foo + .long 0 diff --git a/llvm/test/MC/COFF/cv-fpo-setframe.s b/llvm/test/MC/COFF/cv-fpo-setframe.s new file mode 100644 index 00000000000..12369c7523c --- /dev/null +++ b/llvm/test/MC/COFF/cv-fpo-setframe.s @@ -0,0 +1,144 @@ +# RUN: llvm-mc -filetype=asm < %s -triple i686-windows-msvc | FileCheck %s --check-prefix=ASM +# RUN: llvm-mc -filetype=obj < %s -triple i686-windows-msvc | llvm-readobj -codeview | FileCheck %s --check-prefix=OBJ + +.globl _foo +_foo: + .cv_fpo_proc _foo 4 + pushl %ebp + .cv_fpo_pushreg %ebp + movl %ebp, %esp + .cv_fpo_setframe %ebp + pushl %ebx + .cv_fpo_pushreg %ebx + pushl %edi + .cv_fpo_pushreg %edi + pushl %esi + .cv_fpo_pushreg esi + subl $20, %esp + .cv_fpo_stackalloc 20 + .cv_fpo_endprologue + + # ASM: .cv_fpo_proc _foo 4 + # ASM: pushl %ebp + # ASM: .cv_fpo_pushreg %ebp + # ASM: movl %ebp, %esp + # ASM: .cv_fpo_setframe %ebp + # ASM: pushl %ebx + # ASM: .cv_fpo_pushreg %ebx + # ASM: pushl %edi + # ASM: .cv_fpo_pushreg %edi + # ASM: pushl %esi + # ASM: .cv_fpo_pushreg %esi + # ASM: subl $20, %esp + # ASM: .cv_fpo_stackalloc 20 + # ASM: .cv_fpo_endprologue + + # Clobbers + xorl %ebx, %ebx + xorl %edi, %edi + xorl %esi, %esi + # Use that stack memory + leal 4(%esp), %eax + movl %eax, (%esp) + calll _bar + + # ASM: calll _bar + + # Epilogue + # FIXME: Get FPO data for this once we get it for DWARF. + addl $20, %esp + popl %esi + popl %edi + popl %ebx + popl %ebp + retl + .cv_fpo_endproc + + # ASM: .cv_fpo_endproc + + .section .debug$S,"dr" + .p2align 2 + .long 4 # Debug section magic + .cv_fpo_data _foo + .cv_stringtable + + # ASM: .cv_fpo_data + +# OBJ: Subsection [ +# OBJ-NEXT: SubSectionType: FrameData (0xF5) +# OBJ-NEXT: SubSectionSize: +# OBJ-NEXT: LinkageName: _foo +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x0 +# OBJ-NEXT: CodeSize: 0x23 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = +# OBJ-NEXT: PrologSize: 0x9 +# OBJ-NEXT: SavedRegsSize: 0x0 +# OBJ-NEXT: Flags [ (0x4) +# OBJ-NEXT: IsFunctionStart (0x4) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x1 +# OBJ-NEXT: CodeSize: 0x22 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +# OBJ-NEXT: PrologSize: 0x8 +# OBJ-NEXT: SavedRegsSize: 0x4 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x3 +# OBJ-NEXT: CodeSize: 0x20 +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = +# OBJ-NEXT: PrologSize: 0x6 +# OBJ-NEXT: SavedRegsSize: 0x4 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x4 +# OBJ-NEXT: CodeSize: 0x1F +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = +# OBJ-NEXT: PrologSize: 0x5 +# OBJ-NEXT: SavedRegsSize: 0x8 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x5 +# OBJ-NEXT: CodeSize: 0x1E +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = +# OBJ-NEXT: PrologSize: 0x4 +# OBJ-NEXT: SavedRegsSize: 0xC +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NEXT: FrameData { +# OBJ-NEXT: RvaStart: 0x6 +# OBJ-NEXT: CodeSize: 0x1D +# OBJ-NEXT: LocalSize: 0x0 +# OBJ-NEXT: ParamsSize: 0x4 +# OBJ-NEXT: MaxStackSize: 0x0 +# OBJ-NEXT: FrameFunc: $T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $ebx $T0 8 - ^ = $edi $T0 12 - ^ = $esi $T0 16 - ^ = +# OBJ-NEXT: PrologSize: 0x3 +# OBJ-NEXT: SavedRegsSize: 0x10 +# OBJ-NEXT: Flags [ (0x0) +# OBJ-NEXT: ] +# OBJ-NEXT: } +# OBJ-NOT: FrameData |

