Recently, bf16 type has been added in RISCV psABI. Now we need to support this datatype in LLVM backend. Right now, according to psABI, we basically address __bf16 like FP16.
Sorry to not have specifics on this - I'm working on a patch in this same area and as you've found as well, it's quite fiddly. Using the __truncsfhf2 and __extendhfsf2 libcalls isn't correct - they expect 16-bit floats in a different format to bfloat16.
I have checked compiler-rt/lib/builtins. There is truncsfbf2 for single-bfloat conversion, but I cannot find any library for bfloat extend.
libgcc has defined truncsfbf2, truncdfbf2, truncxfbf2, trunctfbf2, trunchfbf2, truncbfhf2 and extendbfsf2
I guess this might made me seems like a GNUism, but following the same rule should be easier for our life :P
If the libcall doesn't exist, you can cast it to i16, any_extend to i32, and shift it left by 16 and bitcast it to f32.
Which is what the default lowering in LegalizeDAG.cpp does.
This is an incorrect conversion. We can't truncate the mantissa. It would turn some nan encodings into infinity. Probably other issues I haven't thought of yet.
We need to use truncsfbf2
No need for else after an if that returns
Doesn't this need to be i64 on 64 bit target?
This creates an MVT::i16 after type legalization which is illegal.
You share the shift code between both paths by using XLenVT.
No need for else after if returns
We cannot directly use the default lowering in LegalizeDAG.cpp. It uses a bitcast from i32 to f32. However, i32 is not a legal type in RV64 backend.
In fact, without Zfbfmin enabled, bf16 type isn't legal and this condition will never happen. If Zfbfmin is enabled, maybe we can use FCVT.S.BF16 to directly convert BF16 value to an FP32 value.