[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
>> 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
>> to f32 in their initial selection dag for calling this function. When
>> FP_EXTENDs are type legalized
>> by DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND, the FP_EXTEND will be
>> removed completely with no replacement operations. I believe this
>> 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
> 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
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