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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 10 05:37:57 PDT 2025


================
@@ -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" }
----------------
nikic wrote:

I'd move this into `-mattr` on the llc invocations where relevant.

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


More information about the llvm-commits mailing list