[clang] [compiler-rt] [llvm] [SystemZ] Add support for half (fp16) (PR #109164)
Ulrich Weigand via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 19 05:49:24 PST 2024
================
@@ -6108,6 +6160,133 @@ static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG) {
return Op;
}
+SDValue SystemZTargetLowering::LowerFP_EXTEND(SDValue Op,
+ SelectionDAG &DAG) const {
+ bool IsStrict = Op->isStrictFPOpcode();
+ SDValue In = Op.getOperand(IsStrict ? 1 : 0);
+ MVT VT = Op.getSimpleValueType();
+ MVT SVT = In.getSimpleValueType();
+ if (SVT != MVT::f16)
+ return Op;
+
+ SDLoc DL(Op);
+ SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
+
+ // Need a libcall. XXX factor out (below)
+ TargetLowering::CallLoweringInfo CLI(DAG);
+ Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Node = In;
+ Entry.Ty = EVT(SVT).getTypeForEVT(*DAG.getContext());
+ Args.push_back(Entry);
+ SDValue Callee = DAG.getExternalSymbol(
+ getLibcallName(RTLIB::FPEXT_F16_F32), getPointerTy(DAG.getDataLayout()));
+ CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
+ CallingConv::C, EVT(MVT::f32).getTypeForEVT(*DAG.getContext()), Callee,
+ std::move(Args));
+ SDValue Res;
+ std::tie(Res,Chain) = LowerCallTo(CLI);
+ if (IsStrict)
+ Res = DAG.getMergeValues({Res, Chain}, DL);
+
+ return DAG.getNode(ISD::FP_EXTEND, DL, VT, Res);
+}
+
+SDValue SystemZTargetLowering::LowerFP_ROUND(SDValue Op,
+ SelectionDAG &DAG) const {
+ bool IsStrict = Op->isStrictFPOpcode();
+ SDValue In = Op.getOperand(IsStrict ? 1 : 0);
+ MVT VT = Op.getSimpleValueType();
+ MVT SVT = In.getSimpleValueType();
+ if (VT != MVT::f16)
+ return SDValue(); // XXX?
+
+ SDLoc DL(Op);
+ SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
+
+ if (SVT != MVT::f32) {
+ SDValue Rnd = DAG.getIntPtrConstant(0, DL, /*isTarget=*/true);
+ In = DAG.getNode(ISD::FP_ROUND, DL, MVT::f32, In, Rnd);
+ }
----------------
uweigand wrote:
The double rounding may yield an incorrect result. I think GCC just uses different libcalls for all source types. Another alternative might be to use the "round to prepare for shorter precision" mode for the first operation.
https://github.com/llvm/llvm-project/pull/109164
More information about the cfe-commits
mailing list