blob: 2ffe420a20520aa8982a944475067ae8e877db62 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=armv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16 | FileCheck %s --check-prefix=LE
; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16 | FileCheck %s --check-prefix=BE
; RUN: llc -mtriple=armv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+bf16 | FileCheck %s --check-prefix=LE-BF16
; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+bf16 | FileCheck %s --check-prefix=BE-BF16
;; Global ISel successfully generates code for some functions for little-endian
;; without +bf16, and falls back to SelectionDAG in all others.
; RUN: llc -mtriple=armv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=LE-GISEL
; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=BE
; RUN: llc -mtriple=armv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+bf16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=LE-BF16
; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+bf16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=BE-BF16
define arm_aapcscc bfloat @callee_soft_bfloat_in_reg(bfloat %f) {
; LE-LABEL: callee_soft_bfloat_in_reg:
; LE: @ %bb.0: @ %entry
; LE-NEXT: bx lr
;
; BE-LABEL: callee_soft_bfloat_in_reg:
; BE: @ %bb.0: @ %entry
; BE-NEXT: bx lr
;
; LE-BF16-LABEL: callee_soft_bfloat_in_reg:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .pad #4
; LE-BF16-NEXT: sub sp, #4
; LE-BF16-NEXT: strh.w r0, [sp, #2]
; LE-BF16-NEXT: ldrh.w r0, [sp, #2]
; LE-BF16-NEXT: add sp, #4
; LE-BF16-NEXT: bx lr
;
; BE-BF16-LABEL: callee_soft_bfloat_in_reg:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .pad #4
; BE-BF16-NEXT: sub sp, #4
; BE-BF16-NEXT: strh.w r0, [sp, #2]
; BE-BF16-NEXT: ldrh.w r0, [sp, #2]
; BE-BF16-NEXT: add sp, #4
; BE-BF16-NEXT: bx lr
;
; LE-GISEL-LABEL: callee_soft_bfloat_in_reg:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: bx lr
entry:
ret bfloat %f
}
define void @caller_soft_bfloat_in_reg() {
; LE-LABEL: caller_soft_bfloat_in_reg:
; LE: @ %bb.0: @ %entry
; LE-NEXT: .save {r7, lr}
; LE-NEXT: push {r7, lr}
; LE-NEXT: mov.w r0, #16256
; LE-NEXT: bl callee_soft_bfloat_in_reg
; LE-NEXT: pop {r7, pc}
;
; BE-LABEL: caller_soft_bfloat_in_reg:
; BE: @ %bb.0: @ %entry
; BE-NEXT: .save {r7, lr}
; BE-NEXT: push {r7, lr}
; BE-NEXT: mov.w r0, #16256
; BE-NEXT: bl callee_soft_bfloat_in_reg
; BE-NEXT: pop {r7, pc}
;
; LE-BF16-LABEL: caller_soft_bfloat_in_reg:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .save {r7, lr}
; LE-BF16-NEXT: push {r7, lr}
; LE-BF16-NEXT: mov.w r0, #16256
; LE-BF16-NEXT: bl callee_soft_bfloat_in_reg
; LE-BF16-NEXT: pop {r7, pc}
;
; BE-BF16-LABEL: caller_soft_bfloat_in_reg:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .save {r7, lr}
; BE-BF16-NEXT: push {r7, lr}
; BE-BF16-NEXT: mov.w r0, #16256
; BE-BF16-NEXT: bl callee_soft_bfloat_in_reg
; BE-BF16-NEXT: pop {r7, pc}
;
; LE-GISEL-LABEL: caller_soft_bfloat_in_reg:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: .save {r7, lr}
; LE-GISEL-NEXT: push {r7, lr}
; LE-GISEL-NEXT: mov.w r0, #16256
; LE-GISEL-NEXT: bl callee_soft_bfloat_in_reg
; LE-GISEL-NEXT: pop {r7, pc}
entry:
%ret = call arm_aapcscc bfloat @callee_soft_bfloat_in_reg(bfloat 1.0)
ret void
}
define arm_aapcscc bfloat @callee_soft_bfloat_on_stack(float %r0, float %r1, float %r2, float %r3, bfloat %f) {
; LE-LABEL: callee_soft_bfloat_on_stack:
; LE: @ %bb.0: @ %entry
; LE-NEXT: ldr r0, [sp]
; LE-NEXT: bx lr
;
; BE-LABEL: callee_soft_bfloat_on_stack:
; BE: @ %bb.0: @ %entry
; BE-NEXT: ldr r0, [sp]
; BE-NEXT: bx lr
;
; LE-BF16-LABEL: callee_soft_bfloat_on_stack:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: ldrh.w r0, [sp]
; LE-BF16-NEXT: bx lr
;
; BE-BF16-LABEL: callee_soft_bfloat_on_stack:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: ldrh.w r0, [sp, #2]
; BE-BF16-NEXT: bx lr
;
; LE-GISEL-LABEL: callee_soft_bfloat_on_stack:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: mov r0, sp
; LE-GISEL-NEXT: ldr r0, [r0]
; LE-GISEL-NEXT: bx lr
entry:
ret bfloat %f
}
define void @caller_soft_bfloat_on_stack() {
; LE-LABEL: caller_soft_bfloat_on_stack:
; LE: @ %bb.0: @ %entry
; LE-NEXT: .save {r7, lr}
; LE-NEXT: push {r7, lr}
; LE-NEXT: .pad #8
; LE-NEXT: sub sp, #8
; LE-NEXT: mov.w r0, #16256
; LE-NEXT: str r0, [sp]
; LE-NEXT: bl callee_soft_bfloat_on_stack
; LE-NEXT: add sp, #8
; LE-NEXT: pop {r7, pc}
;
; BE-LABEL: caller_soft_bfloat_on_stack:
; BE: @ %bb.0: @ %entry
; BE-NEXT: .save {r7, lr}
; BE-NEXT: push {r7, lr}
; BE-NEXT: .pad #8
; BE-NEXT: sub sp, #8
; BE-NEXT: mov.w r0, #16256
; BE-NEXT: str r0, [sp]
; BE-NEXT: bl callee_soft_bfloat_on_stack
; BE-NEXT: add sp, #8
; BE-NEXT: pop {r7, pc}
;
; LE-BF16-LABEL: caller_soft_bfloat_on_stack:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .save {r7, lr}
; LE-BF16-NEXT: push {r7, lr}
; LE-BF16-NEXT: .pad #8
; LE-BF16-NEXT: sub sp, #8
; LE-BF16-NEXT: mov.w r0, #16256
; LE-BF16-NEXT: str r0, [sp]
; LE-BF16-NEXT: bl callee_soft_bfloat_on_stack
; LE-BF16-NEXT: add sp, #8
; LE-BF16-NEXT: pop {r7, pc}
;
; BE-BF16-LABEL: caller_soft_bfloat_on_stack:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .save {r7, lr}
; BE-BF16-NEXT: push {r7, lr}
; BE-BF16-NEXT: .pad #8
; BE-BF16-NEXT: sub sp, #8
; BE-BF16-NEXT: mov.w r0, #16256
; BE-BF16-NEXT: str r0, [sp]
; BE-BF16-NEXT: bl callee_soft_bfloat_on_stack
; BE-BF16-NEXT: add sp, #8
; BE-BF16-NEXT: pop {r7, pc}
;
; LE-GISEL-LABEL: caller_soft_bfloat_on_stack:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: .save {r7, lr}
; LE-GISEL-NEXT: push {r7, lr}
; LE-GISEL-NEXT: .pad #8
; LE-GISEL-NEXT: sub sp, #8
; LE-GISEL-NEXT: mov.w r0, #16256
; LE-GISEL-NEXT: str r0, [sp]
; LE-GISEL-NEXT: bl callee_soft_bfloat_on_stack
; LE-GISEL-NEXT: add sp, #8
; LE-GISEL-NEXT: pop {r7, pc}
entry:
%ret = call arm_aapcscc bfloat @callee_soft_bfloat_on_stack(float poison, float poison, float poison, float poison, bfloat 1.0)
ret void
}
define arm_aapcs_vfpcc bfloat @callee_hard_bfloat_in_reg(bfloat %f) {
; LE-LABEL: callee_hard_bfloat_in_reg:
; LE: @ %bb.0: @ %entry
; LE-NEXT: bx lr
;
; BE-LABEL: callee_hard_bfloat_in_reg:
; BE: @ %bb.0: @ %entry
; BE-NEXT: bx lr
;
; LE-BF16-LABEL: callee_hard_bfloat_in_reg:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .pad #4
; LE-BF16-NEXT: sub sp, #4
; LE-BF16-NEXT: vmov r0, s0
; LE-BF16-NEXT: strh.w r0, [sp, #2]
; LE-BF16-NEXT: ldrh.w r0, [sp, #2]
; LE-BF16-NEXT: vmov s0, r0
; LE-BF16-NEXT: add sp, #4
; LE-BF16-NEXT: bx lr
;
; BE-BF16-LABEL: callee_hard_bfloat_in_reg:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .pad #4
; BE-BF16-NEXT: sub sp, #4
; BE-BF16-NEXT: vmov r0, s0
; BE-BF16-NEXT: strh.w r0, [sp, #2]
; BE-BF16-NEXT: ldrh.w r0, [sp, #2]
; BE-BF16-NEXT: vmov s0, r0
; BE-BF16-NEXT: add sp, #4
; BE-BF16-NEXT: bx lr
;
; LE-GISEL-LABEL: callee_hard_bfloat_in_reg:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: bx lr
entry:
ret bfloat %f
}
define void @caller_hard_bfloat_in_reg() {
; LE-LABEL: caller_hard_bfloat_in_reg:
; LE: @ %bb.0: @ %entry
; LE-NEXT: .save {r7, lr}
; LE-NEXT: push {r7, lr}
; LE-NEXT: vldr s0, .LCPI5_0
; LE-NEXT: bl callee_hard_bfloat_in_reg
; LE-NEXT: pop {r7, pc}
; LE-NEXT: .p2align 2
; LE-NEXT: @ %bb.1:
; LE-NEXT: .LCPI5_0:
; LE-NEXT: .long 0x00003f80 @ float 2.27795078E-41
;
; BE-LABEL: caller_hard_bfloat_in_reg:
; BE: @ %bb.0: @ %entry
; BE-NEXT: .save {r7, lr}
; BE-NEXT: push {r7, lr}
; BE-NEXT: vldr s0, .LCPI5_0
; BE-NEXT: bl callee_hard_bfloat_in_reg
; BE-NEXT: pop {r7, pc}
; BE-NEXT: .p2align 2
; BE-NEXT: @ %bb.1:
; BE-NEXT: .LCPI5_0:
; BE-NEXT: .long 0x00003f80 @ float 2.27795078E-41
;
; LE-BF16-LABEL: caller_hard_bfloat_in_reg:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .save {r7, lr}
; LE-BF16-NEXT: push {r7, lr}
; LE-BF16-NEXT: vldr s0, .LCPI5_0
; LE-BF16-NEXT: bl callee_hard_bfloat_in_reg
; LE-BF16-NEXT: pop {r7, pc}
; LE-BF16-NEXT: .p2align 2
; LE-BF16-NEXT: @ %bb.1:
; LE-BF16-NEXT: .LCPI5_0:
; LE-BF16-NEXT: .long 0x00003f80 @ float 2.27795078E-41
;
; BE-BF16-LABEL: caller_hard_bfloat_in_reg:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .save {r7, lr}
; BE-BF16-NEXT: push {r7, lr}
; BE-BF16-NEXT: vldr s0, .LCPI5_0
; BE-BF16-NEXT: bl callee_hard_bfloat_in_reg
; BE-BF16-NEXT: pop {r7, pc}
; BE-BF16-NEXT: .p2align 2
; BE-BF16-NEXT: @ %bb.1:
; BE-BF16-NEXT: .LCPI5_0:
; BE-BF16-NEXT: .long 0x00003f80 @ float 2.27795078E-41
;
; LE-GISEL-LABEL: caller_hard_bfloat_in_reg:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: .save {r7, lr}
; LE-GISEL-NEXT: push {r7, lr}
; LE-GISEL-NEXT: vldr s0, .LCPI5_0
; LE-GISEL-NEXT: bl callee_hard_bfloat_in_reg
; LE-GISEL-NEXT: pop {r7, pc}
; LE-GISEL-NEXT: .p2align 2
; LE-GISEL-NEXT: @ %bb.1:
; LE-GISEL-NEXT: .LCPI5_0:
; LE-GISEL-NEXT: .long 0x00003f80 @ float 2.27795078E-41
entry:
%ret = call arm_aapcs_vfpcc bfloat @callee_hard_bfloat_in_reg(bfloat 1.0)
ret void
}
define arm_aapcs_vfpcc bfloat @callee_hard_bfloat_on_stack(float %s0, float %s1, float %s2, float %s3, float %s4, float %s5, float %s6, float %s7,float %s8, float %s9, float %s10, float %s11, float %s12, float %s13, float %s14, float %s15, bfloat %f) {
; LE-LABEL: callee_hard_bfloat_on_stack:
; LE: @ %bb.0: @ %entry
; LE-NEXT: vldr s0, [sp]
; LE-NEXT: bx lr
;
; BE-LABEL: callee_hard_bfloat_on_stack:
; BE: @ %bb.0: @ %entry
; BE-NEXT: vldr s0, [sp]
; BE-NEXT: bx lr
;
; LE-BF16-LABEL: callee_hard_bfloat_on_stack:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: ldrh.w r0, [sp]
; LE-BF16-NEXT: vmov s0, r0
; LE-BF16-NEXT: bx lr
;
; BE-BF16-LABEL: callee_hard_bfloat_on_stack:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: ldrh.w r0, [sp, #2]
; BE-BF16-NEXT: vmov s0, r0
; BE-BF16-NEXT: bx lr
;
; LE-GISEL-LABEL: callee_hard_bfloat_on_stack:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: mov r0, sp
; LE-GISEL-NEXT: ldr r0, [r0]
; LE-GISEL-NEXT: vmov s0, r0
; LE-GISEL-NEXT: bx lr
entry:
ret bfloat %f
}
define void @caller_hard_bfloat_on_stack() {
; LE-LABEL: caller_hard_bfloat_on_stack:
; LE: @ %bb.0: @ %entry
; LE-NEXT: .save {r7, lr}
; LE-NEXT: push {r7, lr}
; LE-NEXT: .pad #8
; LE-NEXT: sub sp, #8
; LE-NEXT: mov.w r0, #16256
; LE-NEXT: str r0, [sp]
; LE-NEXT: bl callee_hard_bfloat_on_stack
; LE-NEXT: add sp, #8
; LE-NEXT: pop {r7, pc}
;
; BE-LABEL: caller_hard_bfloat_on_stack:
; BE: @ %bb.0: @ %entry
; BE-NEXT: .save {r7, lr}
; BE-NEXT: push {r7, lr}
; BE-NEXT: .pad #8
; BE-NEXT: sub sp, #8
; BE-NEXT: mov.w r0, #16256
; BE-NEXT: str r0, [sp]
; BE-NEXT: bl callee_hard_bfloat_on_stack
; BE-NEXT: add sp, #8
; BE-NEXT: pop {r7, pc}
;
; LE-BF16-LABEL: caller_hard_bfloat_on_stack:
; LE-BF16: @ %bb.0: @ %entry
; LE-BF16-NEXT: .save {r7, lr}
; LE-BF16-NEXT: push {r7, lr}
; LE-BF16-NEXT: .pad #8
; LE-BF16-NEXT: sub sp, #8
; LE-BF16-NEXT: mov.w r0, #16256
; LE-BF16-NEXT: str r0, [sp]
; LE-BF16-NEXT: bl callee_hard_bfloat_on_stack
; LE-BF16-NEXT: add sp, #8
; LE-BF16-NEXT: pop {r7, pc}
;
; BE-BF16-LABEL: caller_hard_bfloat_on_stack:
; BE-BF16: @ %bb.0: @ %entry
; BE-BF16-NEXT: .save {r7, lr}
; BE-BF16-NEXT: push {r7, lr}
; BE-BF16-NEXT: .pad #8
; BE-BF16-NEXT: sub sp, #8
; BE-BF16-NEXT: mov.w r0, #16256
; BE-BF16-NEXT: str r0, [sp]
; BE-BF16-NEXT: bl callee_hard_bfloat_on_stack
; BE-BF16-NEXT: add sp, #8
; BE-BF16-NEXT: pop {r7, pc}
;
; LE-GISEL-LABEL: caller_hard_bfloat_on_stack:
; LE-GISEL: @ %bb.0: @ %entry
; LE-GISEL-NEXT: .save {r7, lr}
; LE-GISEL-NEXT: push {r7, lr}
; LE-GISEL-NEXT: .pad #8
; LE-GISEL-NEXT: sub sp, #8
; LE-GISEL-NEXT: mov.w r0, #16256
; LE-GISEL-NEXT: str r0, [sp]
; LE-GISEL-NEXT: bl callee_hard_bfloat_on_stack
; LE-GISEL-NEXT: add sp, #8
; LE-GISEL-NEXT: pop {r7, pc}
entry:
%ret = call arm_aapcs_vfpcc bfloat @callee_hard_bfloat_on_stack(float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, float poison, bfloat 1.0)
ret void
}