[llvm] ARM: Fix calling convention for gnu half conversion functions (PR #147951)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 10 06:12:52 PDT 2025


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/147951

>From 4b3be712837e846d359d160eb9d1df4c5baf4b39 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 10 Jul 2025 19:54:15 +0900
Subject: [PATCH 1/2] ARM: Fix calling convention for gnu half conversion
 functions

I'm surprised at how bad the test coverage is here. There is some
overlap with existing tests, but they aren't comprehensive and do
not cover all the ABIs, or all the different types.

Fixes #147935
---
 llvm/lib/Target/ARM/ARMISelLowering.cpp       |   4 +
 .../issue147935-half-convert-libcall-abi.ll   | 188 ++++++++++++++++++
 2 files changed, 192 insertions(+)
 create mode 100644 llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll

diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 45311e92f9866..cbd43cde78548 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -715,10 +715,14 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
       setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_AAPCS);
       setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_AAPCS);
       setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_AAPCS);
+      setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee, CallingConv::ARM_AAPCS);
+      setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee, CallingConv::ARM_AAPCS);
     } else {
       setLibcallImplCallingConv(RTLIB::__truncsfhf2, CallingConv::ARM_APCS);
       setLibcallImplCallingConv(RTLIB::__truncdfhf2, CallingConv::ARM_APCS);
       setLibcallImplCallingConv(RTLIB::__extendhfsf2, CallingConv::ARM_APCS);
+      setLibcallImplCallingConv(RTLIB::__gnu_h2f_ieee, CallingConv::ARM_APCS);
+      setLibcallImplCallingConv(RTLIB::__gnu_f2h_ieee, CallingConv::ARM_APCS);
     }
   }
 
diff --git a/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll b/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
new file mode 100644
index 0000000000000..20cfa2b80eb79
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
@@ -0,0 +1,188 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=arm-unknown-linux-gnueabihf < %s | FileCheck -check-prefix=AAPCS-HARD %s
+; RUN: llc -mtriple=arm-unknown-linux-gnueabi < %s | FileCheck -check-prefix=AAPCS-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
+
+define i1 @test(half %self) #0 {
+; AAPCS-HARD-LABEL: test:
+; AAPCS-HARD:       @ %bb.0:
+; AAPCS-HARD-NEXT:    .save {r11, lr}
+; AAPCS-HARD-NEXT:    push {r11, lr}
+; AAPCS-HARD-NEXT:    vmov r0, s0
+; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
+; AAPCS-HARD-NEXT:    vmov s0, r0
+; AAPCS-HARD-NEXT:    mov r0, #0
+; AAPCS-HARD-NEXT:    vcmp.f32 s0, s0
+; AAPCS-HARD-NEXT:    vmrs APSR_nzcv, fpscr
+; AAPCS-HARD-NEXT:    movvs r0, #1
+; AAPCS-HARD-NEXT:    pop {r11, lr}
+; AAPCS-HARD-NEXT:    mov pc, lr
+;
+; AAPCS-SOFT-LABEL: test:
+; AAPCS-SOFT:       @ %bb.0:
+; AAPCS-SOFT-NEXT:    .save {r11, lr}
+; AAPCS-SOFT-NEXT:    push {r11, lr}
+; AAPCS-SOFT-NEXT:    bl __gnu_h2f_ieee
+; AAPCS-SOFT-NEXT:    vmov s0, r0
+; AAPCS-SOFT-NEXT:    mov r0, #0
+; AAPCS-SOFT-NEXT:    vcmp.f32 s0, s0
+; AAPCS-SOFT-NEXT:    vmrs APSR_nzcv, fpscr
+; AAPCS-SOFT-NEXT:    movvs r0, #1
+; AAPCS-SOFT-NEXT:    pop {r11, lr}
+; AAPCS-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
+  %_0 = fcmp une half %self, %self
+  ret i1 %_0
+}
+
+define float @f16_to_f32(ptr %p) #0 {
+; AAPCS-HARD-LABEL: f16_to_f32:
+; AAPCS-HARD:       @ %bb.0:
+; AAPCS-HARD-NEXT:    .save {r11, lr}
+; AAPCS-HARD-NEXT:    push {r11, lr}
+; AAPCS-HARD-NEXT:    ldrh r0, [r0]
+; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
+; AAPCS-HARD-NEXT:    vmov s0, r0
+; AAPCS-HARD-NEXT:    pop {r11, lr}
+; AAPCS-HARD-NEXT:    mov pc, lr
+;
+; AAPCS-SOFT-LABEL: f16_to_f32:
+; AAPCS-SOFT:       @ %bb.0:
+; AAPCS-SOFT-NEXT:    ldrh r0, [r0]
+; AAPCS-SOFT-NEXT:    b __gnu_h2f_ieee
+;
+; APCS-LABEL: f16_to_f32:
+; APCS:       @ %bb.0:
+; APCS-NEXT:    ldrh r0, [r0]
+; APCS-NEXT:    b __gnu_h2f_ieee
+  %load = load half, ptr %p
+  %cvt = fpext half %load to float
+  ret float %cvt
+}
+
+define void @f32_to_f16(ptr %p, float %arg) #0 {
+; AAPCS-HARD-LABEL: f32_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, s0
+; AAPCS-HARD-NEXT:    bl __gnu_f2h_ieee
+; AAPCS-HARD-NEXT:    strh r0, [r4]
+; AAPCS-HARD-NEXT:    pop {r4, lr}
+; AAPCS-HARD-NEXT:    mov pc, lr
+;
+; AAPCS-SOFT-LABEL: f32_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 r0, r1
+; AAPCS-SOFT-NEXT:    bl __gnu_f2h_ieee
+; AAPCS-SOFT-NEXT:    strh r0, [r4]
+; AAPCS-SOFT-NEXT:    pop {r4, lr}
+; AAPCS-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}
+  %cvt = fptrunc float %arg to half
+  store half %cvt, ptr %p
+  ret void
+}
+
+define double @f16_to_f64(ptr %p) #0 {
+; AAPCS-HARD-LABEL: f16_to_f64:
+; AAPCS-HARD:       @ %bb.0:
+; AAPCS-HARD-NEXT:    .save {r11, lr}
+; AAPCS-HARD-NEXT:    push {r11, lr}
+; AAPCS-HARD-NEXT:    ldrh r0, [r0]
+; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
+; AAPCS-HARD-NEXT:    vmov s0, r0
+; AAPCS-HARD-NEXT:    vcvt.f64.f32 d0, s0
+; AAPCS-HARD-NEXT:    pop {r11, lr}
+; AAPCS-HARD-NEXT:    mov pc, lr
+;
+; AAPCS-SOFT-LABEL: f16_to_f64:
+; AAPCS-SOFT:       @ %bb.0:
+; AAPCS-SOFT-NEXT:    .save {r11, lr}
+; AAPCS-SOFT-NEXT:    push {r11, lr}
+; AAPCS-SOFT-NEXT:    ldrh r0, [r0]
+; AAPCS-SOFT-NEXT:    bl __gnu_h2f_ieee
+; AAPCS-SOFT-NEXT:    vmov s0, r0
+; AAPCS-SOFT-NEXT:    vcvt.f64.f32 d0, s0
+; AAPCS-SOFT-NEXT:    vmov r0, r1, d0
+; AAPCS-SOFT-NEXT:    pop {r11, lr}
+; AAPCS-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
+  %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}
+  %cvt = fptrunc double %arg to half
+  store half %cvt, ptr %p
+  ret void
+}
+
+attributes #0 = { "target-features"="+vfp2" }

