Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -61,6 +61,7 @@ bool TLSSupported; bool VLASupported; bool NoAsmVariants; // True if {|} are normal characters. + bool HasFloat16; bool HasFloat128; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; @@ -361,6 +362,9 @@ return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128; } // FIXME + /// \brief Determine whether _Float16 is supported on this target. + virtual bool hasFloat16Type() const { return HasFloat16; } + /// \brief Determine whether the __float128 type is supported on this target. virtual bool hasFloat128Type() const { return HasFloat128; } Index: lib/Basic/TargetInfo.cpp =================================================================== --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -32,6 +32,7 @@ TLSSupported = true; VLASupported = true; NoAsmVariants = false; + HasFloat16 = false; HasFloat128 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; Index: lib/Basic/Targets/ARM.h =================================================================== --- lib/Basic/Targets/ARM.h +++ lib/Basic/Targets/ARM.h @@ -69,7 +69,6 @@ unsigned Crypto : 1; unsigned DSP : 1; unsigned Unaligned : 1; - unsigned HasFullFP16 : 1; enum { LDREX_B = (1 << 0), /// byte (8-bit) Index: lib/Basic/Targets/ARM.cpp =================================================================== --- lib/Basic/Targets/ARM.cpp +++ lib/Basic/Targets/ARM.cpp @@ -379,7 +379,7 @@ Unaligned = 1; SoftFloat = SoftFloatABI = false; HWDiv = 0; - HasFullFP16 = 0; + HasFloat16 = 0; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". @@ -421,7 +421,7 @@ } else if (Feature == "+fp16") { HW_FP |= HW_FP_HP; } else if (Feature == "+fullfp16") { - HasFullFP16 = 1; + HasFloat16 = true; } } HW_FP &= ~HW_FP_remove; @@ -714,11 +714,11 @@ Builder.defineMacro("__ARM_FP_FAST", "1"); // Armv8.2-A FP16 vector intrinsic - if ((FPU & NeonFPU) && HasFullFP16) + if ((FPU & NeonFPU) && HasFloat16) Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); // Armv8.2-A FP16 scalar intrinsics - if (HasFullFP16) + if (HasFloat16) Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -3442,6 +3442,7 @@ static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, NeonTypeFlags TypeFlags, llvm::Triple::ArchType Arch, + bool HasFloat16=false, bool V1Ty=false) { int IsQuad = TypeFlags.isQuad(); switch (TypeFlags.getEltType()) { @@ -3452,9 +3453,8 @@ case NeonTypeFlags::Poly16: return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); case NeonTypeFlags::Float16: - // FIXME: Only AArch64 backend can so far properly handle half types. - // Remove else part once ARM backend support for half is complete. - if (Arch == llvm::Triple::aarch64) + if (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be || + HasFloat16) return llvm::VectorType::get(CGF->HalfTy, V1Ty ? 1 : (4 << IsQuad)); else return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); @@ -4338,8 +4338,9 @@ NeonTypeFlags Type(NeonTypeConst.getZExtValue()); bool Usgn = Type.isUnsigned(); bool Quad = Type.isQuad(); + const bool HasFloat16 = getTarget().hasFloat16Type(); - llvm::VectorType *VTy = GetNeonType(this, Type, Arch); + llvm::VectorType *VTy = GetNeonType(this, Type, Arch, HasFloat16); llvm::Type *Ty = VTy; if (!Ty) return nullptr;