@@ -424,6 +424,7 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
424424 void SelectPostStoreLane (SDNode *N, unsigned NumVecs, unsigned Opc);
425425 void SelectPredicatedStore (SDNode *N, unsigned NumVecs, unsigned Scale,
426426 unsigned Opc_rr, unsigned Opc_ri);
427+ void SelectFCVT_FPTOINT_Half (SDNode *N, unsigned Opc);
427428 std::tuple<unsigned , SDValue, SDValue>
428429 findAddrModeSVELoadStore (SDNode *N, unsigned Opc_rr, unsigned Opc_ri,
429430 const SDValue &OldBase, const SDValue &OldOffset,
@@ -2536,6 +2537,25 @@ void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *N, unsigned NumVecs,
25362537 ReplaceNode (N, St);
25372538}
25382539
2540+ // Select f16 -> i16 conversions
2541+ // Since i16 is an illegal type, they need to return an i32 result
2542+ void AArch64DAGToDAGISel::SelectFCVT_FPTOINT_Half (SDNode *N, unsigned int Opc) {
2543+ SDLoc DL (N);
2544+ SDValue SrcVal = N->getOperand (0 );
2545+ SDNode *Cvt = CurDAG->getMachineNode (Opc, DL, MVT::f16 , SrcVal);
2546+ SDValue Sign = CurDAG->getTargetConstant (-1 , DL, MVT::i64 );
2547+ SDValue Hsub = CurDAG->getTargetConstant (AArch64::hsub, DL, MVT::i32 );
2548+ SDNode *SubregToReg = CurDAG->getMachineNode (
2549+ TargetOpcode::SUBREG_TO_REG, DL, MVT::v8f16, Sign, SDValue (Cvt, 0 ), Hsub);
2550+ SDValue Ssub = CurDAG->getTargetConstant (AArch64::ssub, DL, MVT::i32 );
2551+ SDNode *Extract =
2552+ CurDAG->getMachineNode (TargetOpcode::EXTRACT_SUBREG, DL, MVT::f32 ,
2553+ SDValue (SubregToReg, 0 ), Ssub);
2554+ SDNode *Result = CurDAG->getMachineNode (AArch64::FMOVSWr, DL, MVT::i32 ,
2555+ SDValue (Extract, 0 ));
2556+ ReplaceNode (N, Result);
2557+ }
2558+
25392559static bool isBitfieldExtractOpFromAnd (SelectionDAG *CurDAG, SDNode *N,
25402560 unsigned &Opc, SDValue &Opd0,
25412561 unsigned &LSB, unsigned &MSB,
@@ -7359,6 +7379,14 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
73597379 }
73607380 break ;
73617381 }
7382+ case AArch64ISD::FCVTZS_HALF: {
7383+ SelectFCVT_FPTOINT_Half (Node, AArch64::FCVTZSv1f16);
7384+ return ;
7385+ }
7386+ case AArch64ISD::FCVTZU_HALF: {
7387+ SelectFCVT_FPTOINT_Half (Node, AArch64::FCVTZUv1f16);
7388+ return ;
7389+ }
73627390 }
73637391
73647392 // Select the default instruction
0 commit comments