>From 9f1e397f9c72687f8895c95779ba649af3c1614f Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 10 Jul 2025 22:10:03 +0900
Subject: [PATCH 2/2] Test EABI case and move target-features to mattr

---
 .../issue147935-half-convert-libcall-abi.ll   | 253 ++++++++++++------
 1 file changed, 171 insertions(+), 82 deletions(-)

diff --git a/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll b/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
index 20cfa2b80eb79..33f3efccd039e 100644
--- a/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
+++ b/llvm/test/CodeGen/ARM/issue147935-half-convert-libcall-abi.ll
@@ -1,36 +1,65 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=arm-unknown-linux-gnueabihf < %s | FileCheck -check-prefix=AAPCS-HARD %s
-; RUN: llc -mtriple=arm-unknown-linux-gnueabi < %s | FileCheck -check-prefix=AAPCS-SOFT %s
+; 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
 
 define i1 @test(half %self) #0 {
-; AAPCS-HARD-LABEL: test:
-; AAPCS-HARD:       @ %bb.0:
-; AAPCS-HARD-NEXT:    .save {r11, lr}
-; AAPCS-HARD-NEXT:    push {r11, lr}
-; AAPCS-HARD-NEXT:    vmov r0, s0
-; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
-; AAPCS-HARD-NEXT:    vmov s0, r0
-; AAPCS-HARD-NEXT:    mov r0, #0
-; AAPCS-HARD-NEXT:    vcmp.f32 s0, s0
-; AAPCS-HARD-NEXT:    vmrs APSR_nzcv, fpscr
-; AAPCS-HARD-NEXT:    movvs r0, #1
-; AAPCS-HARD-NEXT:    pop {r11, lr}
-; AAPCS-HARD-NEXT:    mov pc, lr
+; 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
 ;
