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