@@ -43,27 +43,32 @@ using namespace llvm;
4343STATISTIC (NumTailCalls, " Number of tail calls" );
4444
4545enum MaterializeFPImm {
46- NoMaterializeFPImm,
47- MaterializeFPImm1Ins,
48- MaterializeFPImm2Ins,
49- MaterializeFPImm3Ins,
50- MaterializeFPImm4Ins
46+ NoMaterializeFPImm = 0 ,
47+ MaterializeFPImm2Ins = 2 ,
48+ MaterializeFPImm3Ins = 3 ,
49+ MaterializeFPImm4Ins = 4 ,
50+ MaterializeFPImm5Ins = 5 ,
51+ MaterializeFPImm6Ins = 6
5152};
5253
5354static cl::opt<MaterializeFPImm> MaterializeFPImmInsNum (
5455 " loongarch-materialize-float-imm" , cl::Hidden,
55- cl::desc (" Maximum number of instructions used when materializing "
56- " floating-point immediates (default = 2)" ),
57- cl::init(MaterializeFPImm2Ins),
56+ cl::desc (" Maximum number of instructions used (including code sequence "
57+ " to generate the value and moving the value to FPR) when "
58+ " materializing floating-point immediates (default = 3)" ),
59+ cl::init(MaterializeFPImm3Ins),
5860 cl::values(clEnumValN(NoMaterializeFPImm, " 0" , " Use constant pool" ),
59- clEnumValN(MaterializeFPImm1Ins, " 1" ,
60- " Materialize FP immediate within 1 instruction" ),
6161 clEnumValN(MaterializeFPImm2Ins, " 2" ,
6262 " Materialize FP immediate within 2 instructions" ),
6363 clEnumValN(MaterializeFPImm3Ins, " 3" ,
6464 " Materialize FP immediate within 3 instructions" ),
6565 clEnumValN(MaterializeFPImm4Ins, " 4" ,
66- " Materialize FP immediate within 4 instructions" )));
66+ " Materialize FP immediate within 4 instructions" ),
67+ clEnumValN(MaterializeFPImm5Ins, " 5" ,
68+ " Materialize FP immediate within 5 instructions" ),
69+ clEnumValN(MaterializeFPImm6Ins, " 6" ,
70+ " Materialize FP immediate within 6 instructions "
71+ " (behaves same as 5 on loongarch64)" )));
6772
6873static cl::opt<bool > ZeroDivCheck (" loongarch-check-zero-division" , cl::Hidden,
6974 cl::desc (" Trap on integer division by zero." ),
@@ -601,6 +606,15 @@ SDValue LoongArchTargetLowering::lowerConstantFP(SDValue Op,
601606
602607 // Construct as integer, and move to float register.
603608 APInt INTVal = FPVal.bitcastToAPInt ();
609+
610+ // If more than MaterializeFPImmInsNum instructions will be used to
611+ // generate the INTVal and move it to float register, fallback to
612+ // use floating point load from the constant pool.
613+ auto Seq = LoongArchMatInt::generateInstSeq (INTVal.getSExtValue ());
614+ int InsNum = Seq.size () + ((VT == MVT::f64 && !Subtarget.is64Bit ()) ? 2 : 1 );
615+ if (InsNum > MaterializeFPImmInsNum && !FPVal.isExactlyValue (+1.0 ))
616+ return SDValue ();
617+
604618 switch (VT.getSimpleVT ().SimpleTy ) {
605619 default :
606620 llvm_unreachable (" Unexpected floating point type!" );
@@ -614,18 +628,10 @@ SDValue LoongArchTargetLowering::lowerConstantFP(SDValue Op,
614628 DL, VT, NewVal);
615629 }
616630 case MVT::f64 : {
617- // If more than MaterializeFPImmInsNum instructions will be used to
618- // generate the INTVal, fallback to use floating point load from the
619- // constant pool.
620- auto Seq = LoongArchMatInt::generateInstSeq (INTVal.getSExtValue ());
621- if (Seq.size () > MaterializeFPImmInsNum && !FPVal.isExactlyValue (+1.0 ))
622- return SDValue ();
623-
624631 if (Subtarget.is64Bit ()) {
625632 SDValue NewVal = DAG.getConstant (INTVal, DL, MVT::i64 );
626633 return DAG.getNode (LoongArchISD::MOVGR2FR_D, DL, VT, NewVal);
627634 }
628-
629635 SDValue Lo = DAG.getConstant (INTVal.trunc (32 ), DL, MVT::i32 );
630636 SDValue Hi = DAG.getConstant (INTVal.lshr (32 ).trunc (32 ), DL, MVT::i32 );
631637 return DAG.getNode (LoongArchISD::MOVGR2FR_D_LO_HI, DL, VT, Lo, Hi);
0 commit comments