-; AAPCS-SOFT-LABEL: test:
-; AAPCS-SOFT:       @ %bb.0:
-; AAPCS-SOFT-NEXT:    .save {r11, lr}
-; AAPCS-SOFT-NEXT:    push {r11, lr}
-; AAPCS-SOFT-NEXT:    bl __gnu_h2f_ieee
-; AAPCS-SOFT-NEXT:    vmov s0, r0
-; AAPCS-SOFT-NEXT:    mov r0, #0
-; AAPCS-SOFT-NEXT:    vcmp.f32 s0, s0
-; AAPCS-SOFT-NEXT:    vmrs APSR_nzcv, fpscr
-; AAPCS-SOFT-NEXT:    movvs r0, #1
-; AAPCS-SOFT-NEXT:    pop {r11, lr}
-; AAPCS-SOFT-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:
@@ -48,20 +77,35 @@ define i1 @test(half %self) #0 {
 }
 
 define float @f16_to_f32(ptr %p) #0 {
-; AAPCS-HARD-LABEL: f16_to_f32:
-; AAPCS-HARD:       @ %bb.0:
-; AAPCS-HARD-NEXT:    .save {r11, lr}
-; AAPCS-HARD-NEXT:    push {r11, lr}
-; AAPCS-HARD-NEXT:    ldrh r0, [r0]
-; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
-; AAPCS-HARD-NEXT:    vmov s0, r0
-; AAPCS-HARD-NEXT:    pop {r11, lr}
-; AAPCS-HARD-NEXT:    mov pc, lr
+; 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
 ;
-; AAPCS-SOFT-LABEL: f16_to_f32:
-; AAPCS-SOFT:       @ %bb.0:
-; AAPCS-SOFT-NEXT:    ldrh r0, [r0]
-; AAPCS-SOFT-NEXT:    b __gnu_h2f_ieee
+; 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:
@@ -73,27 +117,49 @@ define float @f16_to_f32(ptr %p) #0 {
 }
 
 define void @f32_to_f16(ptr %p, float %arg) #0 {
-; AAPCS-HARD-LABEL: f32_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, s0
-; AAPCS-HARD-NEXT:    bl __gnu_f2h_ieee
-; AAPCS-HARD-NEXT:    strh r0, [r4]
-; AAPCS-HARD-NEXT:    pop {r4, lr}
-; AAPCS-HARD-NEXT:    mov pc, lr
+; 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
 ;
-; AAPCS-SOFT-LABEL: f32_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 r0, r1
-; AAPCS-SOFT-NEXT:    bl __gnu_f2h_ieee
-; AAPCS-SOFT-NEXT:    strh r0, [r4]
-; AAPCS-SOFT-NEXT:    pop {r4, lr}
-; AAPCS-SOFT-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:
@@ -109,28 +175,51 @@ define void @f32_to_f16(ptr %p, float %arg) #0 {
 }
 
 define double @f16_to_f64(ptr %p) #0 {
-; AAPCS-HARD-LABEL: f16_to_f64:
-; AAPCS-HARD:       @ %bb.0:
-; AAPCS-HARD-NEXT:    .save {r11, lr}
-; AAPCS-HARD-NEXT:    push {r11, lr}
-; AAPCS-HARD-NEXT:    ldrh r0, [r0]
-; AAPCS-HARD-NEXT:    bl __gnu_h2f_ieee
-; AAPCS-HARD-NEXT:    vmov s0, r0
-; AAPCS-HARD-NEXT:    vcvt.f64.f32 d0, s0
-; AAPCS-HARD-NEXT:    pop {r11, lr}
-; AAPCS-HARD-NEXT:    mov pc, lr
+; 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
 ;
-; AAPCS-SOFT-LABEL: f16_to_f64:
-; AAPCS-SOFT:       @ %bb.0:
-; AAPCS-SOFT-NEXT:    .save {r11, lr}
-; AAPCS-SOFT-NEXT:    push {r11, lr}
-; AAPCS-SOFT-NEXT:    ldrh r0, [r0]
-; AAPCS-SOFT-NEXT:    bl __gnu_h2f_ieee
-; AAPCS-SOFT-NEXT:    vmov s0, r0
-; AAPCS-SOFT-NEXT:    vcvt.f64.f32 d0, s0
-; AAPCS-SOFT-NEXT:    vmov r0, r1, d0
-; AAPCS-SOFT-NEXT:    pop {r11, lr}
-; AAPCS-SOFT-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:
@@ -185,4 +274,4 @@ define void @f64_to_f16(ptr %p, double %arg) #0 {
   ret void
 }
 
-attributes #0 = { "target-features"="+vfp2" }
+attributes #0 = { nounwind }



More information about the llvm-commits mailing list