@@ -138,6 +138,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
138138 setOperationAction (Op, MVT::f32 , Expand);
139139 }
140140
141+ if (Subtarget.hasStdExtF () && Subtarget.is64Bit ())
142+ setOperationAction (ISD::BITCAST, MVT::i32 , Custom);
143+
141144 if (Subtarget.hasStdExtD ()) {
142145 setOperationAction (ISD::FMINNUM, MVT::f64 , Legal);
143146 setOperationAction (ISD::FMAXNUM, MVT::f64 , Legal);
@@ -339,6 +342,17 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
339342 return lowerFRAMEADDR (Op, DAG);
340343 case ISD::RETURNADDR:
341344 return lowerRETURNADDR (Op, DAG);
345+ case ISD::BITCAST: {
346+ assert (Subtarget.is64Bit () && Subtarget.hasStdExtF () &&
347+ " Unexpected custom legalisation" );
348+ SDLoc DL (Op);
349+ SDValue Op0 = Op.getOperand (0 );
350+ if (Op.getValueType () != MVT::f32 || Op0.getValueType () != MVT::i32 )
351+ return SDValue ();
352+ SDValue NewOp0 = DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64 , Op0);
353+ SDValue FPConv = DAG.getNode (RISCVISD::FMV_W_X_RV64, DL, MVT::f32 , NewOp0);
354+ return FPConv;
355+ }
342356 }
343357}
344358
@@ -580,6 +594,18 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
580594 return ;
581595 Results.push_back (customLegalizeToWOp (N, DAG));
582596 break ;
597+ case ISD::BITCAST: {
598+ assert (N->getValueType (0 ) == MVT::i32 && Subtarget.is64Bit () &&
599+ Subtarget.hasStdExtF () && " Unexpected custom legalisation" );
600+ SDLoc DL (N);
601+ SDValue Op0 = N->getOperand (0 );
602+ if (Op0.getValueType () != MVT::f32 )
603+ return ;
604+ SDValue FPConv =
605+ DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64 , Op0);
606+ Results.push_back (DAG.getNode (ISD::TRUNCATE, DL, MVT::i32 , FPConv));
607+ break ;
608+ }
583609 }
584610}
585611
@@ -634,6 +660,38 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
634660 return SDValue ();
635661 break ;
636662 }
663+ case RISCVISD::FMV_X_ANYEXTW_RV64: {
664+ SDLoc DL (N);
665+ SDValue Op0 = N->getOperand (0 );
666+ // If the input to FMV_X_ANYEXTW_RV64 is just FMV_W_X_RV64 then the
667+ // conversion is unnecessary and can be replaced with an ANY_EXTEND
668+ // of the FMV_W_X_RV64 operand.
669+ if (Op0->getOpcode () == RISCVISD::FMV_W_X_RV64) {
670+ SDValue AExtOp =
671+ DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64 , Op0.getOperand (0 ));
672+ return DCI.CombineTo (N, AExtOp);
673+ }
674+
675+ // This is a target-specific version of a DAGCombine performed in
676+ // DAGCombiner::visitBITCAST. It performs the equivalent of:
677+ // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit)
678+ // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit))
679+ if (!(Op0.getOpcode () == ISD::FNEG || Op0.getOpcode () == ISD::FABS) ||
680+ !Op0.getNode ()->hasOneUse ())
681+ break ;
682+ SDValue NewFMV = DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64 ,
683+ Op0.getOperand (0 ));
684+ APInt SignBit = APInt::getSignMask (32 ).sext (64 );
685+ if (Op0.getOpcode () == ISD::FNEG) {
686+ return DCI.CombineTo (N,
687+ DAG.getNode (ISD::XOR, DL, MVT::i64 , NewFMV,
688+ DAG.getConstant (SignBit, DL, MVT::i64 )));
689+ }
690+ assert (Op0.getOpcode () == ISD::FABS);
691+ return DCI.CombineTo (N,
692+ DAG.getNode (ISD::AND, DL, MVT::i64 , NewFMV,
693+ DAG.getConstant (~SignBit, DL, MVT::i64 )));
694+ }
637695 }
638696
639697 return SDValue ();
@@ -875,7 +933,7 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
875933 assert (XLen == 32 || XLen == 64 );
876934 MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64 ;
877935 if (ValVT == MVT::f32 ) {
878- LocVT = MVT:: i32 ;
936+ LocVT = XLenVT ;
879937 LocInfo = CCValAssign::BCvt;
880938 }
881939
@@ -1048,6 +1106,10 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
10481106 case CCValAssign::Full:
10491107 break ;
10501108 case CCValAssign::BCvt:
1109+ if (VA.getLocVT () == MVT::i64 && VA.getValVT () == MVT::f32 ) {
1110+ Val = DAG.getNode (RISCVISD::FMV_W_X_RV64, DL, MVT::f32 , Val);
1111+ break ;
1112+ }
10511113 Val = DAG.getNode (ISD::BITCAST, DL, VA.getValVT (), Val);
10521114 break ;
10531115 }
@@ -1083,6 +1145,10 @@ static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val,
10831145 case CCValAssign::Full:
10841146 break ;
10851147 case CCValAssign::BCvt:
1148+ if (VA.getLocVT () == MVT::i64 && VA.getValVT () == MVT::f32 ) {
1149+ Val = DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64 , Val);
1150+ break ;
1151+ }
10861152 Val = DAG.getNode (ISD::BITCAST, DL, LocVT, Val);
10871153 break ;
10881154 }
@@ -1109,9 +1175,12 @@ static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
11091175 llvm_unreachable (" Unexpected CCValAssign::LocInfo" );
11101176 case CCValAssign::Full:
11111177 case CCValAssign::Indirect:
1178+ case CCValAssign::BCvt:
11121179 ExtType = ISD::NON_EXTLOAD;
11131180 break ;
11141181 }
1182+ if (ValVT == MVT::f32 )
1183+ LocVT = MVT::f32 ;
11151184 Val = DAG.getExtLoad (
11161185 ExtType, DL, LocVT, Chain, FIN,
11171186 MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FI), ValVT);
@@ -1760,6 +1829,10 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
17601829 return " RISCVISD::DIVUW" ;
17611830 case RISCVISD::REMUW:
17621831 return " RISCVISD::REMUW" ;
1832+ case RISCVISD::FMV_W_X_RV64:
1833+ return " RISCVISD::FMV_W_X_RV64" ;
1834+ case RISCVISD::FMV_X_ANYEXTW_RV64:
1835+ return " RISCVISD::FMV_X_ANYEXTW_RV64" ;
17631836 }
17641837 return nullptr ;
17651838}
0 commit comments