[llvm] r213373 - ARM: support legalisation of "fptrunc ... to half" operations.

Oliver Stannard oliver.stannard at arm.com
Mon Jul 28 09:38:22 PDT 2014


Hi Tim,

This patch (or one of the related ones) breaks instruction selection for the
llvm.convert.from.fp16 intrinsic for ARM targets which do not have a
floating-point unit. I had a quick look but could not see anything obviously
wrong. Is this something you can fix quickly, or should I raise a bug
report?

This can be triggered with this IR:
declare float @llvm.convert.from.fp16.f32(i16 %a)
define float @h_to_f(i16 %a) {
  %1 = call float @llvm.convert.from.fp16.f32(i16 %a)
  ret float %1
}

Or with this C:
float foo(__fp16* a) {
  return *a;
}

Thanks,
Oliver

> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of Tim Northover
> Sent: 18 July 2014 14:01
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm] r213373 - ARM: support legalisation of "fptrunc ... to
> half" operations.
> 
> Author: tnorthover
> Date: Fri Jul 18 08:01:19 2014
> New Revision: 213373
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=213373&view=rev
> Log:
> ARM: support legalisation of "fptrunc ... to half" operations.
> 
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
>     llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>     llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/half.ll
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=
> 213373&r1=213372&r2=213373&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Fri Jul
> 18 08:01:19 2014
> @@ -397,6 +397,12 @@ SDValue DAGTypeLegalizer::SoftenFloatRes
>  SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
>    EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N-
> >getValueType(0));
>    SDValue Op = N->getOperand(0);
> +  if (N->getValueType(0) == MVT::f16) {
> +    // Semi-soften first, to FP_TO_FP16, so that targets which support
> f16 as a
> +    // storage-only type get a chance to select things.
> +    return DAG.getNode(ISD::FP_TO_FP16, SDLoc(N), NVT, Op);
> +  }
> +
>    RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N-
> >getValueType(0));
>    assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
>    return TLI.makeLibCall(DAG, LC, NVT, &Op, 1, false, SDLoc(N)).first;
> @@ -632,6 +638,7 @@ bool DAGTypeLegalizer::SoftenFloatOperan
> 
>    case ISD::BITCAST:     Res = SoftenFloatOp_BITCAST(N); break;
>    case ISD::BR_CC:       Res = SoftenFloatOp_BR_CC(N); break;
> +  case ISD::FP_EXTEND:   Res = SoftenFloatOp_FP_EXTEND(N); break;
>    case ISD::FP_TO_FP16:  // Same as FP_ROUND for softening purposes
>    case ISD::FP_ROUND:    Res = SoftenFloatOp_FP_ROUND(N); break;
>    case ISD::FP_TO_SINT:  Res = SoftenFloatOp_FP_TO_SINT(N); break;
> @@ -661,6 +668,22 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_
>                       GetSoftenedFloat(N->getOperand(0)));
>  }
> 
> +SDValue DAGTypeLegalizer::SoftenFloatOp_FP_EXTEND(SDNode *N) {
> +  // If we get here, the result must be legal but the source illegal.
> +  EVT SVT = N->getOperand(0).getValueType();
> +  EVT RVT = N->getValueType(0);
> +  SDValue Op = GetSoftenedFloat(N->getOperand(0));
> +
> +  if (SVT == MVT::f16)
> +    return DAG.getNode(ISD::FP16_TO_FP, SDLoc(N), RVT, Op);
> +
> +  RTLIB::Libcall LC = RTLIB::getFPEXT(SVT, RVT);
> +  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND
> libcall");
> +
> +  return TLI.makeLibCall(DAG, LC, RVT, &Op, 1, false, SDLoc(N)).first;
> +}
> +
> +
>  SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
>    // We actually deal with the partially-softened FP_TO_FP16 node too,
> which
>    // returns an i16 so doesn't meet the constraints necessary for
> FP_ROUND.
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=213373&
> r1=213372&r2=213373&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Fri Jul 18
> 08:01:19 2014
> @@ -425,6 +425,7 @@ private:
>    bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
>    SDValue SoftenFloatOp_BITCAST(SDNode *N);
>    SDValue SoftenFloatOp_BR_CC(SDNode *N);
> +  SDValue SoftenFloatOp_FP_EXTEND(SDNode *N);
>    SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
>    SDValue SoftenFloatOp_FP_TO_SINT(SDNode *N);
>    SDValue SoftenFloatOp_FP_TO_UINT(SDNode *N);
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=213373&r1=213
> 372&r2=213373&view=diff
> =======================================================================
> =======
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jul 18 08:01:19
> 2014
> @@ -396,8 +396,6 @@ ARMTargetLowering::ARMTargetLowering(Tar
>      addRegisterClass(MVT::f32, &ARM::SPRRegClass);
>      if (!Subtarget->isFPOnlySP())
>        addRegisterClass(MVT::f64, &ARM::DPRRegClass);
> -
> -    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
>    }
> 
>    for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
> @@ -582,8 +580,14 @@ ARMTargetLowering::ARMTargetLowering(Tar
> 
>    computeRegisterProperties();
> 
> -  // ARM does not have f32 extending load.
> +  // ARM does not have floating-point extending loads.
>    setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
> +  setLoadExtAction(ISD::EXTLOAD, MVT::f16, Expand);
> +
> +  // ... or truncating stores
> +  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
> +  setTruncStoreAction(MVT::f32, MVT::f16, Expand);
> +  setTruncStoreAction(MVT::f64, MVT::f16, Expand);
> 
>    // ARM does not have i1 sign extending load.
>    setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
> 
> Modified: llvm/trunk/test/CodeGen/ARM/half.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/CodeGen/ARM/half.ll?rev=213373&r1=213372&r2=213
> 373&view=diff
> =======================================================================
> =======
> --- llvm/trunk/test/CodeGen/ARM/half.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/half.ll Fri Jul 18 08:01:19 2014
> @@ -1,4 +1,6 @@
> -; RUN: llc < %s -mtriple=thumbv7s-apple-ios7.0 | FileCheck %s
> +; RUN: llc < %s -mtriple=thumbv7-apple-ios7.0 | FileCheck %s --check-
> prefix=CHECK --check-prefix=CHECK-OLD
> +; RUN: llc < %s -mtriple=thumbv7s-apple-ios7.0 | FileCheck %s --check-
> prefix=CHECK --check-prefix=CHECK-F16
> +; RUN: llc < %s -mtriple=thumbv8-apple-ios7.0 | FileCheck %s --check-
> prefix=CHECK  --check-prefix=CHECK-V8
> 
>  define void @test_load_store(half* %in, half* %out) {
>  ; CHECK-LABEL: test_load_store:
> @@ -24,3 +26,49 @@ define void @test_bitcast_to_half(half*
>    store half %val_fp, half* %addr
>    ret void
>  }
> +
> +define float @test_extend32(half* %addr) {
> +; CHECK-LABEL: test_extend32:
> +
> +; CHECK-OLD: b.w ___gnu_h2f_ieee
> +; CHECK-F16: vcvtb.f32.f16
> +; CHECK-V8: vcvtb.f32.f16
> +  %val16 = load half* %addr
> +  %val32 = fpext half %val16 to float
> +  ret float %val32
> +}
> +
> +define double @test_extend64(half* %addr) {
> +; CHECK-LABEL: test_extend64:
> +
> +; CHECK-OLD: blx ___gnu_h2f_ieee
> +; CHECK-OLD: vcvt.f64.f32
> +; CHECK-F16: vcvtb.f32.f16
> +; CHECK-F16: vcvt.f64.f32
> +; CHECK-V8: vcvtb.f64.f16
> +  %val16 = load half* %addr
> +  %val32 = fpext half %val16 to double
> +  ret double %val32
> +}
> +
> +define void @test_trunc32(float %in, half* %addr) {
> +; CHECK-LABEL: test_trunc32:
> +
> +; CHECK-OLD: blx ___gnu_f2h_ieee
> +; CHECK-F16: vcvtb.f16.f32
> +; CHECK-V8: vcvtb.f16.f32
> +  %val16 = fptrunc float %in to half
> +  store half %val16, half* %addr
> +  ret void
> +}
> +
> +define void @test_trunc64(double %in, half* %addr) {
> +; CHECK-LABEL: test_trunc64:
> +
> +; CHECK-OLD: blx ___truncdfhf2
> +; CHECK-F16: blx ___truncdfhf2
> +; CHECK-V8: vcvtb.f16.f64
> +  %val16 = fptrunc double %in to half
> +  store half %val16, half* %addr
> +  ret void
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits








More information about the llvm-commits mailing list