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 14declare i32 @getint() 15declare void @useints(...) 16declare void @f(i32 %p) 17declare i32 @__CxxFrameHandler3(...) 18 19define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 { 20entry: 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 29try.cont: 30 ret i32 0 31 32catch.dispatch: 33 %cs = catchswitch within none [label %handler1] unwind to caller 34 35handler1: 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 %rbp 91; X64: pushq %rsi 92; X64: .seh_pushreg %rsi 93; X64: pushq %rdi 94; X64: .seh_pushreg %rdi 95; X64: pushq %rbx 96; X64: .seh_pushreg %rbx 97; X64: subq $40, %rsp 98; X64: .seh_stackalloc 40 99; X64: leaq 32(%rsp), %rbp 100; X64: .seh_setframe %rbp, 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 %rbp 121; X64: pushq %rsi 122; X64: .seh_pushreg %rsi 123; X64: pushq %rdi 124; X64: .seh_pushreg %rdi 125; X64: pushq %rbx 126; X64: .seh_pushreg %rbx 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 148define i32 @try_one_csr() personality i32 (...)* @__CxxFrameHandler3 { 149entry: 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 156catch.dispatch: 157 %cs = catchswitch within none [label %handler1] unwind to caller 158 159handler1: 160 %0 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 161 catchret from %0 to label %try.cont 162 163try.cont: 164 ret i32 0 165} 166 167; X64-LABEL: try_one_csr: 168; X64: pushq %rbp 169; X64: .seh_pushreg %rbp 170; X64: pushq %rsi 171; X64: .seh_pushreg %rsi 172; X64-NOT: pushq 173; X64: subq $40, %rsp 174; X64: .seh_stackalloc 40 175; X64: leaq 32(%rsp), %rbp 176; X64: .seh_setframe %rbp, 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 %rbp 196; X64: pushq %rsi 197; X64: .seh_pushreg %rsi 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 215define i32 @try_no_csr() personality i32 (...)* @__CxxFrameHandler3 { 216entry: 217 invoke void @f(i32 1) 218 to label %try.cont unwind label %catch.dispatch 219 220catch.dispatch: 221 %cs = catchswitch within none [label %handler1] unwind to caller 222 223handler1: 224 %cp1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] 225 catchret from %cp1 to label %try.cont 226 227try.cont: 228 ret i32 0 229} 230 231; X64-LABEL: try_no_csr: 232; X64: pushq %rbp 233; X64: .seh_pushreg %rbp 234; X64-NOT: pushq 235; X64: subq $48, %rsp 236; X64: .seh_stackalloc 48 237; X64: leaq 48(%rsp), %rbp 238; X64: .seh_setframe %rbp, 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 %rbp 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