437 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 22; RUN: llc -mtriple=x86_64-apple-darwin10.6 < %s | FileCheck %s3; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s --check-prefix=NOCOMPACTUNWIND4;5; Note: This test cannot be merged with the shrink-wrapping tests6; because the booleans set on the command line take precedence on7; the target logic that disable shrink-wrapping.8 9; The current compact unwind scheme does not work when the prologue is not at10; the start (the instructions before the prologue cannot be described).11; Currently we choose to not perform shrink-wrapping for functions without FP12; not marked as nounwind. PR2561413;14; No shrink-wrapping should occur here, until the CFI information are fixed.15 16define i32 @framelessUnwind(i32 %a, i32 %b) #0 {17; CHECK-LABEL: framelessUnwind:18; CHECK: ## %bb.0:19; CHECK-NEXT: pushq %rax20; CHECK-NEXT: .cfi_def_cfa_offset 1621; CHECK-NEXT: movl %edi, %eax22; CHECK-NEXT: cmpl %esi, %edi23; CHECK-NEXT: jge LBB0_224; CHECK-NEXT: ## %bb.1: ## %true25; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)26; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi27; CHECK-NEXT: xorl %edi, %edi28; CHECK-NEXT: callq _doSomething29; CHECK-NEXT: LBB0_2: ## %false30; CHECK-NEXT: popq %rcx31; CHECK-NEXT: retq32;33; NOCOMPACTUNWIND-LABEL: framelessUnwind:34; NOCOMPACTUNWIND: # %bb.0:35; NOCOMPACTUNWIND-NEXT: movl %edi, %eax36; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi37; NOCOMPACTUNWIND-NEXT: jge .LBB0_238; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true39; NOCOMPACTUNWIND-NEXT: pushq %rax40; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 1641; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)42; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi43; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi44; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT45; NOCOMPACTUNWIND-NEXT: addq $8, %rsp46; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 847; NOCOMPACTUNWIND-NEXT: .LBB0_2: # %false48; NOCOMPACTUNWIND-NEXT: retq49 %tmp = alloca i32, align 450 %tmp2 = icmp slt i32 %a, %b51 br i1 %tmp2, label %true, label %false52 53true:54 store i32 %a, ptr %tmp, align 455 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)56 br label %false57 58false:59 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]60 ret i32 %tmp.061}62 63declare i32 @doSomething(i32, ptr)64 65attributes #0 = { "frame-pointer"="none" }66 67; Shrink-wrapping should occur here. We have a frame pointer.68define i32 @frameUnwind(i32 %a, i32 %b) #1 {69; CHECK-LABEL: frameUnwind:70; CHECK: ## %bb.0:71; CHECK-NEXT: movl %edi, %eax72; CHECK-NEXT: cmpl %esi, %edi73; CHECK-NEXT: jge LBB1_274; CHECK-NEXT: ## %bb.1: ## %true75; CHECK-NEXT: pushq %rbp76; CHECK-NEXT: .cfi_def_cfa_offset 1677; CHECK-NEXT: .cfi_offset %rbp, -1678; CHECK-NEXT: movq %rsp, %rbp79; CHECK-NEXT: .cfi_def_cfa_register %rbp80; CHECK-NEXT: subq $16, %rsp81; CHECK-NEXT: movl %eax, -4(%rbp)82; CHECK-NEXT: leaq -4(%rbp), %rsi83; CHECK-NEXT: xorl %edi, %edi84; CHECK-NEXT: callq _doSomething85; CHECK-NEXT: addq $16, %rsp86; CHECK-NEXT: popq %rbp87; CHECK-NEXT: LBB1_2: ## %false88; CHECK-NEXT: retq89;90; NOCOMPACTUNWIND-LABEL: frameUnwind:91; NOCOMPACTUNWIND: # %bb.0:92; NOCOMPACTUNWIND-NEXT: movl %edi, %eax93; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi94; NOCOMPACTUNWIND-NEXT: jge .LBB1_295; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true96; NOCOMPACTUNWIND-NEXT: pushq %rbp97; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 1698; NOCOMPACTUNWIND-NEXT: .cfi_offset %rbp, -1699; NOCOMPACTUNWIND-NEXT: movq %rsp, %rbp100; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_register %rbp101; NOCOMPACTUNWIND-NEXT: subq $16, %rsp102; NOCOMPACTUNWIND-NEXT: movl %eax, -4(%rbp)103; NOCOMPACTUNWIND-NEXT: leaq -4(%rbp), %rsi104; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi105; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT106; NOCOMPACTUNWIND-NEXT: addq $16, %rsp107; NOCOMPACTUNWIND-NEXT: popq %rbp108; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa %rsp, 8109; NOCOMPACTUNWIND-NEXT: .cfi_restore %rbp110; NOCOMPACTUNWIND-NEXT: .LBB1_2: # %false111; NOCOMPACTUNWIND-NEXT: retq112 %tmp = alloca i32, align 4113 %tmp2 = icmp slt i32 %a, %b114 br i1 %tmp2, label %true, label %false115 116true:117 store i32 %a, ptr %tmp, align 4118 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)119 br label %false120 121false:122 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]123 ret i32 %tmp.0124}125 126attributes #1 = { "frame-pointer"="all" }127 128; Shrink-wrapping should occur here. We do not have to unwind.129define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {130; CHECK-LABEL: framelessnoUnwind:131; CHECK: ## %bb.0:132; CHECK-NEXT: movl %edi, %eax133; CHECK-NEXT: cmpl %esi, %edi134; CHECK-NEXT: jge LBB2_2135; CHECK-NEXT: ## %bb.1: ## %true136; CHECK-NEXT: pushq %rax137; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)138; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi139; CHECK-NEXT: xorl %edi, %edi140; CHECK-NEXT: callq _doSomething141; CHECK-NEXT: addq $8, %rsp142; CHECK-NEXT: LBB2_2: ## %false143; CHECK-NEXT: retq144;145; NOCOMPACTUNWIND-LABEL: framelessnoUnwind:146; NOCOMPACTUNWIND: # %bb.0:147; NOCOMPACTUNWIND-NEXT: movl %edi, %eax148; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi149; NOCOMPACTUNWIND-NEXT: jge .LBB2_2150; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true151; NOCOMPACTUNWIND-NEXT: pushq %rax152; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)153; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi154; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi155; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT156; NOCOMPACTUNWIND-NEXT: addq $8, %rsp157; NOCOMPACTUNWIND-NEXT: .LBB2_2: # %false158; NOCOMPACTUNWIND-NEXT: retq159 %tmp = alloca i32, align 4160 %tmp2 = icmp slt i32 %a, %b161 br i1 %tmp2, label %true, label %false162 163true:164 store i32 %a, ptr %tmp, align 4165 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)166 br label %false167 168false:169 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]170 ret i32 %tmp.0171}172 173attributes #2 = { "frame-pointer"="none" nounwind }174 175 176; Check that we generate correct code for segmented stack.177; We used to emit the code at the entry point of the function178; instead of just before the prologue.179; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.180define zeroext i1 @segmentedStack(ptr readonly %vk1, ptr readonly %vk2, i64 %key_size) #5 {181; CHECK-LABEL: segmentedStack:182; CHECK: ## %bb.0:183; CHECK-NEXT: cmpq %gs:816, %rsp184; CHECK-NEXT: jbe LBB3_7185; CHECK-NEXT: LBB3_1: ## %entry186; CHECK-NEXT: pushq %rax187; CHECK-NEXT: .cfi_def_cfa_offset 16188; CHECK-NEXT: movq %rdi, %rax189; CHECK-NEXT: orq %rsi, %rax190; CHECK-NEXT: sete %al191; CHECK-NEXT: testq %rdi, %rdi192; CHECK-NEXT: je LBB3_5193; CHECK-NEXT: ## %bb.2: ## %entry194; CHECK-NEXT: testq %rsi, %rsi195; CHECK-NEXT: je LBB3_5196; CHECK-NEXT: ## %bb.3: ## %if.end4.i197; CHECK-NEXT: movq 8(%rdi), %rdx198; CHECK-NEXT: cmpq 8(%rsi), %rdx199; CHECK-NEXT: jne LBB3_6200; CHECK-NEXT: ## %bb.4: ## %land.rhs.i.i201; CHECK-NEXT: movq (%rsi), %rsi202; CHECK-NEXT: movq (%rdi), %rdi203; CHECK-NEXT: callq _memcmp204; CHECK-NEXT: testl %eax, %eax205; CHECK-NEXT: sete %al206; CHECK-NEXT: LBB3_5: ## %__go_ptr_strings_equal.exit207; CHECK-NEXT: ## kill: def $al killed $al killed $eax208; CHECK-NEXT: popq %rcx209; CHECK-NEXT: retq210; CHECK-NEXT: LBB3_6:211; CHECK-NEXT: xorl %eax, %eax212; CHECK-NEXT: ## kill: def $al killed $al killed $eax213; CHECK-NEXT: popq %rcx214; CHECK-NEXT: retq215; CHECK-NEXT: LBB3_7:216; CHECK-NEXT: movl $8, %r10d217; CHECK-NEXT: movl $0, %r11d218; CHECK-NEXT: callq ___morestack219; CHECK-NEXT: retq220; CHECK-NEXT: jmp LBB3_1221;222; NOCOMPACTUNWIND-LABEL: segmentedStack:223; NOCOMPACTUNWIND: # %bb.0:224; NOCOMPACTUNWIND-NEXT: cmpq %fs:112, %rsp225; NOCOMPACTUNWIND-NEXT: jbe .LBB3_7226; NOCOMPACTUNWIND-NEXT: .LBB3_1: # %entry227; NOCOMPACTUNWIND-NEXT: pushq %rax228; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16229; NOCOMPACTUNWIND-NEXT: movq %rdi, %rax230; NOCOMPACTUNWIND-NEXT: orq %rsi, %rax231; NOCOMPACTUNWIND-NEXT: sete %al232; NOCOMPACTUNWIND-NEXT: testq %rdi, %rdi233; NOCOMPACTUNWIND-NEXT: je .LBB3_5234; NOCOMPACTUNWIND-NEXT: # %bb.2: # %entry235; NOCOMPACTUNWIND-NEXT: testq %rsi, %rsi236; NOCOMPACTUNWIND-NEXT: je .LBB3_5237; NOCOMPACTUNWIND-NEXT: # %bb.3: # %if.end4.i238; NOCOMPACTUNWIND-NEXT: movq 8(%rdi), %rdx239; NOCOMPACTUNWIND-NEXT: cmpq 8(%rsi), %rdx240; NOCOMPACTUNWIND-NEXT: jne .LBB3_6241; NOCOMPACTUNWIND-NEXT: # %bb.4: # %land.rhs.i.i242; NOCOMPACTUNWIND-NEXT: movq (%rsi), %rsi243; NOCOMPACTUNWIND-NEXT: movq (%rdi), %rdi244; NOCOMPACTUNWIND-NEXT: callq memcmp@PLT245; NOCOMPACTUNWIND-NEXT: testl %eax, %eax246; NOCOMPACTUNWIND-NEXT: sete %al247; NOCOMPACTUNWIND-NEXT: .LBB3_5: # %__go_ptr_strings_equal.exit248; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax249; NOCOMPACTUNWIND-NEXT: popq %rcx250; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8251; NOCOMPACTUNWIND-NEXT: retq252; NOCOMPACTUNWIND-NEXT: .LBB3_6:253; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16254; NOCOMPACTUNWIND-NEXT: xorl %eax, %eax255; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax256; NOCOMPACTUNWIND-NEXT: popq %rcx257; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8258; NOCOMPACTUNWIND-NEXT: retq259; NOCOMPACTUNWIND-NEXT: .LBB3_7:260; NOCOMPACTUNWIND-NEXT: movl $8, %r10d261; NOCOMPACTUNWIND-NEXT: movl $0, %r11d262; NOCOMPACTUNWIND-NEXT: callq __morestack263; NOCOMPACTUNWIND-NEXT: retq264; NOCOMPACTUNWIND-NEXT: jmp .LBB3_1265entry:266 %cmp.i = icmp eq ptr %vk1, null267 %cmp1.i = icmp eq ptr %vk2, null268 %brmerge.i = or i1 %cmp.i, %cmp1.i269 %cmp1.mux.i = and i1 %cmp.i, %cmp1.i270 br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i271 272if.end4.i: ; preds = %entry273 %tmp = getelementptr inbounds i8, ptr %vk1, i64 8274 %tmp2 = load i64, ptr %tmp, align 8275 %tmp3 = getelementptr inbounds i8, ptr %vk2, i64 8276 %tmp5 = load i64, ptr %tmp3, align 8277 %cmp.i.i = icmp eq i64 %tmp2, %tmp5278 br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit279 280land.rhs.i.i: ; preds = %if.end4.i281 %tmp7 = load ptr, ptr %vk2, align 8282 %tmp9 = load ptr, ptr %vk1, align 8283 %call.i.i = tail call i32 @memcmp(ptr %tmp9, ptr %tmp7, i64 %tmp2) #5284 %cmp4.i.i = icmp eq i32 %call.i.i, 0285 br label %__go_ptr_strings_equal.exit286 287__go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.end4.i, %entry288 %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]289 ret i1 %retval.0.i290}291 292; Function Attrs: nounwind readonly293declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) #5294 295attributes #5 = { nounwind readonly ssp uwtable "split-stack" }296 297; Check that correctly take into account the jumps to landing pad.298; We used to consider function that may throw like regular299; function calls.300; Therefore, in this example, we were happily inserting the epilogue301; right after the call to throw_exception. Because of that we would not302; execute the epilogue when an execption occur and bad things will303; happen.304; PR36513305define void @with_nounwind(i1 %cond) nounwind personality ptr @my_personality {306; CHECK-LABEL: with_nounwind:307; CHECK: ## %bb.0: ## %entry308; CHECK-NEXT: pushq %rax309; CHECK-NEXT: .cfi_def_cfa_offset 16310; CHECK-NEXT: testb $1, %dil311; CHECK-NEXT: jne LBB4_1312; CHECK-NEXT: ## %bb.4: ## %return313; CHECK-NEXT: popq %rax314; CHECK-NEXT: retq315; CHECK-NEXT: LBB4_1: ## %throw316; CHECK-NEXT: Ltmp0: ## EH_LABEL317; CHECK-NEXT: callq _throw_exception318; CHECK-NEXT: Ltmp1: ## EH_LABEL319; CHECK-NEXT: ## %bb.2: ## %unreachable320; CHECK-NEXT: ud2321; CHECK-NEXT: LBB4_3: ## %landing322; CHECK-NEXT: Ltmp2: ## EH_LABEL323; CHECK-NEXT: popq %rax324; CHECK-NEXT: retq325; CHECK-NEXT: Lfunc_end0:326;327; NOCOMPACTUNWIND-LABEL: with_nounwind:328; NOCOMPACTUNWIND: # %bb.0: # %entry329; NOCOMPACTUNWIND-NEXT: pushq %rax330; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16331; NOCOMPACTUNWIND-NEXT: testb $1, %dil332; NOCOMPACTUNWIND-NEXT: jne .LBB4_1333; NOCOMPACTUNWIND-NEXT: # %bb.4: # %return334; NOCOMPACTUNWIND-NEXT: popq %rax335; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8336; NOCOMPACTUNWIND-NEXT: retq337; NOCOMPACTUNWIND-NEXT: .LBB4_1: # %throw338; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16339; NOCOMPACTUNWIND-NEXT: .Ltmp0: # EH_LABEL340; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT341; NOCOMPACTUNWIND-NEXT: .Ltmp1: # EH_LABEL342; NOCOMPACTUNWIND-NEXT: # %bb.2: # %unreachable343; NOCOMPACTUNWIND-NEXT: .LBB4_3: # %landing344; NOCOMPACTUNWIND-NEXT: .Ltmp2: # EH_LABEL345; NOCOMPACTUNWIND-NEXT: popq %rax346; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8347; NOCOMPACTUNWIND-NEXT: retq348entry:349 br i1 %cond, label %throw, label %return350 351throw:352 invoke void @throw_exception()353 to label %unreachable unwind label %landing354 355unreachable:356 unreachable357 358landing:359 %pad = landingpad { ptr, i32 }360 catch ptr null361 ret void362 363return:364 ret void365}366 367; Check landing pad again.368; This time checks that we can shrink-wrap when the epilogue does not369; span accross several blocks.370define void @with_nounwind_same_succ(i1 %cond) nounwind personality ptr @my_personality2 {371; CHECK-LABEL: with_nounwind_same_succ:372; CHECK: ## %bb.0: ## %entry373; CHECK-NEXT: testb $1, %dil374; CHECK-NEXT: je LBB5_4375; CHECK-NEXT: ## %bb.1: ## %throw376; CHECK-NEXT: pushq %rax377; CHECK-NEXT: .cfi_def_cfa_offset 16378; CHECK-NEXT: Ltmp3: ## EH_LABEL379; CHECK-NEXT: callq _throw_exception380; CHECK-NEXT: Ltmp4: ## EH_LABEL381; CHECK-NEXT: LBB5_3: ## %fallthrough382; CHECK-NEXT: ## InlineAsm Start383; CHECK-NEXT: nop384; CHECK-NEXT: ## InlineAsm End385; CHECK-NEXT: popq %rax386; CHECK-NEXT: LBB5_4: ## %return387; CHECK-NEXT: retq388; CHECK-NEXT: LBB5_2: ## %landing389; CHECK-NEXT: Ltmp5: ## EH_LABEL390; CHECK-NEXT: jmp LBB5_3391; CHECK-NEXT: Lfunc_end1:392;393; NOCOMPACTUNWIND-LABEL: with_nounwind_same_succ:394; NOCOMPACTUNWIND: # %bb.0: # %entry395; NOCOMPACTUNWIND-NEXT: testb $1, %dil396; NOCOMPACTUNWIND-NEXT: je .LBB5_4397; NOCOMPACTUNWIND-NEXT: # %bb.1: # %throw398; NOCOMPACTUNWIND-NEXT: pushq %rax399; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16400; NOCOMPACTUNWIND-NEXT: .Ltmp3: # EH_LABEL401; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT402; NOCOMPACTUNWIND-NEXT: .Ltmp4: # EH_LABEL403; NOCOMPACTUNWIND-NEXT: .LBB5_3: # %fallthrough404; NOCOMPACTUNWIND-NEXT: #APP405; NOCOMPACTUNWIND-NEXT: nop406; NOCOMPACTUNWIND-NEXT: #NO_APP407; NOCOMPACTUNWIND-NEXT: popq %rax408; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8409; NOCOMPACTUNWIND-NEXT: .LBB5_4: # %return410; NOCOMPACTUNWIND-NEXT: retq411; NOCOMPACTUNWIND-NEXT: .LBB5_2: # %landing412; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16413; NOCOMPACTUNWIND-NEXT: .Ltmp5: # EH_LABEL414; NOCOMPACTUNWIND-NEXT: jmp .LBB5_3415entry:416 br i1 %cond, label %throw, label %return417 418throw:419 invoke void @throw_exception()420 to label %fallthrough unwind label %landing421landing:422 %pad = landingpad { ptr, i32 }423 catch ptr null424 br label %fallthrough425 426fallthrough:427 tail call void asm "nop", ""()428 br label %return429 430return:431 ret void432}433 434declare void @throw_exception()435declare i32 @my_personality(...)436declare i32 @my_personality2(...)437