366 lines · plain
1; RUN: llc -stack-symbol-ordering=0 -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s2; RUN: llc -stack-symbol-ordering=0 -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s3 4; Loosely based on IR for this C++ source code:5; void f(int p);6; int main() {7; try {8; f(1);9; } catch (int e) {10; f(e);11; } catch (...) {12; f(3);13; }14; }15 16%rtti.TypeDescriptor2 = type { ptr, ptr, [3 x i8] }17%eh.CatchableType = type { i32, ptr, i32, i32, i32, i32, ptr }18%eh.CatchableTypeArray.1 = type { i32, [1 x ptr] }19%eh.ThrowInfo = type { i32, ptr, ptr, ptr }20 21$"\01??_R0H@8" = comdat any22 23@"\01??_7type_info@@6B@" = external constant ptr24@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { ptr @"\01??_7type_info@@6B@", ptr null, [3 x i8] c".H\00" }, comdat25 26 27declare void @f(i32 %p, ptr %l)28declare i1 @getbool()29declare i32 @__CxxFrameHandler3(...)30 31define i32 @try_catch_catch() personality ptr @__CxxFrameHandler3 {32entry:33 %e.addr = alloca i3234 %local = alloca i3235 invoke void @f(i32 1, ptr %local)36 to label %try.cont unwind label %catch.dispatch37 38catch.dispatch: ; preds = %entry39 %cs = catchswitch within none [label %handler1, label %handler2] unwind to caller40 41handler1:42 %h1 = catchpad within %cs [ptr @"\01??_R0H@8", i32 0, ptr %e.addr]43 %e = load i32, ptr %e.addr44 call void @f(i32 %e, ptr %local) [ "funclet"(token %h1) ]45 catchret from %h1 to label %try.cont46 47handler2:48 %h2 = catchpad within %cs [ptr null, i32 64, ptr null]49 call void @f(i32 3, ptr %local) [ "funclet"(token %h2) ]50 catchret from %h2 to label %try.cont51 52try.cont:53 ret i32 054}55 56; X86-LABEL: _try_catch_catch:57; X86: movl %esp, -[[sp_offset:[0-9]+]](%ebp)58; X86: movl $0, -{{[0-9]+}}(%ebp)59; X86: leal -[[local_offs:[0-9]+]](%ebp), %[[addr_reg:[a-z]+]]60; X86-DAG: pushl %[[addr_reg]]61; X86-DAG: pushl $162; X86: calll _f63; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont64; X86: retl65 66; FIXME: These should be de-duplicated.67; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken68; X86-NEXT: # %handler169; X86-NEXT: addl $12, %ebp70; X86: jmp [[contbb]]71 72; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken73; X86-NEXT: # %handler274; X86-NEXT: addl $12, %ebp75; X86: jmp [[contbb]]76 77; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":78; X86: LBB0_[[catch1bb]]: # %handler1{{$}}79; X86: pushl %ebp80; X86: subl $8, %esp81; X86: addl $12, %ebp82; X86: movl %esp, -[[sp_offset]](%ebp)83; X86-DAG: movl -32(%ebp), %[[e_reg:[a-z]+]]84; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]85; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)86; X86: pushl %[[addr_reg]]87; X86: pushl %[[e_reg]]88; X86: calll _f89; X86: addl $8, %esp90; X86: movl $[[restorebb1]], %eax91; X86: addl $8, %esp92; X86: popl %ebp93; X86: retl94 95; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":96; X86: LBB0_[[catch2bb]]: # %handler2{{$}}97; X86: pushl %ebp98; X86: subl $8, %esp99; X86: addl $12, %ebp100; X86: movl %esp, -[[sp_offset]](%ebp)101; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]102; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)103; X86: pushl %[[addr_reg]]104; X86: pushl $3105; X86: calll _f106; X86: addl $8, %esp107; X86: movl $[[restorebb2]], %eax108; X86: addl $8, %esp109; X86: popl %ebp110; X86: retl111 112; X86: L__ehtable$try_catch_catch:113; X86: $handlerMap$0$try_catch_catch:114; X86-NEXT: .long 0115; X86-NEXT: .long "??_R0H@8"116; X86-NEXT: .long -20117; X86-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"118; X86-NEXT: .long 64119; X86-NEXT: .long 0120; X86-NEXT: .long 0121; X86-NEXT: .long "?catch$[[catch2bb]]@?0?try_catch_catch@4HA"122 123; X64-LABEL: try_catch_catch:124; X64: Lfunc_begin0:125; X64: pushq %rbp126; X64: .seh_pushreg %rbp127; X64: subq $[[STCK_ALLOC:.*]], %rsp128; X64: .seh_stackalloc [[STCK_ALLOC]]129; X64: leaq [[STCK_ALLOC]](%rsp), %rbp130; X64: .seh_setframe %rbp, [[STCK_ALLOC]]131; X64: .seh_endprologue132; X64: movq $-2, -16(%rbp)133; X64: .Ltmp0134; X64-DAG: leaq -[[local_offs:[0-9]+]](%rbp), %rdx135; X64-DAG: movl $1, %ecx136; X64: callq f137; X64: [[contbb:\.LBB0_[0-9]+]]: # Block address taken138; X64-NEXT: # %try.cont139; X64: .seh_startepilogue140; X64: addq $[[STCK_ALLOC]], %rsp141; X64: popq %rbp142; X64: .seh_endepilogue143; X64: retq144 145; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":146; X64: LBB0_[[catch1bb]]: # %handler1{{$}}147; X64: movq %rdx, 16(%rsp)148; X64: pushq %rbp149; X64: .seh_pushreg %rbp150; X64: subq $32, %rsp151; X64: .seh_stackalloc 32152; X64: leaq [[STCK_ALLOC]](%rdx), %rbp153; X64: .seh_endprologue154; X64-DAG: leaq -[[local_offs]](%rbp), %rdx155; X64-DAG: movl -4(%rbp), %ecx156; X64: callq f157; X64: leaq [[contbb]](%rip), %rax158; X64-NEXT: .seh_startepilogue159; X64-NEXT: addq $32, %rsp160; X64-NEXT: popq %rbp161; X64-NEXT: .seh_endepilogue162; X64-NEXT: retq163 164; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":165; X64: LBB0_[[catch2bb]]: # %handler2{{$}}166; X64: movq %rdx, 16(%rsp)167; X64: pushq %rbp168; X64: .seh_pushreg %rbp169; X64: subq $32, %rsp170; X64: .seh_stackalloc 32171; X64: leaq [[STCK_ALLOC]](%rdx), %rbp172; X64: .seh_endprologue173; X64-DAG: leaq -[[local_offs]](%rbp), %rdx174; X64-DAG: movl $3, %ecx175; X64: callq f176; X64: leaq [[contbb]](%rip), %rax177; X64-NEXT: .seh_startepilogue178; X64-NEXT: addq $32, %rsp179; X64-NEXT: popq %rbp180; X64-NEXT: .seh_endepilogue181; X64-NEXT: retq182 183; X64: $cppxdata$try_catch_catch:184; X64-NEXT: .long 429065506185; X64-NEXT: .long 2186; X64-NEXT: .long $stateUnwindMap$try_catch_catch@IMGREL187; X64-NEXT: .long 1188; X64-NEXT: .long $tryMap$try_catch_catch@IMGREL189; X64-NEXT: .long 5190; X64-NEXT: .long $ip2state$try_catch_catch@IMGREL191; X64-NEXT: .long 48192; X64-NEXT: .long 0193; X64-NEXT: .long 1194 195; X64: $tryMap$try_catch_catch:196; X64-NEXT: .long 0197; X64-NEXT: .long 0198; X64-NEXT: .long 1199; X64-NEXT: .long 2200; X64-NEXT: .long $handlerMap$0$try_catch_catch@IMGREL201 202; X64: $handlerMap$0$try_catch_catch:203; X64-NEXT: .long 0204; X64-NEXT: .long "??_R0H@8"@IMGREL205; X64-NEXT: .long 60206; X64-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL207; X64-NEXT: .long 56208; X64-NEXT: .long 64209; X64-NEXT: .long 0210; X64-NEXT: .long 0211; X64-NEXT: .long "?catch$[[catch2bb]]@?0?try_catch_catch@4HA"@IMGREL212; X64-NEXT: .long 56213 214; X64: $ip2state$try_catch_catch:215; X64-NEXT: .long .Lfunc_begin0@IMGREL216; X64-NEXT: .long -1217; X64-NEXT: .long .Ltmp0@IMGREL218; X64-NEXT: .long 0219; X64-NEXT: .long .Ltmp1@IMGREL220; X64-NEXT: .long -1221; X64-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL222; X64-NEXT: .long 1223; X64-NEXT: .long "?catch$[[catch2bb]]@?0?try_catch_catch@4HA"@IMGREL224; X64-NEXT: .long 1225 226 227define i32 @branch_to_normal_dest() personality ptr @__CxxFrameHandler3 {228entry:229 invoke void @f(i32 1, ptr null)230 to label %try.cont unwind label %catch.dispatch231 232catch.dispatch:233 %cs1 = catchswitch within none [label %catch] unwind to caller234 235catch:236 %cp1 = catchpad within %cs1 [ptr null, i32 64, ptr null]237 br label %loop238 239loop:240 %V = call i1 @getbool() [ "funclet"(token %cp1) ]241 br i1 %V, label %loop, label %catch.done242 243catch.done:244 catchret from %cp1 to label %try.cont245 246try.cont:247 ret i32 0248}249 250; X86-LABEL: _branch_to_normal_dest:251; X86: calll _f252 253; X86: [[contbb:LBB1_[0-9]+]]: # %try.cont254; X86: retl255 256; X86: [[restorebb:LBB1_[0-9]+]]: # Block address taken257; X86-NEXT: # %catch.done258; X86-NEXT: addl $12, %ebp259; X86: jmp [[contbb]]260 261; X86: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":262; X86: LBB1_[[catchbb]]: # %catch{{$}}263; X86: pushl %ebp264; X86: subl $8, %esp265; X86: addl $12, %ebp266; X86: movl $1, -16(%ebp)267; X86: LBB1_[[loopbb:[0-9]+]]: # %loop268; X86: calll _getbool269; X86: testb $1, %al270; X86: jne LBB1_[[loopbb]]271; X86: # %catch.done272; X86-NEXT: movl $[[restorebb]], %eax273; X86-NEXT: addl $8, %esp274; X86-NEXT: popl %ebp275; X86-NEXT: retl276 277; X86: L__ehtable$branch_to_normal_dest:278; X86: $handlerMap$0$branch_to_normal_dest:279; X86-NEXT: .long 64280; X86-NEXT: .long 0281; X86-NEXT: .long 0282; X86-NEXT: .long "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"283 284; X64-LABEL: branch_to_normal_dest:285; X64: # %entry286; X64: pushq %rbp287; X64: .seh_pushreg %rbp288; X64: subq $48, %rsp289; X64: .seh_stackalloc 48290; X64: leaq 48(%rsp), %rbp291; X64: .seh_setframe %rbp, 48292; X64: .seh_endprologue293; X64: .Ltmp[[before_call:[0-9]+]]:294; X64: callq f295; X64: .Ltmp[[after_call:[0-9]+]]:296; X64: [[contbb:\.LBB1_[0-9]+]]: # Block address taken297; X64-NEXT: # %try.cont298; X64: .seh_startepilogue299; X64: addq $48, %rsp300; X64: popq %rbp301; X64: .seh_endepilogue302; X64: retq303 304; X64: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":305; X64: LBB1_[[catchbb]]: # %catch{{$}}306; X64: movq %rdx, 16(%rsp)307; X64: pushq %rbp308; X64: .seh_pushreg %rbp309; X64: subq $32, %rsp310; X64: .seh_stackalloc 32311; X64: leaq 48(%rdx), %rbp312; X64: .seh_endprologue313; X64: .LBB1_[[normal_dest_bb:[0-9]+]]: # %loop314; X64: callq getbool315; X64: testb $1, %al316; X64: jne .LBB1_[[normal_dest_bb]]317; X64: # %catch.done318; X64: leaq [[contbb]](%rip), %rax319; X64-NEXT: .seh_startepilogue320; X64-NEXT: addq $32, %rsp321; X64-NEXT: popq %rbp322; X64-NEXT: .seh_endepilogue323; X64-NEXT: retq324 325; X64-LABEL: $cppxdata$branch_to_normal_dest:326; X64-NEXT: .long 429065506327; X64-NEXT: .long 2328; X64-NEXT: .long $stateUnwindMap$branch_to_normal_dest@IMGREL329; X64-NEXT: .long 1330; X64-NEXT: .long $tryMap$branch_to_normal_dest@IMGREL331; X64-NEXT: .long 4332; X64-NEXT: .long $ip2state$branch_to_normal_dest@IMGREL333; X64-NEXT: .long 40334; X64-NEXT: .long 0335; X64-NEXT: .long 1336 337; X64-LABEL: $stateUnwindMap$branch_to_normal_dest:338; X64-NEXT: .long -1339; X64-NEXT: .long 0340; X64-NEXT: .long -1341; X64-NEXT: .long 0342 343; X64-LABEL: $tryMap$branch_to_normal_dest:344; X64-NEXT: .long 0345; X64-NEXT: .long 0346; X64-NEXT: .long 1347; X64-NEXT: .long 1348; X64-NEXT: .long $handlerMap$0$branch_to_normal_dest@IMGREL349 350; X64-LABEL: $handlerMap$0$branch_to_normal_dest:351; X64-NEXT: .long 64352; X64-NEXT: .long 0353; X64-NEXT: .long 0354; X64-NEXT: .long "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"@IMGREL355; X64-NEXT: .long 56356 357; X64-LABEL: $ip2state$branch_to_normal_dest:358; X64-NEXT: .long .Lfunc_begin1@IMGREL359; X64-NEXT: .long -1360; X64-NEXT: .long .Ltmp[[before_call]]@IMGREL361; X64-NEXT: .long 0362; X64-NEXT: .long .Ltmp[[after_call]]@IMGREL363; X64-NEXT: .long -1364; X64-NEXT: .long "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"@IMGREL365; X64-NEXT: .long 1366