@@ -190,6 +190,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
190190 setTruncStoreAction (MVT::f32 , MVT::bf16 , Expand);
191191 setCondCodeAction (FPCCToExpand, MVT::f32 , Expand);
192192
193+ setOperationAction (ISD::ConstantFP, MVT::f32 , Custom);
193194 setOperationAction (ISD::SELECT_CC, MVT::f32 , Expand);
194195 setOperationAction (ISD::BR_CC, MVT::f32 , Expand);
195196 setOperationAction (ISD::FMA, MVT::f32 , Legal);
@@ -237,6 +238,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
237238 setTruncStoreAction (MVT::f64 , MVT::f32 , Expand);
238239 setCondCodeAction (FPCCToExpand, MVT::f64 , Expand);
239240
241+ setOperationAction (ISD::ConstantFP, MVT::f64 , Custom);
240242 setOperationAction (ISD::SELECT_CC, MVT::f64 , Expand);
241243 setOperationAction (ISD::BR_CC, MVT::f64 , Expand);
242244 setOperationAction (ISD::STRICT_FSETCCS, MVT::f64 , Legal);
@@ -549,10 +551,58 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
549551 case ISD::VECREDUCE_UMAX:
550552 case ISD::VECREDUCE_UMIN:
551553 return lowerVECREDUCE (Op, DAG);
554+ case ISD::ConstantFP:
555+ return lowerConstantFP (Op, DAG);
552556 }
553557 return SDValue ();
554558}
555559
560+ SDValue LoongArchTargetLowering::lowerConstantFP (SDValue Op,
561+ SelectionDAG &DAG) const {
562+ EVT VT = Op.getValueType ();
563+ ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
564+ const APFloat &FPVal = CFP->getValueAPF ();
565+ SDLoc DL (CFP);
566+
567+ assert ((VT == MVT::f32 && Subtarget.hasBasicF ()) ||
568+ (VT == MVT::f64 && Subtarget.hasBasicD ()));
569+
570+ // If value is 0.0 or -0.0, just ignore it.
571+ if (FPVal.isZero ())
572+ return SDValue ();
573+
574+ // If lsx enabled, use cheaper 'vldi' instruction if possible.
575+ if (Subtarget.hasExtLSX () && isFPImmVLDILegal (FPVal, VT))
576+ return SDValue ();
577+
578+ // Construct as integer, and move to float register.
579+ APInt INTVal = FPVal.bitcastToAPInt ();
580+ switch (VT.getSimpleVT ().SimpleTy ) {
581+ default :
582+ llvm_unreachable (" Unexpected floating point type!" );
583+ break ;
584+ case MVT::f32 : {
585+ SDValue NewVal = DAG.getConstant (INTVal, DL, MVT::i32 );
586+ if (Subtarget.is64Bit ())
587+ NewVal = DAG.getNode (ISD::ZERO_EXTEND, DL, MVT::i64 , NewVal);
588+ return DAG.getNode (Subtarget.is64Bit () ? LoongArchISD::MOVGR2FR_W_LA64
589+ : LoongArchISD::MOVGR2FR_W,
590+ DL, VT, NewVal);
591+ }
592+ case MVT::f64 : {
593+ if (Subtarget.is64Bit ()) {
594+ SDValue NewVal = DAG.getConstant (INTVal, DL, MVT::i64 );
595+ return DAG.getNode (LoongArchISD::MOVGR2FR_D, DL, VT, NewVal);
596+ }
597+ SDValue Lo = DAG.getConstant (INTVal.trunc (32 ), DL, MVT::i32 );
598+ SDValue Hi = DAG.getConstant (INTVal.lshr (32 ).trunc (32 ), DL, MVT::i32 );
599+ return DAG.getNode (LoongArchISD::MOVGR2FR_D_LO_HI, DL, VT, Lo, Hi);
600+ }
601+ }
602+
603+ return SDValue ();
604+ }
605+
556606// Lower vecreduce_add using vhaddw instructions.
557607// For Example:
558608// call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
@@ -7041,7 +7091,10 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
70417091 NODE_NAME_CASE (SRL_W)
70427092 NODE_NAME_CASE (BSTRINS)
70437093 NODE_NAME_CASE (BSTRPICK)
7094+ NODE_NAME_CASE (MOVGR2FR_W)
70447095 NODE_NAME_CASE (MOVGR2FR_W_LA64)
7096+ NODE_NAME_CASE (MOVGR2FR_D)
7097+ NODE_NAME_CASE (MOVGR2FR_D_LO_HI)
70457098 NODE_NAME_CASE (MOVFR2GR_S_LA64)
70467099 NODE_NAME_CASE (FTINT)
70477100 NODE_NAME_CASE (BUILD_PAIR_F64)
0 commit comments