[OpenCL] Representing OpenCL half type by _Float16 type


Clang supports two 16 bit floating point builtin types: __fp16 and _Float16. Their differences are here


Currently clang supports OpenCL half type as __fp16, one significant disadvantage of which is that arithmetic operations are emitted as fp32 instead of fp16 instructions in LLVM IR. Another disadvantage is interoperability with C++ programs, which uses _Float16 mostly since it is an ISO standard whereas __fp16 is not.

OpenCL spec v 2.0 s (https://www.khronos.org/registry/OpenCL/specs/opencl-2.0-openclc.pdf ) defines half type. There is no requirement that it has to be __fp16 or _Float16 type in clang. Actually, it seems both __fp16 and _Float16 can be used to represent OpenCL half type.

Considering the advantages of _Float16 type, I am wondering whether we should consider using _Float16 to represent OpenCL half type.

Any comments are welcome.


Yaxun (Sam) Liu

Hi Sam,

I assume OpenCL half type mapped to __fp16 as OpenCL specification defines it as “A 16-bit floating-point conforming to the IEEE 754-2008 half precision storage format”. This aligned with __fp16 description from clang documentation.

OpenCL cl_khr_fp16 extension enables arithmetic operations on ‘half’ data types and I think it’s reasonable to map ‘half’ data type to _Float16 if cl_khr_fp16 is enabled.

Is it possible to map ‘half’ data type to _Float16 and keep the restrictions of OpenCL core specification?



Hi Alexey,

We have semantic checks to enforce the restrictions on half type when cl_khr_fp16 is not enabled. We could keep these checks if we switch to _Float16.


The proposal sounds good to me.

I assume that by changing OpenCL half data type representation from __fp16 to _Float16, we align it with cl_khr_fp16 extension. There should be no functional changes for programs not using this extension. Right?



Hi Sam,

I would disagree regarding the requirements on the half implementation. Section 6.1.1 explicitly says:

“The half data type must conform to the IEEE 754-2008 half precision storage format.”

Do you suggest to change the spec to refer to ISO standard instead of IEEE for half type? I am a bit concerned about backwards compatibility though in case current implementations are relying on the higher precision arithmetic. Do you know the implications on the precision and ulp bounds?




The doc Sam referenced seems to be implying that sizeof(_Float16) is allowed to be 4 if the target doesn’t support “native” half precision operations. Is that correct? That would be a showstopper for OpenCL where sizeof(half) must be 2.


Hi Brian,

Generally, all builtin types are configurable in Clang based on the target (incl int or float). We have a way to enforce the language specific settings using TargetInfo::adjust. We currently already force the half width to 2 bytes there.

However, subclass targets can still override this logic. Not something we recommend to do though.