1 ; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s 2 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s 3 4 %rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] } 5 %eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* } 6 %eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] } 7 %eh.ThrowInfo = type { i32, i8*, i8*, i8* } 8 9 $"\01??_R0H@8" = comdat any 10 11 @"\01??_7type_info@@6B@" = external constant i8* 12 @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat 13 14 declare i32 @getint() 15 declare void @useints(...) 16 declare void @f(i32 %p) 17 declare i32 @__CxxFrameHandler3(...) 18 19 define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 { 20 entry: 21 %a = call i32 @getint() 22 %b = call i32 @getint() 23 %c = call i32 @getint() 24 %d = call i32 @getint() 25 call void (...) @useints(i32 %a, i32 %b, i32 %c, i32 %d) 26 invoke void @f(i32 1) 27 to label %try.cont unwind label %catch.dispatch 28 29 try.cont: 30 ret i32 0 31 32 catch.dispatch: 33 %cs = catchswitch within none [label %handler1] unwind to caller 34 35 handler1: 36 %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 37 call void @f(i32 2) [ "funclet"(token %h1) ] 38 catchret from %h1 to label %try.cont 39 } 40 41 ; X86-LABEL: _try_catch_catch: 42 ; X86: pushl %ebp 43 ; X86: movl %esp, %ebp 44 ; X86: pushl %ebx 45 ; X86: pushl %edi 46 ; X86: pushl %esi 47 ; X86: subl ${{[0-9]+}}, %esp 48 ; X86: calll _getint 49 ; X86: calll _getint 50 ; X86: calll _getint 51 ; X86: calll _getint 52 ; X86: calll _useints 53 ; X86: movl $0, -{{[0-9]+}}(%ebp) 54 ; X86: pushl $1 55 ; X86: calll _f 56 ; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont 57 ; X86: popl %esi 58 ; X86: popl %edi 59 ; X86: popl %ebx 60 ; X86: popl %ebp 61 ; X86: retl 62 63 ; X86: [[restorebb:LBB0_[0-9]+]]: 64 ; X86: addl $12, %ebp 65 ; X86: jmp [[contbb]] 66 67 ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": 68 ; X86: LBB0_[[catch1bb]]: # %handler1{{$}} 69 ; X86: pushl %ebp 70 ; X86-NOT: pushl 71 ; X86: subl $16, %esp 72 ; X86: addl $12, %ebp 73 ; X86: movl $1, -{{[0-9]+}}(%ebp) 74 ; X86: pushl $2 75 ; X86: calll _f 76 ; X86: movl $[[restorebb]], %eax 77 ; X86-NEXT: addl $16, %esp 78 ; X86-NEXT: popl %ebp 79 ; X86-NEXT: retl 80 81 ; X86: L__ehtable$try_catch_catch: 82 ; X86: $handlerMap$0$try_catch_catch: 83 ; X86: .long 0 84 ; X86: .long "??_R0H@8" 85 ; X86: .long 0 86 ; X86: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA" 87 88 ; X64-LABEL: try_catch_catch: 89 ; X64: pushq %rbp 90 ; X64: .seh_pushreg 5 91 ; X64: pushq %rsi 92 ; X64: .seh_pushreg 6 93 ; X64: pushq %rdi 94 ; X64: .seh_pushreg 7 95 ; X64: pushq %rbx 96 ; X64: .seh_pushreg 3 97 ; X64: subq $40, %rsp 98 ; X64: .seh_stackalloc 40 99 ; X64: leaq 32(%rsp), %rbp 100 ; X64: .seh_setframe 5, 32 101 ; X64: .seh_endprologue 102 ; X64: movq $-2, (%rbp) 103 ; X64: callq getint 104 ; X64: callq getint 105 ; X64: callq getint 106 ; X64: callq getint 107 ; X64: callq useints 108 ; X64: movl $1, %ecx 109 ; X64: callq f 110 ; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken 111 ; X64-NEXT: # %try.cont 112 ; X64: addq $40, %rsp 113 ; X64: popq %rbp 114 ; X64: retq 115 116 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": 117 ; X64: LBB0_[[catch1bb]]: # %handler1{{$}} 118 ; X64: movq %rdx, 16(%rsp) 119 ; X64: pushq %rbp 120 ; X64: .seh_pushreg 5 121 ; X64: pushq %rsi 122 ; X64: .seh_pushreg 6 123 ; X64: pushq %rdi 124 ; X64: .seh_pushreg 7 125 ; X64: pushq %rbx 126 ; X64: .seh_pushreg 3 127 ; X64: subq $40, %rsp 128 ; X64: .seh_stackalloc 40 129 ; X64: leaq 32(%rdx), %rbp 130 ; X64: .seh_endprologue 131 ; X64: movl $2, %ecx 132 ; X64: callq f 133 ; X64: leaq [[contbb]](%rip), %rax 134 ; X64: addq $40, %rsp 135 ; X64: popq %rbx 136 ; X64: popq %rdi 137 ; X64: popq %rsi 138 ; X64: popq %rbp 139 ; X64: retq 140 141 ; X64: $handlerMap$0$try_catch_catch: 142 ; X64: .long 0 143 ; X64: .long "??_R0H@8"@IMGREL 144 ; X64: .long 0 145 ; X64: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL 146 ; X64: .long 88 147 148 define i32 @try_one_csr() personality i32 (...)* @__CxxFrameHandler3 { 149 entry: 150 %a = call i32 @getint() 151 %b = call i32 @getint() 152 call void (...) @useints(i32 %a) 153 invoke void @f(i32 1) 154 to label %try.cont unwind label %catch.dispatch 155 156 catch.dispatch: 157 %cs = catchswitch within none [label %handler1] unwind to caller 158 159 handler1: 160 %0 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 161 catchret from %0 to label %try.cont 162 163 try.cont: 164 ret i32 0 165 } 166 167 ; X64-LABEL: try_one_csr: 168 ; X64: pushq %rbp 169 ; X64: .seh_pushreg 5 170 ; X64: pushq %rsi 171 ; X64: .seh_pushreg 6 172 ; X64-NOT: pushq 173 ; X64: subq $40, %rsp 174 ; X64: .seh_stackalloc 40 175 ; X64: leaq 32(%rsp), %rbp 176 ; X64: .seh_setframe 5, 32 177 ; X64: .seh_endprologue 178 ; X64: callq getint 179 ; X64: callq getint 180 ; X64: callq useints 181 ; X64: movl $1, %ecx 182 ; X64: callq f 183 ; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken 184 ; X64-NEXT: # %try.cont 185 ; X64: addq $40, %rsp 186 ; X64-NOT: popq 187 ; X64: popq %rsi 188 ; X64: popq %rbp 189 ; X64: retq 190 191 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_one_csr@4HA": 192 ; X64: LBB1_[[catch1bb]]: # %handler1{{$}} 193 ; X64: movq %rdx, 16(%rsp) 194 ; X64: pushq %rbp 195 ; X64: .seh_pushreg 5 196 ; X64: pushq %rsi 197 ; X64: .seh_pushreg 6 198 ; X64: subq $40, %rsp 199 ; X64: .seh_stackalloc 40 200 ; X64: leaq 32(%rdx), %rbp 201 ; X64: .seh_endprologue 202 ; X64: leaq [[contbb]](%rip), %rax 203 ; X64: addq $40, %rsp 204 ; X64: popq %rsi 205 ; X64: popq %rbp 206 ; X64: retq 207 208 ; X64: $handlerMap$0$try_one_csr: 209 ; X64: .long 0 210 ; X64: .long "??_R0H@8"@IMGREL 211 ; X64: .long 0 212 ; X64: .long "?catch$[[catch1bb]]@?0?try_one_csr@4HA"@IMGREL 213 ; X64: .long 72 214 215 define i32 @try_no_csr() personality i32 (...)* @__CxxFrameHandler3 { 216 entry: 217 invoke void @f(i32 1) 218 to label %try.cont unwind label %catch.dispatch 219 220 catch.dispatch: 221 %cs = catchswitch within none [label %handler1] unwind to caller 222 223 handler1: 224 %cp1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 225 catchret from %cp1 to label %try.cont 226 227 try.cont: 228 ret i32 0 229 } 230 231 ; X64-LABEL: try_no_csr: 232 ; X64: pushq %rbp 233 ; X64: .seh_pushreg 5 234 ; X64-NOT: pushq 235 ; X64: subq $48, %rsp 236 ; X64: .seh_stackalloc 48 237 ; X64: leaq 48(%rsp), %rbp 238 ; X64: .seh_setframe 5, 48 239 ; X64: .seh_endprologue 240 ; X64: movl $1, %ecx 241 ; X64: callq f 242 ; X64: [[contbb:\.LBB2_[0-9]+]]: # Block address taken 243 ; X64-NEXT: # %try.cont 244 ; X64: addq $48, %rsp 245 ; X64-NOT: popq 246 ; X64: popq %rbp 247 ; X64: retq 248 249 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_no_csr@4HA": 250 ; X64: LBB2_[[catch1bb]]: # %handler1{{$}} 251 ; X64: movq %rdx, 16(%rsp) 252 ; X64: pushq %rbp 253 ; X64: .seh_pushreg 5 254 ; X64: subq $32, %rsp 255 ; X64: .seh_stackalloc 32 256 ; X64: leaq 48(%rdx), %rbp 257 ; X64: .seh_endprologue 258 ; X64: leaq [[contbb]](%rip), %rax 259 ; X64: addq $32, %rsp 260 ; X64: popq %rbp 261 ; X64: retq 262 263 ; X64: $handlerMap$0$try_no_csr: 264 ; X64: .long 0 265 ; X64: .long "??_R0H@8"@IMGREL 266 ; X64: .long 0 267 ; X64: .long "?catch$[[catch1bb]]@?0?try_no_csr@4HA"@IMGREL 268 ; X64: .long 56 269