@@ -43,27 +43,32 @@ using namespace llvm;
43
43
STATISTIC (NumTailCalls, " Number of tail calls" );
44
44
45
45
enum 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
51
52
};
52
53
53
54
static cl::opt<MaterializeFPImm> MaterializeFPImmInsNum (
54
55
" 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),
58
60
cl::values(clEnumValN(NoMaterializeFPImm, " 0" , " Use constant pool" ),
59
- clEnumValN(MaterializeFPImm1Ins, " 1" ,
60
- " Materialize FP immediate within 1 instruction" ),
61
61
clEnumValN(MaterializeFPImm2Ins, " 2" ,
62
62
" Materialize FP immediate within 2 instructions" ),
63
63
clEnumValN(MaterializeFPImm3Ins, " 3" ,
64
64
" Materialize FP immediate within 3 instructions" ),
65
65
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)" )));
67
72
68
73
static cl::opt<bool > ZeroDivCheck (" loongarch-check-zero-division" , cl::Hidden,
69
74
cl::desc (" Trap on integer division by zero." ),
@@ -601,6 +606,15 @@ SDValue LoongArchTargetLowering::lowerConstantFP(SDValue Op,
601
606
602
607
// Construct as integer, and move to float register.
603
608
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
+
604
618
switch (VT.getSimpleVT ().SimpleTy ) {
605
619
default :
606
620
llvm_unreachable (" Unexpected floating point type!" );
@@ -614,18 +628,10 @@ SDValue LoongArchTargetLowering::lowerConstantFP(SDValue Op,
614
628
DL, VT, NewVal);
615
629
}
616
630
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
-
624
631
if (Subtarget.is64Bit ()) {
625
632
SDValue NewVal = DAG.getConstant (INTVal, DL, MVT::i64 );
626
633
return DAG.getNode (LoongArchISD::MOVGR2FR_D, DL, VT, NewVal);
627
634
}
628
-
629
635
SDValue Lo = DAG.getConstant (INTVal.trunc (32 ), DL, MVT::i32 );
630
636
SDValue Hi = DAG.getConstant (INTVal.lshr (32 ).trunc (32 ), DL, MVT::i32 );
631
637
return DAG.getNode (LoongArchISD::MOVGR2FR_D_LO_HI, DL, VT, Lo, Hi);
0 commit comments