[cfe-dev] [llvm-dev] _Float16 support

John McCall via cfe-dev cfe-dev at lists.llvm.org
Wed Jan 23 21:36:26 PST 2019

On 23 Jan 2019, at 14:52, Richard Smith via cfe-dev wrote:
> On Wed, 23 Jan 2019, 11:27 Craig Topper via llvm-dev, <
> llvm-dev at lists.llvm.org> wrote:
>> While looking at the codegen Andy showed, I notice that the initial
>> SelectionDAG looks like this for x86-64.
>>   t0: ch = EntryToken
>>       t2: f32,ch = CopyFromReg t0, Register:f32 %0
>>     t6: f16 = fp_round t2, TargetConstant:i64<1>
>>       t4: f32,ch = CopyFromReg t0, Register:f32 %1
>>     t7: f16 = fp_round t4, TargetConstant:i64<1>
>>   t8: f16 = fmul t6, t7
>>   t10: i64 = Constant<0>
>>     t12: ch = store<(store 2 into @x)> t0, t8, 
>> GlobalAddress:i64<half* @x>
>> 0, undef:i64
>>     t13: f32 = fp_extend t8
>>   t16: ch,glue = CopyToReg t12, Register:f32 $xmm0, t13
>>   t17: ch = X86ISD::RET_FLAG t16, TargetConstant:i32<0>, Register:f32
>> $xmm0, t16:1
>> The FP_ROUNDs for the arguments each have the flag set that indicates 
>> that
>> the fp_round doesn't lose any information. This is the
>> TargetConstant:i64<1> as the second operand.
>> As far as I can tell, any caller of this would have an FP_EXTEND from 
>> f16
>> to f32 in their initial selection dag for calling this function. When 
>> the
>> FP_EXTENDs are type legalized
>> by DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND, the FP_EXTEND will be
>> removed completely with no replacement operations. I believe this 
>> means
>> there is no guarantee that the f32 value passed in doesn't contain
>> precision beyond the range of f16. So the fp_round nodes saying no
>> information is lost in the callee are not accurate.
> That seems wrong to me from an ABI perspective; I would expect the 
> burden
> to be on the caller to only pass a valid "half" value to a "half"
> parameter. But this leads back to Andy's point: we're inventing an ABI 
> rule
> here.

Right.  IR and SelectionDAG representational choices aside, it seems to 
that, like GCC, Clang should not be permitting _Float16 on any target 
doesn't specify an ABI for it, because otherwise we're just creating
future compatibility problems for that target.  I'm surprised and 
that it wasn't implemented this way.

Unlike GCC, of course, we would implement it in all language modes on 
target, since there's zero reason to make it C-specific.

As for those internal representational choices: I'll leave SelectionDAG
up to the backend engineers, but I think that in IR, a half argument 
clearly correspond to a direct representation whenever hardware support 
half exists.  If the ABI calls for the type to be promoted and passed as 
float, that should be done in the frontend, just as is done for small 
types.  It would then make sense to have an attribute (fpext?) for 
purposes that says that a parameter is guaranteed to be a promotion of a
smaller type; Clang could use this whenever it's allowed by the psABI.


More information about the cfe-dev mailing list