For windows __security_check_cookie call gets call everytime function is return without fixup. Since this function is defined in runtime library, it incures cost of call in dll which simply does comparison and returns most time. With Fixup, We selective move to call in DLL only if comparison fails.
100 lines
3.4 KiB
LLVM
100 lines
3.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc -mtriple=x86_64-windows-msvc %s -o - -verify-machineinstrs | FileCheck %s -check-prefix=WINDOWS
|
|
; RUN: llc -mtriple=x86_64-linux-gnu %s -o - -verify-machineinstrs | FileCheck %s -check-prefix=LINUX
|
|
|
|
declare void @h(ptr, i64, ptr)
|
|
|
|
define tailcc void @tailcall_frame(ptr %0, i64 %1) sspreq {
|
|
; WINDOWS-LABEL: tailcall_frame:
|
|
; WINDOWS: # %bb.0:
|
|
; WINDOWS-NEXT: subq $56, %rsp
|
|
; WINDOWS-NEXT: .seh_stackalloc 56
|
|
; WINDOWS-NEXT: .seh_endprologue
|
|
; WINDOWS-NEXT: movq __security_cookie(%rip), %rax
|
|
; WINDOWS-NEXT: xorq %rsp, %rax
|
|
; WINDOWS-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; WINDOWS-NEXT: movq {{[0-9]+}}(%rsp), %rcx
|
|
; WINDOWS-NEXT: xorq %rsp, %rcx
|
|
; WINDOWS-NEXT: cmpq __security_cookie(%rip), %rcx
|
|
; WINDOWS-NEXT: jne .LBB0_1
|
|
; WINDOWS-NEXT: # %bb.2:
|
|
; WINDOWS-NEXT: xorl %ecx, %ecx
|
|
; WINDOWS-NEXT: xorl %edx, %edx
|
|
; WINDOWS-NEXT: xorl %r8d, %r8d
|
|
; WINDOWS-NEXT: addq $56, %rsp
|
|
; WINDOWS-NEXT: jmp h # TAILCALL
|
|
; WINDOWS-NEXT: .LBB0_1:
|
|
; WINDOWS-NEXT: callq __security_check_cookie
|
|
; WINDOWS-NEXT: int3
|
|
; WINDOWS-NEXT: .seh_endproc
|
|
;
|
|
; LINUX-LABEL: tailcall_frame:
|
|
; LINUX: # %bb.0:
|
|
; LINUX-NEXT: subq $24, %rsp
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 32
|
|
; LINUX-NEXT: movq %fs:40, %rax
|
|
; LINUX-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; LINUX-NEXT: movq %fs:40, %rax
|
|
; LINUX-NEXT: cmpq {{[0-9]+}}(%rsp), %rax
|
|
; LINUX-NEXT: jne .LBB0_2
|
|
; LINUX-NEXT: # %bb.1: # %SP_return
|
|
; LINUX-NEXT: xorl %edi, %edi
|
|
; LINUX-NEXT: xorl %esi, %esi
|
|
; LINUX-NEXT: xorl %edx, %edx
|
|
; LINUX-NEXT: addq $24, %rsp
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 8
|
|
; LINUX-NEXT: jmp h@PLT # TAILCALL
|
|
; LINUX-NEXT: .LBB0_2: # %CallStackCheckFailBlk
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 32
|
|
; LINUX-NEXT: callq __stack_chk_fail@PLT
|
|
|
|
tail call tailcc void @h(ptr null, i64 0, ptr null)
|
|
ret void
|
|
}
|
|
|
|
declare void @bar()
|
|
define void @tailcall_unrelated_frame() sspreq {
|
|
; WINDOWS-LABEL: tailcall_unrelated_frame:
|
|
; WINDOWS: # %bb.0:
|
|
; WINDOWS-NEXT: subq $40, %rsp
|
|
; WINDOWS-NEXT: .seh_stackalloc 40
|
|
; WINDOWS-NEXT: .seh_endprologue
|
|
; WINDOWS-NEXT: movq __security_cookie(%rip), %rax
|
|
; WINDOWS-NEXT: xorq %rsp, %rax
|
|
; WINDOWS-NEXT: movq %rax, {{[0-9]+}}(%rsp)
|
|
; WINDOWS-NEXT: callq bar
|
|
; WINDOWS-NEXT: movq {{[0-9]+}}(%rsp), %rcx
|
|
; WINDOWS-NEXT: xorq %rsp, %rcx
|
|
; WINDOWS-NEXT: cmpq __security_cookie(%rip), %rcx
|
|
; WINDOWS-NEXT: jne .LBB1_1
|
|
; WINDOWS-NEXT: # %bb.2:
|
|
; WINDOWS-NEXT: addq $40, %rsp
|
|
; WINDOWS-NEXT: jmp bar # TAILCALL
|
|
; WINDOWS-NEXT: .LBB1_1:
|
|
; WINDOWS-NEXT: callq __security_check_cookie
|
|
; WINDOWS-NEXT: int3
|
|
; WINDOWS-NEXT: .seh_endproc
|
|
|
|
; LINUX-LABEL: tailcall_unrelated_frame:
|
|
; LINUX: # %bb.0:
|
|
; LINUX-NEXT: pushq %rax
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 16
|
|
; LINUX-NEXT: movq %fs:40, %rax
|
|
; LINUX-NEXT: movq %rax, (%rsp)
|
|
; LINUX-NEXT: callq bar@PLT
|
|
; LINUX-NEXT: movq %fs:40, %rax
|
|
; LINUX-NEXT: cmpq (%rsp), %rax
|
|
; LINUX-NEXT: jne .LBB1_2
|
|
; LINUX-NEXT: # %bb.1: # %SP_return
|
|
; LINUX-NEXT: popq %rax
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 8
|
|
; LINUX-NEXT: jmp bar@PLT # TAILCALL
|
|
; LINUX-NEXT: .LBB1_2: # %CallStackCheckFailBlk
|
|
; LINUX-NEXT: .cfi_def_cfa_offset 16
|
|
; LINUX-NEXT: callq __stack_chk_fail@PLT
|
|
|
|
call void @bar()
|
|
tail call void @bar()
|
|
ret void
|
|
}
|