This is a port of the feature that allows the StackProtector pass to omit checking code for stack canary checks, and rely on SelectionDAG to do it at a later stage. The reasoning behind this seems to be to prevent the IR checking instructions from hindering tail-call optimizations during codegen. Here we allow GlobalISel to also use that scheme. Doing so requires that we do some analysis using some factored-out code to determine where to generate code for the epilogs. Not every case is handled in this patch since we don't have support for all targets that exercise different stack protector schemes. Differential Revision: https://reviews.llvm.org/D98200
41 lines
2.3 KiB
LLVM
41 lines
2.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios %s -stop-after=irtranslator -o - -global-isel | FileCheck %s
|
|
|
|
define void @caller() sspreq {
|
|
; CHECK-LABEL: name: caller
|
|
; CHECK: bb.1.entry:
|
|
; CHECK-NEXT: successors: %bb.2(0x7ffff800), %bb.3(0x00000800)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.StackGuardSlot
|
|
; CHECK-NEXT: [[LOAD_STACK_GUARD:%[0-9]+]]:gpr64sp(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load (p0) from @__stack_chk_guard)
|
|
; CHECK-NEXT: [[LOAD_STACK_GUARD1:%[0-9]+]]:gpr64sp(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load (p0) from @__stack_chk_guard)
|
|
; CHECK-NEXT: G_STORE [[LOAD_STACK_GUARD1]](p0), [[FRAME_INDEX]](p0) :: (volatile store (p0) into %stack.0.StackGuardSlot)
|
|
; CHECK-NEXT: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.x
|
|
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
|
|
; CHECK-NEXT: $x0 = COPY [[FRAME_INDEX1]](p0)
|
|
; CHECK-NEXT: BL @callee, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
|
|
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
|
|
; CHECK-NEXT: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.StackGuardSlot
|
|
; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (volatile load (s64) from %stack.0.StackGuardSlot)
|
|
; CHECK-NEXT: [[LOAD_STACK_GUARD2:%[0-9]+]]:gpr64sp(s64) = LOAD_STACK_GUARD :: (dereferenceable invariant load (p0) from @__stack_chk_guard)
|
|
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LOAD_STACK_GUARD2]](s64), [[LOAD]]
|
|
; CHECK-NEXT: G_BRCOND [[ICMP]](s1), %bb.3
|
|
; CHECK-NEXT: G_BR %bb.2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.3.entry:
|
|
; CHECK-NEXT: successors:
|
|
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
|
|
; CHECK-NEXT: BL &__stack_chk_fail, csr_darwin_aarch64_aapcs, implicit-def $lr, implicit $sp
|
|
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.2.entry:
|
|
; CHECK-NEXT: RET_ReallyLR
|
|
entry:
|
|
%x = alloca i32, align 4
|
|
%0 = bitcast i32* %x to i8*
|
|
call void @callee(i32* nonnull %x)
|
|
ret void
|
|
}
|
|
|
|
declare void @callee(i32*)
|