| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: llc -mtriple=arm-unknown-linux-gnueabihf -mattr=+vfp2 < %s | FileCheck -check-prefixes=AAPCS-HARD,GNU-AAPCS-HARD %s |
| ; RUN: llc -mtriple=arm-unknown-linux-gnueabi -mattr=+vfp2 < %s | FileCheck -check-prefixes=AAPCS-SOFT,GNU-AAPCS-SOFT %s |
| ; RUN: llc -mtriple=arm-unknown-linux-eabihf -mattr=+vfp2 < %s | FileCheck -check-prefixes=AAPCS-HARD,EABI-HARD %s |
| ; RUN: llc -mtriple=arm-unknown-linux-eabi -mattr=+vfp2 < %s | FileCheck -check-prefixes=AAPCS-SOFT,EABI-SOFT %s |
| ; RUN: llc -mtriple=armv7-unknown-linux -target-abi=apcs -float-abi=soft < %s | FileCheck -check-prefix=APCS %s |
| ; RUN: llc -mtriple=armv7-unknown-linux -target-abi=apcs -float-abi=hard < %s | FileCheck -check-prefix=APCS %s |
| ; RUN: llc -mtriple=armv7k-apple-watchos2.0 -mcpu=cortex-a7 < %s | FileCheck -check-prefix=WATCHABI-HARD %s |
| ; RUN: llc -mtriple=armv7k-apple-watchos2.0 -mcpu=cortex-a7 -float-abi=soft < %s | FileCheck -check-prefix=WATCHABI-SOFT %s |
| |
| define i1 @test(half %self) #0 { |
| ; GNU-AAPCS-HARD-LABEL: test: |
| ; GNU-AAPCS-HARD: @ %bb.0: |
| ; GNU-AAPCS-HARD-NEXT: .save {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: push {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: vmov r0, s0 |
| ; GNU-AAPCS-HARD-NEXT: bl __gnu_h2f_ieee |
| ; GNU-AAPCS-HARD-NEXT: vmov s0, r0 |
| ; GNU-AAPCS-HARD-NEXT: mov r0, #0 |
| ; GNU-AAPCS-HARD-NEXT: vcmp.f32 s0, s0 |
| ; GNU-AAPCS-HARD-NEXT: vmrs APSR_nzcv, fpscr |
| ; GNU-AAPCS-HARD-NEXT: movvs r0, #1 |
| ; GNU-AAPCS-HARD-NEXT: pop {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: mov pc, lr |
| ; |
| ; GNU-AAPCS-SOFT-LABEL: test: |
| ; GNU-AAPCS-SOFT: @ %bb.0: |
| ; GNU-AAPCS-SOFT-NEXT: .save {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: push {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: bl __gnu_h2f_ieee |
| ; GNU-AAPCS-SOFT-NEXT: vmov s0, r0 |
| ; GNU-AAPCS-SOFT-NEXT: mov r0, #0 |
| ; GNU-AAPCS-SOFT-NEXT: vcmp.f32 s0, s0 |
| ; GNU-AAPCS-SOFT-NEXT: vmrs APSR_nzcv, fpscr |
| ; GNU-AAPCS-SOFT-NEXT: movvs r0, #1 |
| ; GNU-AAPCS-SOFT-NEXT: pop {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: mov pc, lr |
| ; |
| ; EABI-HARD-LABEL: test: |
| ; EABI-HARD: @ %bb.0: |
| ; EABI-HARD-NEXT: .save {r11, lr} |
| ; EABI-HARD-NEXT: push {r11, lr} |
| ; EABI-HARD-NEXT: vmov r0, s0 |
| ; EABI-HARD-NEXT: bl __aeabi_h2f |
| ; EABI-HARD-NEXT: vmov s0, r0 |
| ; EABI-HARD-NEXT: mov r0, #0 |
| ; EABI-HARD-NEXT: vcmp.f32 s0, s0 |
| ; EABI-HARD-NEXT: vmrs APSR_nzcv, fpscr |
| ; EABI-HARD-NEXT: movvs r0, #1 |
| ; EABI-HARD-NEXT: pop {r11, lr} |
| ; EABI-HARD-NEXT: mov pc, lr |
| ; |
| ; EABI-SOFT-LABEL: test: |
| ; EABI-SOFT: @ %bb.0: |
| ; EABI-SOFT-NEXT: .save {r11, lr} |
| ; EABI-SOFT-NEXT: push {r11, lr} |
| ; EABI-SOFT-NEXT: bl __aeabi_h2f |
| ; EABI-SOFT-NEXT: vmov s0, r0 |
| ; EABI-SOFT-NEXT: mov r0, #0 |
| ; EABI-SOFT-NEXT: vcmp.f32 s0, s0 |
| ; EABI-SOFT-NEXT: vmrs APSR_nzcv, fpscr |
| ; EABI-SOFT-NEXT: movvs r0, #1 |
| ; EABI-SOFT-NEXT: pop {r11, lr} |
| ; EABI-SOFT-NEXT: mov pc, lr |
| ; |
| ; APCS-LABEL: test: |
| ; APCS: @ %bb.0: |
| ; APCS-NEXT: push {lr} |
| ; APCS-NEXT: bl __gnu_h2f_ieee |
| ; APCS-NEXT: vmov s0, r0 |
| ; APCS-NEXT: mov r0, #0 |
| ; APCS-NEXT: vcmp.f32 s0, s0 |
| ; APCS-NEXT: vmrs APSR_nzcv, fpscr |
| ; APCS-NEXT: movwvs r0, #1 |
| ; APCS-NEXT: pop {lr} |
| ; APCS-NEXT: bx lr |
| ; |
| ; WATCHABI-HARD-LABEL: test: |
| ; WATCHABI-HARD: @ %bb.0: |
| ; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-HARD-NEXT: mov r0, #0 |
| ; WATCHABI-HARD-NEXT: vcmp.f32 s0, s0 |
| ; WATCHABI-HARD-NEXT: vmrs APSR_nzcv, fpscr |
| ; WATCHABI-HARD-NEXT: movwvs r0, #1 |
| ; WATCHABI-HARD-NEXT: bx lr |
| ; |
| ; WATCHABI-SOFT-LABEL: test: |
| ; WATCHABI-SOFT: @ %bb.0: |
| ; WATCHABI-SOFT-NEXT: vmov s0, r0 |
| ; WATCHABI-SOFT-NEXT: mov r1, #0 |
| ; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-SOFT-NEXT: vcmp.f32 s0, s0 |
| ; WATCHABI-SOFT-NEXT: vmrs APSR_nzcv, fpscr |
| ; WATCHABI-SOFT-NEXT: movwvs r1, #1 |
| ; WATCHABI-SOFT-NEXT: mov r0, r1 |
| ; WATCHABI-SOFT-NEXT: bx lr |
| %_0 = fcmp une half %self, %self |
| ret i1 %_0 |
| } |
| |
| define float @f16_to_f32(ptr %p) #0 { |
| ; GNU-AAPCS-HARD-LABEL: f16_to_f32: |
| ; GNU-AAPCS-HARD: @ %bb.0: |
| ; GNU-AAPCS-HARD-NEXT: .save {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: push {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: ldrh r0, [r0] |
| ; GNU-AAPCS-HARD-NEXT: bl __gnu_h2f_ieee |
| ; GNU-AAPCS-HARD-NEXT: vmov s0, r0 |
| ; GNU-AAPCS-HARD-NEXT: pop {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: mov pc, lr |
| ; |
| ; GNU-AAPCS-SOFT-LABEL: f16_to_f32: |
| ; GNU-AAPCS-SOFT: @ %bb.0: |
| ; GNU-AAPCS-SOFT-NEXT: ldrh r0, [r0] |
| ; GNU-AAPCS-SOFT-NEXT: b __gnu_h2f_ieee |
| ; |
| ; EABI-HARD-LABEL: f16_to_f32: |
| ; EABI-HARD: @ %bb.0: |
| ; EABI-HARD-NEXT: .save {r11, lr} |
| ; EABI-HARD-NEXT: push {r11, lr} |
| ; EABI-HARD-NEXT: ldrh r0, [r0] |
| ; EABI-HARD-NEXT: bl __aeabi_h2f |
| ; EABI-HARD-NEXT: vmov s0, r0 |
| ; EABI-HARD-NEXT: pop {r11, lr} |
| ; EABI-HARD-NEXT: mov pc, lr |
| ; |
| ; EABI-SOFT-LABEL: f16_to_f32: |
| ; EABI-SOFT: @ %bb.0: |
| ; EABI-SOFT-NEXT: ldrh r0, [r0] |
| ; EABI-SOFT-NEXT: b __aeabi_h2f |
| ; |
| ; APCS-LABEL: f16_to_f32: |
| ; APCS: @ %bb.0: |
| ; APCS-NEXT: ldrh r0, [r0] |
| ; APCS-NEXT: b __gnu_h2f_ieee |
| ; |
| ; WATCHABI-HARD-LABEL: f16_to_f32: |
| ; WATCHABI-HARD: @ %bb.0: |
| ; WATCHABI-HARD-NEXT: ldrh r0, [r0] |
| ; WATCHABI-HARD-NEXT: vmov s0, r0 |
| ; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-HARD-NEXT: bx lr |
| ; |
| ; WATCHABI-SOFT-LABEL: f16_to_f32: |
| ; WATCHABI-SOFT: @ %bb.0: |
| ; WATCHABI-SOFT-NEXT: ldrh r0, [r0] |
| ; WATCHABI-SOFT-NEXT: vmov s0, r0 |
| ; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-SOFT-NEXT: vmov r0, s0 |
| ; WATCHABI-SOFT-NEXT: bx lr |
| %load = load half, ptr %p |
| %cvt = fpext half %load to float |
| ret float %cvt |
| } |
| |
| define void @f32_to_f16(ptr %p, float %arg) #0 { |
| ; GNU-AAPCS-HARD-LABEL: f32_to_f16: |
| ; GNU-AAPCS-HARD: @ %bb.0: |
| ; GNU-AAPCS-HARD-NEXT: .save {r4, lr} |
| ; GNU-AAPCS-HARD-NEXT: push {r4, lr} |
| ; GNU-AAPCS-HARD-NEXT: mov r4, r0 |
| ; GNU-AAPCS-HARD-NEXT: vmov r0, s0 |
| ; GNU-AAPCS-HARD-NEXT: bl __gnu_f2h_ieee |
| ; GNU-AAPCS-HARD-NEXT: strh r0, [r4] |
| ; GNU-AAPCS-HARD-NEXT: pop {r4, lr} |
| ; GNU-AAPCS-HARD-NEXT: mov pc, lr |
| ; |
| ; GNU-AAPCS-SOFT-LABEL: f32_to_f16: |
| ; GNU-AAPCS-SOFT: @ %bb.0: |
| ; GNU-AAPCS-SOFT-NEXT: .save {r4, lr} |
| ; GNU-AAPCS-SOFT-NEXT: push {r4, lr} |
| ; GNU-AAPCS-SOFT-NEXT: mov r4, r0 |
| ; GNU-AAPCS-SOFT-NEXT: mov r0, r1 |
| ; GNU-AAPCS-SOFT-NEXT: bl __gnu_f2h_ieee |
| ; GNU-AAPCS-SOFT-NEXT: strh r0, [r4] |
| ; GNU-AAPCS-SOFT-NEXT: pop {r4, lr} |
| ; GNU-AAPCS-SOFT-NEXT: mov pc, lr |
| ; |
| ; EABI-HARD-LABEL: f32_to_f16: |
| ; EABI-HARD: @ %bb.0: |
| ; EABI-HARD-NEXT: .save {r4, lr} |
| ; EABI-HARD-NEXT: push {r4, lr} |
| ; EABI-HARD-NEXT: mov r4, r0 |
| ; EABI-HARD-NEXT: vmov r0, s0 |
| ; EABI-HARD-NEXT: bl __aeabi_f2h |
| ; EABI-HARD-NEXT: strh r0, [r4] |
| ; EABI-HARD-NEXT: pop {r4, lr} |
| ; EABI-HARD-NEXT: mov pc, lr |
| ; |
| ; EABI-SOFT-LABEL: f32_to_f16: |
| ; EABI-SOFT: @ %bb.0: |
| ; EABI-SOFT-NEXT: .save {r4, lr} |
| ; EABI-SOFT-NEXT: push {r4, lr} |
| ; EABI-SOFT-NEXT: mov r4, r0 |
| ; EABI-SOFT-NEXT: mov r0, r1 |
| ; EABI-SOFT-NEXT: bl __aeabi_f2h |
| ; EABI-SOFT-NEXT: strh r0, [r4] |
| ; EABI-SOFT-NEXT: pop {r4, lr} |
| ; EABI-SOFT-NEXT: mov pc, lr |
| ; |
| ; APCS-LABEL: f32_to_f16: |
| ; APCS: @ %bb.0: |
| ; APCS-NEXT: push {r4, lr} |
| ; APCS-NEXT: mov r4, r0 |
| ; APCS-NEXT: mov r0, r1 |
| ; APCS-NEXT: bl __gnu_f2h_ieee |
| ; APCS-NEXT: strh r0, [r4] |
| ; APCS-NEXT: pop {r4, pc} |
| ; |
| ; WATCHABI-HARD-LABEL: f32_to_f16: |
| ; WATCHABI-HARD: @ %bb.0: |
| ; WATCHABI-HARD-NEXT: vcvtb.f16.f32 s0, s0 |
| ; WATCHABI-HARD-NEXT: vmov r1, s0 |
| ; WATCHABI-HARD-NEXT: strh r1, [r0] |
| ; WATCHABI-HARD-NEXT: bx lr |
| ; |
| ; WATCHABI-SOFT-LABEL: f32_to_f16: |
| ; WATCHABI-SOFT: @ %bb.0: |
| ; WATCHABI-SOFT-NEXT: vmov s0, r1 |
| ; WATCHABI-SOFT-NEXT: vcvtb.f16.f32 s0, s0 |
| ; WATCHABI-SOFT-NEXT: vmov r1, s0 |
| ; WATCHABI-SOFT-NEXT: strh r1, [r0] |
| ; WATCHABI-SOFT-NEXT: bx lr |
| %cvt = fptrunc float %arg to half |
| store half %cvt, ptr %p |
| ret void |
| } |
| |
| define double @f16_to_f64(ptr %p) #0 { |
| ; GNU-AAPCS-HARD-LABEL: f16_to_f64: |
| ; GNU-AAPCS-HARD: @ %bb.0: |
| ; GNU-AAPCS-HARD-NEXT: .save {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: push {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: ldrh r0, [r0] |
| ; GNU-AAPCS-HARD-NEXT: bl __gnu_h2f_ieee |
| ; GNU-AAPCS-HARD-NEXT: vmov s0, r0 |
| ; GNU-AAPCS-HARD-NEXT: vcvt.f64.f32 d0, s0 |
| ; GNU-AAPCS-HARD-NEXT: pop {r11, lr} |
| ; GNU-AAPCS-HARD-NEXT: mov pc, lr |
| ; |
| ; GNU-AAPCS-SOFT-LABEL: f16_to_f64: |
| ; GNU-AAPCS-SOFT: @ %bb.0: |
| ; GNU-AAPCS-SOFT-NEXT: .save {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: push {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: ldrh r0, [r0] |
| ; GNU-AAPCS-SOFT-NEXT: bl __gnu_h2f_ieee |
| ; GNU-AAPCS-SOFT-NEXT: vmov s0, r0 |
| ; GNU-AAPCS-SOFT-NEXT: vcvt.f64.f32 d0, s0 |
| ; GNU-AAPCS-SOFT-NEXT: vmov r0, r1, d0 |
| ; GNU-AAPCS-SOFT-NEXT: pop {r11, lr} |
| ; GNU-AAPCS-SOFT-NEXT: mov pc, lr |
| ; |
| ; EABI-HARD-LABEL: f16_to_f64: |
| ; EABI-HARD: @ %bb.0: |
| ; EABI-HARD-NEXT: .save {r11, lr} |
| ; EABI-HARD-NEXT: push {r11, lr} |
| ; EABI-HARD-NEXT: ldrh r0, [r0] |
| ; EABI-HARD-NEXT: bl __aeabi_h2f |
| ; EABI-HARD-NEXT: vmov s0, r0 |
| ; EABI-HARD-NEXT: vcvt.f64.f32 d0, s0 |
| ; EABI-HARD-NEXT: pop {r11, lr} |
| ; EABI-HARD-NEXT: mov pc, lr |
| ; |
| ; EABI-SOFT-LABEL: f16_to_f64: |
| ; EABI-SOFT: @ %bb.0: |
| ; EABI-SOFT-NEXT: .save {r11, lr} |
| ; EABI-SOFT-NEXT: push {r11, lr} |
| ; EABI-SOFT-NEXT: ldrh r0, [r0] |
| ; EABI-SOFT-NEXT: bl __aeabi_h2f |
| ; EABI-SOFT-NEXT: vmov s0, r0 |
| ; EABI-SOFT-NEXT: vcvt.f64.f32 d0, s0 |
| ; EABI-SOFT-NEXT: vmov r0, r1, d0 |
| ; EABI-SOFT-NEXT: pop {r11, lr} |
| ; EABI-SOFT-NEXT: mov pc, lr |
| ; |
| ; APCS-LABEL: f16_to_f64: |
| ; APCS: @ %bb.0: |
| ; APCS-NEXT: push {lr} |
| ; APCS-NEXT: ldrh r0, [r0] |
| ; APCS-NEXT: bl __gnu_h2f_ieee |
| ; APCS-NEXT: vmov s0, r0 |
| ; APCS-NEXT: vcvt.f64.f32 d16, s0 |
| ; APCS-NEXT: vmov r0, r1, d16 |
| ; APCS-NEXT: pop {lr} |
| ; APCS-NEXT: bx lr |
| ; |
| ; WATCHABI-HARD-LABEL: f16_to_f64: |
| ; WATCHABI-HARD: @ %bb.0: |
| ; WATCHABI-HARD-NEXT: ldrh r0, [r0] |
| ; WATCHABI-HARD-NEXT: vmov s0, r0 |
| ; WATCHABI-HARD-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-HARD-NEXT: vcvt.f64.f32 d0, s0 |
| ; WATCHABI-HARD-NEXT: bx lr |
| ; |
| ; WATCHABI-SOFT-LABEL: f16_to_f64: |
| ; WATCHABI-SOFT: @ %bb.0: |
| ; WATCHABI-SOFT-NEXT: ldrh r0, [r0] |
| ; WATCHABI-SOFT-NEXT: vmov s0, r0 |
| ; WATCHABI-SOFT-NEXT: vcvtb.f32.f16 s0, s0 |
| ; WATCHABI-SOFT-NEXT: vcvt.f64.f32 d16, s0 |
| ; WATCHABI-SOFT-NEXT: vmov r0, r1, d16 |
| ; WATCHABI-SOFT-NEXT: bx lr |
| %load = load half, ptr %p |
| %cvt = fpext half %load to double |
| ret double %cvt |
| } |
| |
| define void @f64_to_f16(ptr %p, double %arg) #0 { |
| ; AAPCS-HARD-LABEL: f64_to_f16: |
| ; AAPCS-HARD: @ %bb.0: |
| ; AAPCS-HARD-NEXT: .save {r4, lr} |
| ; AAPCS-HARD-NEXT: push {r4, lr} |
| ; AAPCS-HARD-NEXT: mov r4, r0 |
| ; AAPCS-HARD-NEXT: vmov r0, r1, d0 |
| ; AAPCS-HARD-NEXT: bl __aeabi_d2h |
| ; AAPCS-HARD-NEXT: strh r0, [r4] |
| ; AAPCS-HARD-NEXT: pop {r4, lr} |
| ; AAPCS-HARD-NEXT: mov pc, lr |
| ; |
| ; AAPCS-SOFT-LABEL: f64_to_f16: |
| ; AAPCS-SOFT: @ %bb.0: |
| ; AAPCS-SOFT-NEXT: .save {r4, lr} |
| ; AAPCS-SOFT-NEXT: push {r4, lr} |
| ; AAPCS-SOFT-NEXT: mov r4, r0 |
| ; AAPCS-SOFT-NEXT: mov r1, r3 |
| ; AAPCS-SOFT-NEXT: mov r0, r2 |
| ; AAPCS-SOFT-NEXT: bl __aeabi_d2h |
| ; AAPCS-SOFT-NEXT: strh r0, [r4] |
| ; AAPCS-SOFT-NEXT: pop {r4, lr} |
| ; AAPCS-SOFT-NEXT: mov pc, lr |
| ; |
| ; APCS-LABEL: f64_to_f16: |
| ; APCS: @ %bb.0: |
| ; APCS-NEXT: push {r4, lr} |
| ; APCS-NEXT: mov r4, r0 |
| ; APCS-NEXT: mov r0, r1 |
| ; APCS-NEXT: mov r1, r2 |
| ; APCS-NEXT: bl __truncdfhf2 |
| ; APCS-NEXT: strh r0, [r4] |
| ; APCS-NEXT: pop {r4, pc} |
| ; |
| ; WATCHABI-HARD-LABEL: f64_to_f16: |
| ; WATCHABI-HARD: @ %bb.0: |
| ; WATCHABI-HARD-NEXT: push {r4, lr} |
| ; WATCHABI-HARD-NEXT: sub sp, sp, #8 |
| ; WATCHABI-HARD-NEXT: mov r4, r0 |
| ; WATCHABI-HARD-NEXT: bl ___truncdfhf2 |
| ; WATCHABI-HARD-NEXT: strh r0, [r4] |
| ; WATCHABI-HARD-NEXT: add sp, sp, #8 |
| ; WATCHABI-HARD-NEXT: pop {r4, pc} |
| ; |
| ; WATCHABI-SOFT-LABEL: f64_to_f16: |
| ; WATCHABI-SOFT: @ %bb.0: |
| ; WATCHABI-SOFT-NEXT: push {r4, lr} |
| ; WATCHABI-SOFT-NEXT: sub sp, sp, #8 |
| ; WATCHABI-SOFT-NEXT: mov r4, r0 |
| ; WATCHABI-SOFT-NEXT: mov r1, r3 |
| ; WATCHABI-SOFT-NEXT: mov r0, r2 |
| ; WATCHABI-SOFT-NEXT: bl ___truncdfhf2 |
| ; WATCHABI-SOFT-NEXT: strh r0, [r4] |
| ; WATCHABI-SOFT-NEXT: add sp, sp, #8 |
| ; WATCHABI-SOFT-NEXT: pop {r4, pc} |
| %cvt = fptrunc double %arg to half |
| store half %cvt, ptr %p |
| ret void |
| } |
| |
| attributes #0 = { nounwind } |