@@ -190,6 +190,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
190
190
setTruncStoreAction (MVT::f32 , MVT::bf16 , Expand);
191
191
setCondCodeAction (FPCCToExpand, MVT::f32 , Expand);
192
192
193
+ setOperationAction (ISD::ConstantFP, MVT::f32 , Custom);
193
194
setOperationAction (ISD::SELECT_CC, MVT::f32 , Expand);
194
195
setOperationAction (ISD::BR_CC, MVT::f32 , Expand);
195
196
setOperationAction (ISD::FMA, MVT::f32 , Legal);
@@ -237,6 +238,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
237
238
setTruncStoreAction (MVT::f64 , MVT::f32 , Expand);
238
239
setCondCodeAction (FPCCToExpand, MVT::f64 , Expand);
239
240
241
+ setOperationAction (ISD::ConstantFP, MVT::f64 , Custom);
240
242
setOperationAction (ISD::SELECT_CC, MVT::f64 , Expand);
241
243
setOperationAction (ISD::BR_CC, MVT::f64 , Expand);
242
244
setOperationAction (ISD::STRICT_FSETCCS, MVT::f64 , Legal);
@@ -549,10 +551,58 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
549
551
case ISD::VECREDUCE_UMAX:
550
552
case ISD::VECREDUCE_UMIN:
551
553
return lowerVECREDUCE (Op, DAG);
554
+ case ISD::ConstantFP:
555
+ return lowerConstantFP (Op, DAG);
552
556
}
553
557
return SDValue ();
554
558
}
555
559
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
+
556
606
// Lower vecreduce_add using vhaddw instructions.
557
607
// For Example:
558
608
// call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
@@ -7041,7 +7091,10 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
7041
7091
NODE_NAME_CASE (SRL_W)
7042
7092
NODE_NAME_CASE (BSTRINS)
7043
7093
NODE_NAME_CASE (BSTRPICK)
7094
+ NODE_NAME_CASE (MOVGR2FR_W)
7044
7095
NODE_NAME_CASE (MOVGR2FR_W_LA64)
7096
+ NODE_NAME_CASE (MOVGR2FR_D)
7097
+ NODE_NAME_CASE (MOVGR2FR_D_LO_HI)
7045
7098
NODE_NAME_CASE (MOVFR2GR_S_LA64)
7046
7099
NODE_NAME_CASE (FTINT)
7047
7100
NODE_NAME_CASE (BUILD_PAIR_F64)
0 commit comments