436 lines
15 KiB
LLVM
436 lines
15 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
|
|
; RUN: llc -mtriple=x86_64-apple-darwin10.6 < %s | FileCheck %s
|
|
; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s --check-prefix=NOCOMPACTUNWIND
|
|
;
|
|
; Note: This test cannot be merged with the shrink-wrapping tests
|
|
; because the booleans set on the command line take precedence on
|
|
; the target logic that disable shrink-wrapping.
|
|
|
|
; The current compact unwind scheme does not work when the prologue is not at
|
|
; the start (the instructions before the prologue cannot be described).
|
|
; Currently we choose to not perform shrink-wrapping for functions without FP
|
|
; not marked as nounwind. PR25614
|
|
;
|
|
; No shrink-wrapping should occur here, until the CFI information are fixed.
|
|
|
|
define i32 @framelessUnwind(i32 %a, i32 %b) #0 {
|
|
; CHECK-LABEL: framelessUnwind:
|
|
; CHECK: ## %bb.0:
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: cmpl %esi, %edi
|
|
; CHECK-NEXT: jge LBB0_2
|
|
; CHECK-NEXT: ## %bb.1: ## %true
|
|
; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
|
|
; CHECK-NEXT: xorl %edi, %edi
|
|
; CHECK-NEXT: callq _doSomething
|
|
; CHECK-NEXT: LBB0_2: ## %false
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: framelessUnwind:
|
|
; NOCOMPACTUNWIND: # %bb.0:
|
|
; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
|
|
; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: jge .LBB0_2
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)
|
|
; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
|
|
; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
|
|
; NOCOMPACTUNWIND-NEXT: addq $8, %rsp
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: .LBB0_2: # %false
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
%tmp = alloca i32, align 4
|
|
%tmp2 = icmp slt i32 %a, %b
|
|
br i1 %tmp2, label %true, label %false
|
|
|
|
true:
|
|
store i32 %a, ptr %tmp, align 4
|
|
%tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
|
|
br label %false
|
|
|
|
false:
|
|
%tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
|
|
ret i32 %tmp.0
|
|
}
|
|
|
|
declare i32 @doSomething(i32, ptr)
|
|
|
|
attributes #0 = { "frame-pointer"="none" }
|
|
|
|
; Shrink-wrapping should occur here. We have a frame pointer.
|
|
define i32 @frameUnwind(i32 %a, i32 %b) #1 {
|
|
; CHECK-LABEL: frameUnwind:
|
|
; CHECK: ## %bb.0:
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: cmpl %esi, %edi
|
|
; CHECK-NEXT: jge LBB1_2
|
|
; CHECK-NEXT: ## %bb.1: ## %true
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: subq $16, %rsp
|
|
; CHECK-NEXT: movl %eax, -4(%rbp)
|
|
; CHECK-NEXT: leaq -4(%rbp), %rsi
|
|
; CHECK-NEXT: xorl %edi, %edi
|
|
; CHECK-NEXT: callq _doSomething
|
|
; CHECK-NEXT: addq $16, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: LBB1_2: ## %false
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: frameUnwind:
|
|
; NOCOMPACTUNWIND: # %bb.0:
|
|
; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
|
|
; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: jge .LBB1_2
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rbp
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_offset %rbp, -16
|
|
; NOCOMPACTUNWIND-NEXT: movq %rsp, %rbp
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_register %rbp
|
|
; NOCOMPACTUNWIND-NEXT: subq $16, %rsp
|
|
; NOCOMPACTUNWIND-NEXT: movl %eax, -4(%rbp)
|
|
; NOCOMPACTUNWIND-NEXT: leaq -4(%rbp), %rsi
|
|
; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
|
|
; NOCOMPACTUNWIND-NEXT: addq $16, %rsp
|
|
; NOCOMPACTUNWIND-NEXT: popq %rbp
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa %rsp, 8
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_restore %rbp
|
|
; NOCOMPACTUNWIND-NEXT: .LBB1_2: # %false
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
%tmp = alloca i32, align 4
|
|
%tmp2 = icmp slt i32 %a, %b
|
|
br i1 %tmp2, label %true, label %false
|
|
|
|
true:
|
|
store i32 %a, ptr %tmp, align 4
|
|
%tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
|
|
br label %false
|
|
|
|
false:
|
|
%tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
|
|
ret i32 %tmp.0
|
|
}
|
|
|
|
attributes #1 = { "frame-pointer"="all" }
|
|
|
|
; Shrink-wrapping should occur here. We do not have to unwind.
|
|
define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {
|
|
; CHECK-LABEL: framelessnoUnwind:
|
|
; CHECK: ## %bb.0:
|
|
; CHECK-NEXT: movl %edi, %eax
|
|
; CHECK-NEXT: cmpl %esi, %edi
|
|
; CHECK-NEXT: jge LBB2_2
|
|
; CHECK-NEXT: ## %bb.1: ## %true
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)
|
|
; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
|
|
; CHECK-NEXT: xorl %edi, %edi
|
|
; CHECK-NEXT: callq _doSomething
|
|
; CHECK-NEXT: addq $8, %rsp
|
|
; CHECK-NEXT: LBB2_2: ## %false
|
|
; CHECK-NEXT: retq
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: framelessnoUnwind:
|
|
; NOCOMPACTUNWIND: # %bb.0:
|
|
; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
|
|
; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: jge .LBB2_2
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rax
|
|
; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)
|
|
; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
|
|
; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
|
|
; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
|
|
; NOCOMPACTUNWIND-NEXT: addq $8, %rsp
|
|
; NOCOMPACTUNWIND-NEXT: .LBB2_2: # %false
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
%tmp = alloca i32, align 4
|
|
%tmp2 = icmp slt i32 %a, %b
|
|
br i1 %tmp2, label %true, label %false
|
|
|
|
true:
|
|
store i32 %a, ptr %tmp, align 4
|
|
%tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
|
|
br label %false
|
|
|
|
false:
|
|
%tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
|
|
ret i32 %tmp.0
|
|
}
|
|
|
|
attributes #2 = { "frame-pointer"="none" nounwind }
|
|
|
|
|
|
; Check that we generate correct code for segmented stack.
|
|
; We used to emit the code at the entry point of the function
|
|
; instead of just before the prologue.
|
|
; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.
|
|
define zeroext i1 @segmentedStack(ptr readonly %vk1, ptr readonly %vk2, i64 %key_size) #5 {
|
|
; CHECK-LABEL: segmentedStack:
|
|
; CHECK: ## %bb.0:
|
|
; CHECK-NEXT: cmpq %gs:816, %rsp
|
|
; CHECK-NEXT: jbe LBB3_7
|
|
; CHECK-NEXT: LBB3_1: ## %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: movq %rdi, %rax
|
|
; CHECK-NEXT: orq %rsi, %rax
|
|
; CHECK-NEXT: sete %al
|
|
; CHECK-NEXT: testq %rdi, %rdi
|
|
; CHECK-NEXT: je LBB3_5
|
|
; CHECK-NEXT: ## %bb.2: ## %entry
|
|
; CHECK-NEXT: testq %rsi, %rsi
|
|
; CHECK-NEXT: je LBB3_5
|
|
; CHECK-NEXT: ## %bb.3: ## %if.end4.i
|
|
; CHECK-NEXT: movq 8(%rdi), %rdx
|
|
; CHECK-NEXT: cmpq 8(%rsi), %rdx
|
|
; CHECK-NEXT: jne LBB3_6
|
|
; CHECK-NEXT: ## %bb.4: ## %land.rhs.i.i
|
|
; CHECK-NEXT: movq (%rsi), %rsi
|
|
; CHECK-NEXT: movq (%rdi), %rdi
|
|
; CHECK-NEXT: callq _memcmp
|
|
; CHECK-NEXT: testl %eax, %eax
|
|
; CHECK-NEXT: sete %al
|
|
; CHECK-NEXT: LBB3_5: ## %__go_ptr_strings_equal.exit
|
|
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: LBB3_6:
|
|
; CHECK-NEXT: xorl %eax, %eax
|
|
; CHECK-NEXT: ## kill: def $al killed $al killed $eax
|
|
; CHECK-NEXT: popq %rcx
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: LBB3_7:
|
|
; CHECK-NEXT: movl $8, %r10d
|
|
; CHECK-NEXT: movl $0, %r11d
|
|
; CHECK-NEXT: callq ___morestack
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: jmp LBB3_1
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: segmentedStack:
|
|
; NOCOMPACTUNWIND: # %bb.0:
|
|
; NOCOMPACTUNWIND-NEXT: cmpq %fs:112, %rsp
|
|
; NOCOMPACTUNWIND-NEXT: jbe .LBB3_7
|
|
; NOCOMPACTUNWIND-NEXT: .LBB3_1: # %entry
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: movq %rdi, %rax
|
|
; NOCOMPACTUNWIND-NEXT: orq %rsi, %rax
|
|
; NOCOMPACTUNWIND-NEXT: sete %al
|
|
; NOCOMPACTUNWIND-NEXT: testq %rdi, %rdi
|
|
; NOCOMPACTUNWIND-NEXT: je .LBB3_5
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.2: # %entry
|
|
; NOCOMPACTUNWIND-NEXT: testq %rsi, %rsi
|
|
; NOCOMPACTUNWIND-NEXT: je .LBB3_5
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.3: # %if.end4.i
|
|
; NOCOMPACTUNWIND-NEXT: movq 8(%rdi), %rdx
|
|
; NOCOMPACTUNWIND-NEXT: cmpq 8(%rsi), %rdx
|
|
; NOCOMPACTUNWIND-NEXT: jne .LBB3_6
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.4: # %land.rhs.i.i
|
|
; NOCOMPACTUNWIND-NEXT: movq (%rsi), %rsi
|
|
; NOCOMPACTUNWIND-NEXT: movq (%rdi), %rdi
|
|
; NOCOMPACTUNWIND-NEXT: callq memcmp@PLT
|
|
; NOCOMPACTUNWIND-NEXT: testl %eax, %eax
|
|
; NOCOMPACTUNWIND-NEXT: sete %al
|
|
; NOCOMPACTUNWIND-NEXT: .LBB3_5: # %__go_ptr_strings_equal.exit
|
|
; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
|
|
; NOCOMPACTUNWIND-NEXT: popq %rcx
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
; NOCOMPACTUNWIND-NEXT: .LBB3_6:
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: xorl %eax, %eax
|
|
; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
|
|
; NOCOMPACTUNWIND-NEXT: popq %rcx
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
; NOCOMPACTUNWIND-NEXT: .LBB3_7:
|
|
; NOCOMPACTUNWIND-NEXT: movl $8, %r10d
|
|
; NOCOMPACTUNWIND-NEXT: movl $0, %r11d
|
|
; NOCOMPACTUNWIND-NEXT: callq __morestack
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
; NOCOMPACTUNWIND-NEXT: jmp .LBB3_1
|
|
entry:
|
|
%cmp.i = icmp eq ptr %vk1, null
|
|
%cmp1.i = icmp eq ptr %vk2, null
|
|
%brmerge.i = or i1 %cmp.i, %cmp1.i
|
|
%cmp1.mux.i = and i1 %cmp.i, %cmp1.i
|
|
br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
|
|
|
|
if.end4.i: ; preds = %entry
|
|
%tmp = getelementptr inbounds i8, ptr %vk1, i64 8
|
|
%tmp2 = load i64, ptr %tmp, align 8
|
|
%tmp3 = getelementptr inbounds i8, ptr %vk2, i64 8
|
|
%tmp5 = load i64, ptr %tmp3, align 8
|
|
%cmp.i.i = icmp eq i64 %tmp2, %tmp5
|
|
br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
|
|
|
|
land.rhs.i.i: ; preds = %if.end4.i
|
|
%tmp7 = load ptr, ptr %vk2, align 8
|
|
%tmp9 = load ptr, ptr %vk1, align 8
|
|
%call.i.i = tail call i32 @memcmp(ptr %tmp9, ptr %tmp7, i64 %tmp2) #5
|
|
%cmp4.i.i = icmp eq i32 %call.i.i, 0
|
|
br label %__go_ptr_strings_equal.exit
|
|
|
|
__go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.end4.i, %entry
|
|
%retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
|
|
ret i1 %retval.0.i
|
|
}
|
|
|
|
; Function Attrs: nounwind readonly
|
|
declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) #5
|
|
|
|
attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
|
|
|
|
; Check that correctly take into account the jumps to landing pad.
|
|
; We used to consider function that may throw like regular
|
|
; function calls.
|
|
; Therefore, in this example, we were happily inserting the epilogue
|
|
; right after the call to throw_exception. Because of that we would not
|
|
; execute the epilogue when an execption occur and bad things will
|
|
; happen.
|
|
; PR36513
|
|
define void @with_nounwind(i1 %cond) nounwind personality ptr @my_personality {
|
|
; CHECK-LABEL: with_nounwind:
|
|
; CHECK: ## %bb.0: ## %entry
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: jne LBB4_1
|
|
; CHECK-NEXT: ## %bb.4: ## %return
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: LBB4_1: ## %throw
|
|
; CHECK-NEXT: Ltmp0:
|
|
; CHECK-NEXT: callq _throw_exception
|
|
; CHECK-NEXT: Ltmp1:
|
|
; CHECK-NEXT: ## %bb.2: ## %unreachable
|
|
; CHECK-NEXT: ud2
|
|
; CHECK-NEXT: LBB4_3: ## %landing
|
|
; CHECK-NEXT: Ltmp2:
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: Lfunc_end0:
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: with_nounwind:
|
|
; NOCOMPACTUNWIND: # %bb.0: # %entry
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: testb $1, %dil
|
|
; NOCOMPACTUNWIND-NEXT: jne .LBB4_1
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.4: # %return
|
|
; NOCOMPACTUNWIND-NEXT: popq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
; NOCOMPACTUNWIND-NEXT: .LBB4_1: # %throw
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp0:
|
|
; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp1:
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.2: # %unreachable
|
|
; NOCOMPACTUNWIND-NEXT: .LBB4_3: # %landing
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp2:
|
|
; NOCOMPACTUNWIND-NEXT: popq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
entry:
|
|
br i1 %cond, label %throw, label %return
|
|
|
|
throw:
|
|
invoke void @throw_exception()
|
|
to label %unreachable unwind label %landing
|
|
|
|
unreachable:
|
|
unreachable
|
|
|
|
landing:
|
|
%pad = landingpad { ptr, i32 }
|
|
catch ptr null
|
|
ret void
|
|
|
|
return:
|
|
ret void
|
|
}
|
|
|
|
; Check landing pad again.
|
|
; This time checks that we can shrink-wrap when the epilogue does not
|
|
; span accross several blocks.
|
|
define void @with_nounwind_same_succ(i1 %cond) nounwind personality ptr @my_personality2 {
|
|
; CHECK-LABEL: with_nounwind_same_succ:
|
|
; CHECK: ## %bb.0: ## %entry
|
|
; CHECK-NEXT: testb $1, %dil
|
|
; CHECK-NEXT: je LBB5_4
|
|
; CHECK-NEXT: ## %bb.1: ## %throw
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: Ltmp3:
|
|
; CHECK-NEXT: callq _throw_exception
|
|
; CHECK-NEXT: Ltmp4:
|
|
; CHECK-NEXT: LBB5_3: ## %fallthrough
|
|
; CHECK-NEXT: ## InlineAsm Start
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: ## InlineAsm End
|
|
; CHECK-NEXT: popq %rax
|
|
; CHECK-NEXT: LBB5_4: ## %return
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: LBB5_2: ## %landing
|
|
; CHECK-NEXT: Ltmp5:
|
|
; CHECK-NEXT: jmp LBB5_3
|
|
; CHECK-NEXT: Lfunc_end1:
|
|
;
|
|
; NOCOMPACTUNWIND-LABEL: with_nounwind_same_succ:
|
|
; NOCOMPACTUNWIND: # %bb.0: # %entry
|
|
; NOCOMPACTUNWIND-NEXT: testb $1, %dil
|
|
; NOCOMPACTUNWIND-NEXT: je .LBB5_4
|
|
; NOCOMPACTUNWIND-NEXT: # %bb.1: # %throw
|
|
; NOCOMPACTUNWIND-NEXT: pushq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp3:
|
|
; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp4:
|
|
; NOCOMPACTUNWIND-NEXT: .LBB5_3: # %fallthrough
|
|
; NOCOMPACTUNWIND-NEXT: #APP
|
|
; NOCOMPACTUNWIND-NEXT: nop
|
|
; NOCOMPACTUNWIND-NEXT: #NO_APP
|
|
; NOCOMPACTUNWIND-NEXT: popq %rax
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
|
|
; NOCOMPACTUNWIND-NEXT: .LBB5_4: # %return
|
|
; NOCOMPACTUNWIND-NEXT: retq
|
|
; NOCOMPACTUNWIND-NEXT: .LBB5_2: # %landing
|
|
; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
|
|
; NOCOMPACTUNWIND-NEXT: .Ltmp5:
|
|
; NOCOMPACTUNWIND-NEXT: jmp .LBB5_3
|
|
entry:
|
|
br i1 %cond, label %throw, label %return
|
|
|
|
throw:
|
|
invoke void @throw_exception()
|
|
to label %fallthrough unwind label %landing
|
|
landing:
|
|
%pad = landingpad { ptr, i32 }
|
|
catch ptr null
|
|
br label %fallthrough
|
|
|
|
fallthrough:
|
|
tail call void asm "nop", ""()
|
|
br label %return
|
|
|
|
return:
|
|
ret void
|
|
}
|
|
|
|
declare void @throw_exception()
|
|
declare i32 @my_personality(...)
|
|
declare i32 @my_personality2(...)
|