| ; 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 |
| } |