[llvm] [LoongArch] Pass 'half' in the lower 16 bits of an f32 value with F/D ABI (PR #109368)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 26 01:47:59 PDT 2024
================
@@ -1354,6 +1358,40 @@ SDValue LoongArchTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
return SDValue();
}
+SDValue LoongArchTargetLowering::lowerFP_TO_FP16(SDValue Op,
+ SelectionDAG &DAG) const {
+ // Custom lower to ensure the libcall return is passed in an FPR on hard
+ // float ABIs.
+ SDLoc DL(Op);
+ MakeLibCallOptions CallOptions;
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Chain = SDValue();
+ RTLIB::Libcall LC = RTLIB::getFPROUND(Op0.getValueType(), MVT::f16);
+ SDValue Res;
+ std::tie(Res, Chain) =
+ makeLibCall(DAG, LC, MVT::f32, Op0, CallOptions, DL, Chain);
+ if (Subtarget.is64Bit())
+ return DAG.getNode(LoongArchISD::MOVFR2GR_S_LA64, DL, MVT::i64, Res);
+ return DAG.getBitcast(MVT::i32, Res);
+}
+
+SDValue LoongArchTargetLowering::lowerFP16_TO_FP(SDValue Op,
+ SelectionDAG &DAG) const {
+ // Custom lower to ensure the libcall argument is passed in an FPR on hard
+ // float ABIs.
----------------
heiher wrote:
Thanks for your guidance. I haven't quite managed to get it done yet. To pass fp16 in FPR (excluding libcall), `splitValueIntoRegisterParts` and `joinRegisterPartsIntoValue` insert all ones in the upper bits and extract the lower bits by casting to an integer type. I guess this is the key point where the fp16 value is promoted to an integer when it reaches the `FP16_TO_FP` operation, but I'm not sure how to bypass the integer type to achieve this.
Additionally, it seems that custom-lowering `FP16_TO_FP` and `FP_TO_FP16` to generate a libcall while keeping it passed in FPR works quite well and is fairly easy to implement, RISC-V is already using this approach. Can we go ahead with this? Thanks.
https://github.com/llvm/llvm-project/pull/109368
More information about the llvm-commits
mailing list