1 # RUN: llvm-mc -triple=x86_64-windows -filetype=obj < %s | llvm-readobj -codeview | FileCheck %s 2 3 # C source to generate the assembly: 4 # volatile int unlikely_cond = 0; 5 # extern void __declspec(noreturn) abort(); 6 # __forceinline void f() { 7 # if (unlikely_cond) 8 # abort(); 9 # } 10 # void g() { 11 # unlikely_cond = 0; 12 # f(); 13 # unlikely_cond = 0; 14 # } 15 16 # This test is interesting because the inlined instructions are discontiguous. 17 # LLVM's block layout algorithms will put the 'abort' call last, as it is 18 # considered highly unlikely to execute. This is similar to what it does for 19 # calls to __asan_report*, for which it is very important to have an accurate 20 # stack trace. 21 22 # CHECK: GlobalProcIdSym { 23 # CHECK: FunctionType: g (0x1003) 24 # CHECK: CodeOffset: g+0x0 25 # CHECK: DisplayName: g 26 # CHECK: LinkageName: g 27 # CHECK: } 28 # CHECK: InlineSiteSym { 29 # CHECK: Inlinee: f (0x1002) 30 # CHECK: BinaryAnnotations [ 31 # CHECK-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xE, LineOffset: 1} 32 # CHECK-NEXT: ChangeCodeLength: 0x9 33 # CHECK-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xF, LineOffset: 1} 34 # CHECK-NEXT: ChangeCodeLength: 0x7 35 # CHECK-NEXT: ] 36 37 .text 38 .globl g 39 g: # @g 40 .Lfunc_begin0: 41 .cv_func_id 0 42 .cv_file 1 "C:\\src\\llvm\\build\\t.cpp" 43 .cv_loc 0 1 7 0 is_stmt 0 # t.cpp:7:0 44 .seh_proc g 45 subq $40, %rsp 46 .seh_stackalloc 40 47 .seh_endprologue 48 .cv_loc 0 1 8 17 # t.cpp:8:17 49 movl $0, unlikely_cond(%rip) 50 .cv_inline_site_id 1 within 0 inlined_at 1 9 3 51 .cv_loc 1 1 4 7 # t.cpp:4:7 52 cmpl $0, unlikely_cond(%rip) 53 jne .LBB0_1 54 .cv_loc 0 1 10 17 # t.cpp:10:17 55 movl $0, unlikely_cond(%rip) 56 .cv_loc 0 1 11 1 # t.cpp:11:1 57 addq $40, %rsp 58 retq 59 60 .LBB0_1: # %if.then.i 61 .cv_loc 1 1 5 5 # t.cpp:5:5 62 callq abort 63 ud2 64 .Lfunc_end0: 65 .seh_handlerdata 66 .text 67 .seh_endproc 68 69 .bss 70 .globl unlikely_cond # @unlikely_cond 71 .p2align 2 72 unlikely_cond: 73 .long 0 # 0x0 74 75 .section .debug$S,"dr" 76 .p2align 2 77 .long 4 # Debug section magic 78 .long 246 # Inlinee lines subsection 79 .long .Ltmp9-.Ltmp8 # Subsection size 80 .Ltmp8: 81 .long 0 # Inlinee lines signature 82 83 # Inlined function f starts at t.cpp:3 84 .long 4098 # Type index of inlined function 85 .long 0 # Offset into filechecksum table 86 .long 3 # Starting line number 87 .Ltmp9: 88 .p2align 2 89 .long 241 # Symbol subsection for g 90 .long .Ltmp11-.Ltmp10 # Subsection size 91 .Ltmp10: 92 .short .Ltmp13-.Ltmp12 # Record length 93 .Ltmp12: 94 .short 4423 # Record kind: S_GPROC32_ID 95 .long 0 # PtrParent 96 .long 0 # PtrEnd 97 .long 0 # PtrNext 98 .long .Lfunc_end0-g # Code size 99 .long 0 # Offset after prologue 100 .long 0 # Offset before epilogue 101 .long 4099 # Function type index 102 .secrel32 g # Function section relative address 103 .secidx g # Function section index 104 .byte 0 # Flags 105 .asciz "g" # Function name 106 .Ltmp13: 107 .short .Ltmp15-.Ltmp14 # Record length 108 .Ltmp14: 109 .short 4429 # Record kind: S_INLINESITE 110 .long 0 # PtrParent 111 .long 0 # PtrEnd 112 .long 4098 # Inlinee type index 113 .cv_inline_linetable 1 1 3 .Lfunc_begin0 .Lfunc_end0 114 .Ltmp15: 115 .short 2 # Record length 116 .short 4430 # Record kind: S_INLINESITE_END 117 .short 2 # Record length 118 .short 4431 # Record kind: S_PROC_ID_END 119 .Ltmp11: 120 .p2align 2 121 .cv_linetable 0, g, .Lfunc_end0 122 .long 241 # Symbol subsection for globals 123 .long .Ltmp17-.Ltmp16 # Subsection size 124 .Ltmp16: 125 .short .Ltmp19-.Ltmp18 # Record length 126 .Ltmp18: 127 .short 4365 # Record kind: S_GDATA32 128 .long 4100 # Type 129 .secrel32 unlikely_cond # DataOffset 130 .secidx unlikely_cond # Segment 131 .asciz "unlikely_cond" # Name 132 .Ltmp19: 133 .Ltmp17: 134 .p2align 2 135 .cv_filechecksums # File index to string table offset subsection 136 .cv_stringtable # String table 137 .section .debug$T,"dr" 138 .p2align 2 139 .long 4 # Debug section magic 140 # ArgList (0x1000) { 141 # TypeLeafKind: LF_ARGLIST (0x1201) 142 # NumArgs: 0 143 # Arguments [ 144 # ] 145 # } 146 .byte 0x06, 0x00, 0x01, 0x12 147 .byte 0x00, 0x00, 0x00, 0x00 148 # Procedure (0x1001) { 149 # TypeLeafKind: LF_PROCEDURE (0x1008) 150 # ReturnType: void (0x3) 151 # CallingConvention: NearC (0x0) 152 # FunctionOptions [ (0x0) 153 # ] 154 # NumParameters: 0 155 # ArgListType: () (0x1000) 156 # } 157 .byte 0x0e, 0x00, 0x08, 0x10 158 .byte 0x03, 0x00, 0x00, 0x00 159 .byte 0x00, 0x00, 0x00, 0x00 160 .byte 0x00, 0x10, 0x00, 0x00 161 # FuncId (0x1002) { 162 # TypeLeafKind: LF_FUNC_ID (0x1601) 163 # ParentScope: 0x0 164 # FunctionType: void () (0x1001) 165 # Name: f 166 # } 167 .byte 0x0e, 0x00, 0x01, 0x16 168 .byte 0x00, 0x00, 0x00, 0x00 169 .byte 0x01, 0x10, 0x00, 0x00 170 .byte 0x66, 0x00, 0xf2, 0xf1 171 # FuncId (0x1003) { 172 # TypeLeafKind: LF_FUNC_ID (0x1601) 173 # ParentScope: 0x0 174 # FunctionType: void () (0x1001) 175 # Name: g 176 # } 177 .byte 0x0e, 0x00, 0x01, 0x16 178 .byte 0x00, 0x00, 0x00, 0x00 179 .byte 0x01, 0x10, 0x00, 0x00 180 .byte 0x67, 0x00, 0xf2, 0xf1 181 # Modifier (0x1004) { 182 # TypeLeafKind: LF_MODIFIER (0x1001) 183 # ModifiedType: int (0x74) 184 # Modifiers [ (0x2) 185 # Volatile (0x2) 186 # ] 187 # } 188 .byte 0x0a, 0x00, 0x01, 0x10 189 .byte 0x74, 0x00, 0x00, 0x00 190 .byte 0x02, 0x00, 0xf2, 0xf1 191 192