; 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,+fullfp16 | FileCheck %s --check-prefix=LE-FP16 ; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+fullfp16 | FileCheck %s --check-prefix=BE-FP16 ;; Global ISel successfully generates code for some functions for little-endian ;; without +fullfp16, 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,+fullfp16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=LE-FP16 ; RUN: llc -mtriple=armebv8m.main-none-eabi < %s -frame-pointer=none -mattr=+fp-armv8d16,+fullfp16 -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefix=BE-FP16 define arm_aapcscc half @callee_soft_half_in_reg(half %f) { ; LE-LABEL: callee_soft_half_in_reg: ; LE: @ %bb.0: @ %entry ; LE-NEXT: bx lr ; ; BE-LABEL: callee_soft_half_in_reg: ; BE: @ %bb.0: @ %entry ; BE-NEXT: bx lr ; ; LE-FP16-LABEL: callee_soft_half_in_reg: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: vmov.f16 s0, r0 ; LE-FP16-NEXT: vmov r0, s0 ; LE-FP16-NEXT: bx lr ; ; BE-FP16-LABEL: callee_soft_half_in_reg: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: vmov.f16 s0, r0 ; BE-FP16-NEXT: vmov r0, s0 ; BE-FP16-NEXT: bx lr ; ; LE-GISEL-LABEL: callee_soft_half_in_reg: ; LE-GISEL: @ %bb.0: @ %entry ; LE-GISEL-NEXT: bx lr entry: ret half %f } define void @caller_soft_half_in_reg() { ; LE-LABEL: caller_soft_half_in_reg: ; LE: @ %bb.0: @ %entry ; LE-NEXT: .save {r7, lr} ; LE-NEXT: push {r7, lr} ; LE-NEXT: mov.w r0, #15360 ; LE-NEXT: bl callee_soft_half_in_reg ; LE-NEXT: pop {r7, pc} ; ; BE-LABEL: caller_soft_half_in_reg: ; BE: @ %bb.0: @ %entry ; BE-NEXT: .save {r7, lr} ; BE-NEXT: push {r7, lr} ; BE-NEXT: mov.w r0, #15360 ; BE-NEXT: bl callee_soft_half_in_reg ; BE-NEXT: pop {r7, pc} ; ; LE-FP16-LABEL: caller_soft_half_in_reg: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: .save {r7, lr} ; LE-FP16-NEXT: push {r7, lr} ; LE-FP16-NEXT: mov.w r0, #15360 ; LE-FP16-NEXT: bl callee_soft_half_in_reg ; LE-FP16-NEXT: pop {r7, pc} ; ; BE-FP16-LABEL: caller_soft_half_in_reg: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: .save {r7, lr} ; BE-FP16-NEXT: push {r7, lr} ; BE-FP16-NEXT: mov.w r0, #15360 ; BE-FP16-NEXT: bl callee_soft_half_in_reg ; BE-FP16-NEXT: pop {r7, pc} ; ; LE-GISEL-LABEL: caller_soft_half_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, #15360 ; LE-GISEL-NEXT: bl callee_soft_half_in_reg ; LE-GISEL-NEXT: pop {r7, pc} entry: %ret = call arm_aapcscc half @callee_soft_half_in_reg(half 1.0) ret void } define arm_aapcscc half @callee_soft_half_on_stack(float %r0, float %r1, float %r2, float %r3, half %f) { ; LE-LABEL: callee_soft_half_on_stack: ; LE: @ %bb.0: @ %entry ; LE-NEXT: ldr r0, [sp] ; LE-NEXT: bx lr ; ; BE-LABEL: callee_soft_half_on_stack: ; BE: @ %bb.0: @ %entry ; BE-NEXT: ldr r0, [sp] ; BE-NEXT: bx lr ; ; LE-FP16-LABEL: callee_soft_half_on_stack: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: vldr.16 s0, [sp] ; LE-FP16-NEXT: vmov r0, s0 ; LE-FP16-NEXT: bx lr ; ; BE-FP16-LABEL: callee_soft_half_on_stack: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: vldr.16 s0, [sp, #2] ; BE-FP16-NEXT: vmov r0, s0 ; BE-FP16-NEXT: bx lr ; ; LE-GISEL-LABEL: callee_soft_half_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 half %f } define void @caller_soft_half_on_stack() { ; LE-LABEL: caller_soft_half_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, #15360 ; LE-NEXT: str r0, [sp] ; LE-NEXT: bl callee_soft_half_on_stack ; LE-NEXT: add sp, #8 ; LE-NEXT: pop {r7, pc} ; ; BE-LABEL: caller_soft_half_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, #15360 ; BE-NEXT: str r0, [sp] ; BE-NEXT: bl callee_soft_half_on_stack ; BE-NEXT: add sp, #8 ; BE-NEXT: pop {r7, pc} ; ; LE-FP16-LABEL: caller_soft_half_on_stack: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: .save {r7, lr} ; LE-FP16-NEXT: push {r7, lr} ; LE-FP16-NEXT: .pad #8 ; LE-FP16-NEXT: sub sp, #8 ; LE-FP16-NEXT: mov.w r0, #15360 ; LE-FP16-NEXT: str r0, [sp] ; LE-FP16-NEXT: bl callee_soft_half_on_stack ; LE-FP16-NEXT: add sp, #8 ; LE-FP16-NEXT: pop {r7, pc} ; ; BE-FP16-LABEL: caller_soft_half_on_stack: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: .save {r7, lr} ; BE-FP16-NEXT: push {r7, lr} ; BE-FP16-NEXT: .pad #8 ; BE-FP16-NEXT: sub sp, #8 ; BE-FP16-NEXT: mov.w r0, #15360 ; BE-FP16-NEXT: str r0, [sp] ; BE-FP16-NEXT: bl callee_soft_half_on_stack ; BE-FP16-NEXT: add sp, #8 ; BE-FP16-NEXT: pop {r7, pc} ; ; LE-GISEL-LABEL: caller_soft_half_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, #15360 ; LE-GISEL-NEXT: str r0, [sp] ; LE-GISEL-NEXT: bl callee_soft_half_on_stack ; LE-GISEL-NEXT: add sp, #8 ; LE-GISEL-NEXT: pop {r7, pc} entry: %ret = call arm_aapcscc half @callee_soft_half_on_stack(float poison, float poison, float poison, float poison, half 1.0) ret void } define arm_aapcs_vfpcc half @callee_hard_half_in_reg(half %f) { ; LE-LABEL: callee_hard_half_in_reg: ; LE: @ %bb.0: @ %entry ; LE-NEXT: bx lr ; ; BE-LABEL: callee_hard_half_in_reg: ; BE: @ %bb.0: @ %entry ; BE-NEXT: bx lr ; ; LE-FP16-LABEL: callee_hard_half_in_reg: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: bx lr ; ; BE-FP16-LABEL: callee_hard_half_in_reg: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: bx lr ; ; LE-GISEL-LABEL: callee_hard_half_in_reg: ; LE-GISEL: @ %bb.0: @ %entry ; LE-GISEL-NEXT: bx lr entry: ret half %f } define void @caller_hard_half_in_reg() { ; LE-LABEL: caller_hard_half_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_half_in_reg ; LE-NEXT: pop {r7, pc} ; LE-NEXT: .p2align 2 ; LE-NEXT: @ %bb.1: ; LE-NEXT: .LCPI5_0: ; LE-NEXT: .long 0x00003c00 @ float 2.15239444E-41 ; ; BE-LABEL: caller_hard_half_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_half_in_reg ; BE-NEXT: pop {r7, pc} ; BE-NEXT: .p2align 2 ; BE-NEXT: @ %bb.1: ; BE-NEXT: .LCPI5_0: ; BE-NEXT: .long 0x00003c00 @ float 2.15239444E-41 ; ; LE-FP16-LABEL: caller_hard_half_in_reg: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: .save {r7, lr} ; LE-FP16-NEXT: push {r7, lr} ; LE-FP16-NEXT: vmov.f16 s0, #1.000000e+00 ; LE-FP16-NEXT: bl callee_hard_half_in_reg ; LE-FP16-NEXT: pop {r7, pc} ; ; BE-FP16-LABEL: caller_hard_half_in_reg: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: .save {r7, lr} ; BE-FP16-NEXT: push {r7, lr} ; BE-FP16-NEXT: vmov.f16 s0, #1.000000e+00 ; BE-FP16-NEXT: bl callee_hard_half_in_reg ; BE-FP16-NEXT: pop {r7, pc} ; ; LE-GISEL-LABEL: caller_hard_half_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_half_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 0x00003c00 @ float 2.15239444E-41 entry: %ret = call arm_aapcs_vfpcc half @callee_hard_half_in_reg(half 1.0) ret void } define arm_aapcs_vfpcc half @callee_hard_half_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, half %f) { ; LE-LABEL: callee_hard_half_on_stack: ; LE: @ %bb.0: @ %entry ; LE-NEXT: vldr s0, [sp] ; LE-NEXT: bx lr ; ; BE-LABEL: callee_hard_half_on_stack: ; BE: @ %bb.0: @ %entry ; BE-NEXT: vldr s0, [sp] ; BE-NEXT: bx lr ; ; LE-FP16-LABEL: callee_hard_half_on_stack: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: vldr.16 s0, [sp] ; LE-FP16-NEXT: bx lr ; ; BE-FP16-LABEL: callee_hard_half_on_stack: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: vldr.16 s0, [sp, #2] ; BE-FP16-NEXT: bx lr ; ; LE-GISEL-LABEL: callee_hard_half_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 half %f } define void @caller_hard_half_on_stack() { ; LE-LABEL: caller_hard_half_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, #15360 ; LE-NEXT: str r0, [sp] ; LE-NEXT: bl callee_hard_half_on_stack ; LE-NEXT: add sp, #8 ; LE-NEXT: pop {r7, pc} ; ; BE-LABEL: caller_hard_half_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, #15360 ; BE-NEXT: str r0, [sp] ; BE-NEXT: bl callee_hard_half_on_stack ; BE-NEXT: add sp, #8 ; BE-NEXT: pop {r7, pc} ; ; LE-FP16-LABEL: caller_hard_half_on_stack: ; LE-FP16: @ %bb.0: @ %entry ; LE-FP16-NEXT: .save {r7, lr} ; LE-FP16-NEXT: push {r7, lr} ; LE-FP16-NEXT: .pad #8 ; LE-FP16-NEXT: sub sp, #8 ; LE-FP16-NEXT: mov.w r0, #15360 ; LE-FP16-NEXT: str r0, [sp] ; LE-FP16-NEXT: bl callee_hard_half_on_stack ; LE-FP16-NEXT: add sp, #8 ; LE-FP16-NEXT: pop {r7, pc} ; ; BE-FP16-LABEL: caller_hard_half_on_stack: ; BE-FP16: @ %bb.0: @ %entry ; BE-FP16-NEXT: .save {r7, lr} ; BE-FP16-NEXT: push {r7, lr} ; BE-FP16-NEXT: .pad #8 ; BE-FP16-NEXT: sub sp, #8 ; BE-FP16-NEXT: mov.w r0, #15360 ; BE-FP16-NEXT: str r0, [sp] ; BE-FP16-NEXT: bl callee_hard_half_on_stack ; BE-FP16-NEXT: add sp, #8 ; BE-FP16-NEXT: pop {r7, pc} ; ; LE-GISEL-LABEL: caller_hard_half_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, #15360 ; LE-GISEL-NEXT: str r0, [sp] ; LE-GISEL-NEXT: bl callee_hard_half_on_stack ; LE-GISEL-NEXT: add sp, #8 ; LE-GISEL-NEXT: pop {r7, pc} entry: %ret = call arm_aapcs_vfpcc half @callee_hard_half_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, half 1.0) ret void }