blob: 56124709d747824d041f9e1ec273f9c0e960b63c [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=arm64-apple-ios -o - | FileCheck %s
declare swiftcc ptr @swift_task_alloc(i64)
; A musttail call modelling a swiftasync context reallocation thunk, whose 10
; ordinary arguments overflow the 8 GPR argument registers, leaving 9 bytes of
; stack arg area:
; * Formal arguments %1-%8 are forwarded in registers x0-x7
; * swiftasync and swiftself don't count agaginst the usual 8 GPR argument
; list, and are are passed in dedicated registers (x22/x20)
; * ptr %9 (8 bytes) and i1 %10 (1 byte) are passed on the stack, packed in 9
; contiguous bytes
; We round up that stack arg area to keep the FPDiff (and therefore the stack)
; 16-byte aligned going into the callee.
define swifttailcc void @thunk(ptr %1, ptr swiftasync %sa, i64 %2, i64 %3, i64 %4, ptr %5, i64 %6, ptr %7, ptr %8, ptr %9, i1 %10, ptr swiftself %self) #0 {
; CHECK-LABEL: thunk:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: orr x29, x29, #0x1000000000000000
; CHECK-NEXT: sub sp, sp, #96
; CHECK-NEXT: stp x28, x27, [sp, #8] ; 16-byte Folded Spill
; CHECK-NEXT: mov x27, x1
; CHECK-NEXT: mov x28, x0
; CHECK-NEXT: stp x26, x25, [sp, #24] ; 16-byte Folded Spill
; CHECK-NEXT: mov w0, #64 ; =0x40
; CHECK-NEXT: mov x25, x3
; CHECK-NEXT: stp x24, x23, [sp, #40] ; 16-byte Folded Spill
; CHECK-NEXT: mov x23, x5
; CHECK-NEXT: mov x24, x4
; CHECK-NEXT: stp x21, x19, [sp, #56] ; 16-byte Folded Spill
; CHECK-NEXT: mov x19, x7
; CHECK-NEXT: mov x21, x6
; CHECK-NEXT: stp x29, x30, [sp, #80] ; 16-byte Folded Spill
; CHECK-NEXT: add x29, sp, #80
; CHECK-NEXT: mov x26, x2
; CHECK-NEXT: str x22, [sp, #72]
; CHECK-NEXT: ldr x1, [x20]
; CHECK-NEXT: str x1, [sp] ; 8-byte Spill
; CHECK-NEXT: bl _swift_task_alloc
; CHECK-NEXT: ldp x29, x30, [sp, #80] ; 16-byte Folded Reload
; CHECK-NEXT: mov x8, x0
; CHECK-NEXT: str x0, [x22, #16]
; CHECK-NEXT: mov x0, x28
; CHECK-NEXT: mov x1, x27
; CHECK-NEXT: mov x2, x26
; CHECK-NEXT: mov x3, x25
; CHECK-NEXT: mov x4, x24
; CHECK-NEXT: mov x5, x23
; CHECK-NEXT: mov x6, x21
; CHECK-NEXT: mov x7, x19
; CHECK-NEXT: ldp x21, x19, [sp, #56] ; 16-byte Folded Reload
; CHECK-NEXT: mov x22, x8
; CHECK-NEXT: ldp x24, x23, [sp, #40] ; 16-byte Folded Reload
; CHECK-NEXT: ldr x8, [sp] ; 8-byte Reload
; CHECK-NEXT: ldp x26, x25, [sp, #24] ; 16-byte Folded Reload
; CHECK-NEXT: and x29, x29, #0xefffffffffffffff
; CHECK-NEXT: ldp x28, x27, [sp, #8] ; 16-byte Folded Reload
; CHECK-NEXT: add sp, sp, #96
; CHECK-NEXT: br x8
entry:
%oldCtx = getelementptr inbounds i8, ptr %sa, i64 16
%fn = load ptr, ptr %self, align 8
%newCtx = call swiftcc ptr @swift_task_alloc(i64 64)
store ptr %newCtx, ptr %oldCtx, align 8
musttail call swifttailcc void %fn(ptr %1, ptr swiftasync %newCtx, i64 %2, i64 %3, i64 %4, ptr %5, i64 %6, ptr %7, ptr %8, ptr %9, i1 %10, ptr swiftself %self)
ret void
}
; A musttail call from a function with no arguments (and therefore no reusable
; stack arg area) to a function with 11 i32 arguments that overflow the 8 GPR
; argument registers, leaving 4 bytes of stack arg area:
; * The first 8 i32 arguments land in registers w0-w7
; * The arg is passed on the stack, consuming 4 bytes
; We round up that stack arg area to keep the FPDiff (and therefore the stack)
; 16-byte aligned going into the callee.
define swifttailcc void @caller_no_args() {
; CHECK-LABEL: caller_no_args:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: mov w8, #8 ; =0x8
; CHECK-NEXT: str w8, [sp, #-16]!
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: mov w0, wzr
; CHECK-NEXT: mov w1, #1 ; =0x1
; CHECK-NEXT: mov w2, #2 ; =0x2
; CHECK-NEXT: mov w3, #3 ; =0x3
; CHECK-NEXT: mov w4, #4 ; =0x4
; CHECK-NEXT: mov w5, #5 ; =0x5
; CHECK-NEXT: mov w6, #6 ; =0x6
; CHECK-NEXT: mov w7, #7 ; =0x7
; CHECK-NEXT: b _callee_11_args
entry:
musttail call swifttailcc void @callee_11_args(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8)
ret void
}
; The corresponding callee pops swifttail callee, with 11 i32 arguments that
; overflow the 8 GPR argument registers, leaving 4 bytes of stack arg area,
; which is rounded up to keep the stack 16-byte aligned. The amount popped here
; must match what was pushed in @caller_no_args.
define swifttailcc void @callee_11_args(i32, i32, i32, i32, i32, i32, i32, i32, i32) "noinline" {
; CHECK-LABEL: callee_11_args:
; CHECK: ; %bb.0:
; CHECK-NEXT: add sp, sp, #16
; CHECK-NEXT: ret
ret void
}
attributes #0 = { nounwind "frame-pointer"="non-leaf-no-reserve" }