[llvm] r215891 - Teach the AArch64 backend to handle f16

Oliver Stannard Oliver.Stannard at arm.com
Tue Aug 19 01:58:37 PDT 2014


Hi Wan,

Currently clang will, by default, accept operations on fp16 values, but will store fp16 values as type i16 and use LLVM intrinsics to promote them to fp32 before performing the operation. The C spec does not allow passing fp16 types to or returning them from functions.

The ACLE (ARM C language Extensions) [1] does allow passing fp16s to and returning them from functions, so one of my patches currently in review [2] adds a second language option, HalfArgsAndReturns. When this is set, clang will use the half IR type and allow fp16 in function signatures, but will still promote to fp32 before performing any operations (using the standard fptrunc and fpext instructions). Using the IR half type is not strictly required for ACLE compatibility, but I added it as our calling convention requires handling fp16 differently to i16.

I don't have any plans to enable fp16 support in any non-ARM backends. If you just want to enable C's fp16 type, this should already be supported by all backends, as long as you have lowering for the llvm.convert.{to,from}.fp16 intrinsics.

Oliver

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0053c/index.html
[2] http://reviews.llvm.org/D4456

> -----Original Message-----
> From: Wan, Xiaofei [mailto:xiaofei.wan at intel.com]
> Sent: 19 August 2014 03:07
> To: Oliver Stannard
> Subject: RE: [llvm] r215891 - Teach the AArch64 backend to handle f16
>
> Oliver:
>
> Nice to meet you here, This is Xiaofei from Intel, I saw you submit a
> bunch of patches to support native fp16 in LLVM, thanks for working on
> this.
> I am working on same thing on x86(http://reviews.llvm.org/D4921), but
> my patch is rejected, the reason from the community is very reasonable,
> here my question is that, will your patch address the fp16 support on
> x86? Does it need similar handling on x86 backend?
> I notice you are from ARM, so will you also enable fp16 on x86, if not,
> I am happy to follow your direction to enable it on x86 since you
> already did much solid work on this area, thanks.
>
> Thanks
> Wan Xiaofei
>
> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of Oliver Stannard
> Sent: Monday, August 18, 2014 10:23 PM
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm] r215891 - Teach the AArch64 backend to handle f16
>
> Author: olista01
> Date: Mon Aug 18 09:22:39 2014
> New Revision: 215891
>
> URL: http://llvm.org/viewvc/llvm-project?rev=215891&view=rev
> Log:
> Teach the AArch64 backend to handle f16
>
> This allows the AArch64 backend to handle fadd, fsub, fmul and fdiv
> operations on f16 (half-precision) types by promoting to f32.
>
>
> Added:
>     llvm/trunk/test/CodeGen/AArch64/fp16-instructions.ll
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=215891&
> r1=215890&r2=215891&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Aug 18
> +++ 09:22:39 2014
> @@ -4264,6 +4264,9 @@ void SelectionDAGLegalize::PromoteNode(S
>                                    Tmp1, Tmp2, Node->getOperand(2)));
>      break;
>    }
> +  case ISD::FADD:
> +  case ISD::FSUB:
> +  case ISD::FMUL:
>    case ISD::FDIV:
>    case ISD::FREM:
>    case ISD::FPOW: {
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=21589
> 1&r1=215890&r2=215891&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Mon Aug 18
> +++ 09:22:39 2014
> @@ -278,6 +278,15 @@ AArch64TargetLowering::AArch64TargetLowe
>    setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
>    setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
>
> +  // f16 is storage-only, so we promote operations to f32 if we know
> + this is  // valid, and ignore them otherwise. The operations not
> + mentioned here will  // fail to select, but this is not a major
> + problem as no source language  // should be emitting native f16
> operations yet.
> +  setOperationAction(ISD::FADD, MVT::f16, Promote);
> + setOperationAction(ISD::FDIV, MVT::f16, Promote);
> + setOperationAction(ISD::FMUL, MVT::f16, Promote);
> + setOperationAction(ISD::FSUB, MVT::f16, Promote);
> +
>    // AArch64 has implementations of a lot of rounding-like FP
> operations.
>    static MVT RoundingTypes[] = { MVT::f32, MVT::f64};
>    for (unsigned I = 0; I < array_lengthof(RoundingTypes); ++I) {
>
> Added: llvm/trunk/test/CodeGen/AArch64/fp16-instructions.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/CodeGen/AArch64/fp16-
> instructions.ll?rev=215891&view=auto
> =======================================================================
> =======
> --- llvm/trunk/test/CodeGen/AArch64/fp16-instructions.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/fp16-instructions.ll Mon Aug 18
> +++ 09:22:39 2014
> @@ -0,0 +1,109 @@
> +; RUN: llc < %s -mtriple=aarch64-none-eabi | FileCheck %s
> +
> +define half @add_h(half %a, half %b) {
> +entry:
> +; CHECK-LABEL: add_h:
> +; CHECK: fcvt
> +; CHECK: fcvt
> +; CHECK: fadd
> +; CHECK: fcvt
> +  %0 = fadd half %a, %b
> +  ret half %0
> +}
> +
> +
> +define half @sub_h(half %a, half %b) {
> +entry:
> +; CHECK-LABEL: sub_h:
> +; CHECK: fcvt
> +; CHECK: fcvt
> +; CHECK: fsub
> +; CHECK: fcvt
> +  %0 = fsub half %a, %b
> +  ret half %0
> +}
> +
> +
> +define half @mul_h(half %a, half %b) {
> +entry:
> +; CHECK-LABEL: mul_h:
> +; CHECK: fcvt
> +; CHECK: fcvt
> +; CHECK: fmul
> +; CHECK: fcvt
> +  %0 = fmul half %a, %b
> +  ret half %0
> +}
> +
> +
> +define half @div_h(half %a, half %b) {
> +entry:
> +; CHECK-LABEL: div_h:
> +; CHECK: fcvt
> +; CHECK: fcvt
> +; CHECK: fdiv
> +; CHECK: fcvt
> +  %0 = fdiv half %a, %b
> +  ret half %0
> +}
> +
> +
> +define half @load_h(half* %a) {
> +entry:
> +; CHECK-LABEL: load_h:
> +; CHECK: ldr h
> +  %0 = load half* %a, align 4
> +  ret half %0
> +}
> +
> +
> +define void @store_h(half* %a, half %b) {
> +entry:
> +; CHECK-LABEL: store_h:
> +; CHECK: str h
> +  store half %b, half* %a, align 4
> +  ret void
> +}
> +
> +define half @s_to_h(float %a) {
> +; CHECK-LABEL: s_to_h:
> +; CHECK: fcvt
> +  %1 = fptrunc float %a to half
> +  ret half %1
> +}
> +
> +define half @d_to_h(double %a) {
> +; CHECK-LABEL: d_to_h:
> +; CHECK: fcvt
> +  %1 = fptrunc double %a to half
> +  ret half %1
> +}
> +
> +define float @h_to_s(half %a) {
> +; CHECK-LABEL: h_to_s:
> +; CHECK: fcvt
> +  %1 = fpext half %a to float
> +  ret float %1
> +}
> +
> +define double @h_to_d(half %a) {
> +; CHECK-LABEL: h_to_d:
> +; CHECK: fcvt
> +  %1 = fpext half %a to double
> +  ret double %1
> +}
> +
> +define half @bitcast_i_to_h(i16 %a) {
> +; CHECK-LABEL: bitcast_i_to_h:
> +; CHECK: fmov
> +  %1 = bitcast i16 %a to half
> +  ret half %1
> +}
> +
> +
> +define i16 @bitcast_h_to_i(half %a) {
> +; CHECK-LABEL: bitcast_h_to_i:
> +; CHECK: fmov
> +  %1 = bitcast half %a to i16
> +  ret i16 %1
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium.  Thank you.

ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No:  2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No:  2548782





More information about the llvm-commits mailing list