diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td @@ -202,8 +202,6 @@ /// Floating point constants def : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>; -def : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>; -def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>; // FP Conversion def : Pat<(loongarch_ftint FPR32:$src), (FTINTRZ_W_S FPR32:$src)>; diff --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td @@ -215,8 +215,6 @@ let Predicates = [HasBasicD, IsLA64] in { def : Pat<(f64 fpimm0), (MOVGR2FR_D R0)>; -def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FR_D R0))>; -def : Pat<(f64 fpimm1), (FFINT_D_L (MOVGR2FR_D (ADDI_D R0, 1)))>; // Convert int to FP def : Pat<(f64 (sint_to_fp (i64 (sexti32 (i64 GPR:$src))))), @@ -234,8 +232,6 @@ let Predicates = [HasBasicD, IsLA32] in { def : Pat<(f64 fpimm0), (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0)>; -def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0))>; -def : Pat<(f64 fpimm1), (FCVT_D_S (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1))))>; // Convert int to FP def : Pat<(f64 (sint_to_fp (i32 GPR:$src))), (FFINT_D_W (MOVGR2FR_W GPR:$src))>; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.h @@ -51,6 +51,8 @@ bool selectSExti32(SDValue N, SDValue &Val); bool selectZExti32(SDValue N, SDValue &Val); + SDNode *getImmediate(int64_t Imm, MVT VT, const SDLoc &DL); + // Include the pieces autogenerated from the target description. #include "LoongArchGenDAGISel.inc" }; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp @@ -20,6 +20,22 @@ #define DEBUG_TYPE "loongarch-isel" +SDNode *LoongArchDAGToDAGISel::getImmediate(int64_t Imm, MVT VT, + const SDLoc &DL) { + SDNode *Result = nullptr; + SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, VT); + for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { + SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, VT); + if (Inst.Opc == LoongArch::LU12I_W) + Result = CurDAG->getMachineNode(LoongArch::LU12I_W, DL, VT, SDImm); + else + Result = CurDAG->getMachineNode(Inst.Opc, DL, VT, SrcReg, SDImm); + SrcReg = SDValue(Result, 0); + } + + return Result; +} + void LoongArchDAGToDAGISel::Select(SDNode *Node) { // If we have a custom node, we have already selected. if (Node->isMachineOpcode()) { @@ -70,6 +86,58 @@ ReplaceNode(Node, CurDAG->getMachineNode(ADDIOp, DL, VT, TFI, Imm)); return; } + case ISD::ConstantFP: { + ConstantFPSDNode *CN = dyn_cast(Node); + int64_t Imm = CN->getValueAPF().bitcastToAPInt().getSExtValue(); + SDNode *Result = nullptr; + + // When the floating-point immediate is +0.0, use pattern for matching. + if (Imm == 0) + break; + + if (Node->getValueType(0) == MVT::f64) { + // Handle floating point immediates when is64Bit() is true. + if (Subtarget->is64Bit()) { + Result = getImmediate(Imm, MVT::i64, DL); + Result = CurDAG->getMachineNode(LoongArch::MOVGR2FR_D, DL, MVT::f64, + SDValue(Result, 0)); + ReplaceNode(Node, Result); + return; + } + + // Handle floating point immediates when is64Bit() is false. + int32_t ImmHi = Imm >> 32; + SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT); + if (CN->getValueAPF().bitcastToAPInt().getLoBits(32).isZero()) { + Result = CurDAG->getMachineNode(LoongArch::MOVGR2FR_W_64, DL, MVT::f64, + SrcReg); + Result = CurDAG->getMachineNode( + LoongArch::MOVGR2FRH_W, DL, MVT::f64, SDValue(Result, 0), + SDValue(getImmediate(ImmHi, MVT::i32, DL), 0)); + ReplaceNode(Node, Result); + return; + } + + int32_t ImmLo = + CN->getValueAPF().bitcastToAPInt().getLoBits(32).getSExtValue(); + Result = + CurDAG->getMachineNode(LoongArch::MOVGR2FR_W_64, DL, MVT::f64, + SDValue(getImmediate(ImmLo, MVT::i32, DL), 0)); + Result = CurDAG->getMachineNode( + LoongArch::MOVGR2FRH_W, DL, MVT::f64, SDValue(Result, 0), + SDValue(getImmediate(ImmHi, MVT::i32, DL), 0)); + ReplaceNode(Node, Result); + return; + } + + int32_t Imm32 = CN->getValueAPF().bitcastToAPInt().getSExtValue(); + Result = getImmediate(Imm32, GRLenVT, DL); + Result = CurDAG->getMachineNode(LoongArch::MOVGR2FR_W, DL, MVT::f32, + SDValue(Result, 0)); + ReplaceNode(Node, Result); + return; + } + // TODO: Add selection nodes needed later. } diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -18,6 +18,7 @@ #include "LoongArchSubtarget.h" #include "LoongArchTargetMachine.h" #include "MCTargetDesc/LoongArchMCTargetDesc.h" +#include "MCTargetDesc/LoongArchMatInt.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/ISDOpcodes.h" #include "llvm/Support/Debug.h" @@ -868,10 +869,13 @@ bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const { assert((VT == MVT::f32 || VT == MVT::f64) && "Unexpected VT"); - - if (VT == MVT::f32 && !Subtarget.hasBasicF()) - return false; - if (VT == MVT::f64 && !Subtarget.hasBasicD()) - return false; - return (Imm.isZero() || Imm.isExactlyValue(+1.0)); + if (VT == MVT::f32 && Subtarget.hasBasicF()) + return true; + // f64 imm is legal if the bitcasted integer can be materialized within 2 + // instructions. + if (VT == MVT::f64 && Subtarget.hasBasicD() && + LoongArchMatInt::generateInstSeq(Imm.bitcastToAPInt().getSExtValue()) + .size() < 3) + return true; + return false; } diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -166,8 +166,6 @@ // FP immediate patterns. def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; -def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; -def fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>; def CallSymbol: AsmOperandClass { let Name = "CallSymbol"; diff --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll --- a/llvm/test/CodeGen/LoongArch/double-imm.ll +++ b/llvm/test/CodeGen/LoongArch/double-imm.ll @@ -19,15 +19,15 @@ define double @f64_negative_zero() nounwind { ; LA32-LABEL: f64_negative_zero: ; LA32: # %bb.0: +; LA32-NEXT: lu12i.w $a0, -524288 ; LA32-NEXT: movgr2fr.w $fa0, $zero -; LA32-NEXT: movgr2frh.w $fa0, $zero -; LA32-NEXT: fneg.d $fa0, $fa0 +; LA32-NEXT: movgr2frh.w $fa0, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f64_negative_zero: ; LA64: # %bb.0: -; LA64-NEXT: movgr2fr.d $fa0, $zero -; LA64-NEXT: fneg.d $fa0, $fa0 +; LA64-NEXT: lu52i.d $a0, $zero, -2048 +; LA64-NEXT: movgr2fr.d $fa0, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 ret double -0.0 } @@ -52,18 +52,16 @@ define double @f64_add_fimm1(double %a) nounwind { ; LA32-LABEL: f64_add_fimm1: ; LA32: # %bb.0: -; LA32-NEXT: addi.w $a0, $zero, 1 -; LA32-NEXT: movgr2fr.w $fa1, $a0 -; LA32-NEXT: ffint.s.w $fa1, $fa1 -; LA32-NEXT: fcvt.d.s $fa1, $fa1 +; LA32-NEXT: lu12i.w $a0, 261888 +; LA32-NEXT: movgr2fr.w $fa1, $zero +; LA32-NEXT: movgr2frh.w $fa1, $a0 ; LA32-NEXT: fadd.d $fa0, $fa0, $fa1 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f64_add_fimm1: ; LA64: # %bb.0: -; LA64-NEXT: addi.d $a0, $zero, 1 +; LA64-NEXT: lu52i.d $a0, $zero, 1023 ; LA64-NEXT: movgr2fr.d $fa1, $a0 -; LA64-NEXT: ffint.d.l $fa1, $fa1 ; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = fadd double %a, 1.0 @@ -73,17 +71,79 @@ define double @f64_positive_fimm1() nounwind { ; LA32-LABEL: f64_positive_fimm1: ; LA32: # %bb.0: -; LA32-NEXT: addi.w $a0, $zero, 1 -; LA32-NEXT: movgr2fr.w $fa0, $a0 -; LA32-NEXT: ffint.s.w $fa0, $fa0 -; LA32-NEXT: fcvt.d.s $fa0, $fa0 +; LA32-NEXT: lu12i.w $a0, 261888 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f64_positive_fimm1: ; LA64: # %bb.0: -; LA64-NEXT: addi.d $a0, $zero, 1 +; LA64-NEXT: lu52i.d $a0, $zero, 1023 ; LA64-NEXT: movgr2fr.d $fa0, $a0 -; LA64-NEXT: ffint.d.l $fa0, $fa0 ; LA64-NEXT: jirl $zero, $ra, 0 ret double 1.0 } + +define double @f64_positive_fimm64() nounwind { +; LA32-LABEL: f64_positive_fimm64: +; LA32: # %bb.0: +; LA32-NEXT: lu12i.w $a0, 263424 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 +; LA32-NEXT: jirl $zero, $ra, 0 +; +; LA64-LABEL: f64_positive_fimm64: +; LA64: # %bb.0: +; LA64-NEXT: lu52i.d $a0, $zero, 1029 +; LA64-NEXT: movgr2fr.d $fa0, $a0 +; LA64-NEXT: jirl $zero, $ra, 0 + ret double 64.0 +} + +define double @f64_negative_fimm64() nounwind { +; LA32-LABEL: f64_negative_fimm64: +; LA32: # %bb.0: +; LA32-NEXT: lu12i.w $a0, -260864 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 +; LA32-NEXT: jirl $zero, $ra, 0 +; +; LA64-LABEL: f64_negative_fimm64: +; LA64: # %bb.0: +; LA64-NEXT: lu52i.d $a0, $zero, -1019 +; LA64-NEXT: movgr2fr.d $fa0, $a0 +; LA64-NEXT: jirl $zero, $ra, 0 + ret double -64.0 +} + +define double @f64_positive_fimm1024() nounwind { +; LA32-LABEL: f64_positive_fimm1024: +; LA32: # %bb.0: +; LA32-NEXT: lu12i.w $a0, 264448 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 +; LA32-NEXT: jirl $zero, $ra, 0 +; +; LA64-LABEL: f64_positive_fimm1024: +; LA64: # %bb.0: +; LA64-NEXT: lu52i.d $a0, $zero, 1033 +; LA64-NEXT: movgr2fr.d $fa0, $a0 +; LA64-NEXT: jirl $zero, $ra, 0 + ret double 1024.0 +} + +define double @f64_negative_fimm1024() nounwind { +; LA32-LABEL: f64_negative_fimm1024: +; LA32: # %bb.0: +; LA32-NEXT: lu12i.w $a0, -259840 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 +; LA32-NEXT: jirl $zero, $ra, 0 +; +; LA64-LABEL: f64_negative_fimm1024: +; LA64: # %bb.0: +; LA64-NEXT: lu52i.d $a0, $zero, -1015 +; LA64-NEXT: movgr2fr.d $fa0, $a0 +; LA64-NEXT: jirl $zero, $ra, 0 + ret double -1024.0 +} diff --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll --- a/llvm/test/CodeGen/LoongArch/float-imm.ll +++ b/llvm/test/CodeGen/LoongArch/float-imm.ll @@ -18,14 +18,14 @@ define float @f32_negative_zero() nounwind { ; LA32-LABEL: f32_negative_zero: ; LA32: # %bb.0: -; LA32-NEXT: movgr2fr.w $fa0, $zero -; LA32-NEXT: fneg.s $fa0, $fa0 +; LA32-NEXT: lu12i.w $a0, -524288 +; LA32-NEXT: movgr2fr.w $fa0, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f32_negative_zero: ; LA64: # %bb.0: -; LA64-NEXT: movgr2fr.w $fa0, $zero -; LA64-NEXT: fneg.s $fa0, $fa0 +; LA64-NEXT: lu12i.w $a0, -524288 +; LA64-NEXT: movgr2fr.w $fa0, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 ret float -0.0 } @@ -33,16 +33,16 @@ define float @f32_constant_pi() nounwind { ; LA32-LABEL: f32_constant_pi: ; LA32: # %bb.0: -; LA32-NEXT: pcalau12i $a0, .LCPI2_0 -; LA32-NEXT: addi.w $a0, $a0, .LCPI2_0 -; LA32-NEXT: fld.s $fa0, $a0, 0 +; LA32-NEXT: lu12i.w $a0, 263312 +; LA32-NEXT: ori $a0, $a0, 4059 +; LA32-NEXT: movgr2fr.w $fa0, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f32_constant_pi: ; LA64: # %bb.0: -; LA64-NEXT: pcalau12i $a0, .LCPI2_0 -; LA64-NEXT: addi.d $a0, $a0, .LCPI2_0 -; LA64-NEXT: fld.s $fa0, $a0, 0 +; LA64-NEXT: lu12i.w $a0, 263312 +; LA64-NEXT: ori $a0, $a0, 4059 +; LA64-NEXT: movgr2fr.w $fa0, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 ret float 3.14159274101257324218750 } @@ -50,17 +50,15 @@ define float @f32_add_fimm1(float %a) nounwind { ; LA32-LABEL: f32_add_fimm1: ; LA32: # %bb.0: -; LA32-NEXT: addi.w $a0, $zero, 1 +; LA32-NEXT: lu12i.w $a0, 260096 ; LA32-NEXT: movgr2fr.w $fa1, $a0 -; LA32-NEXT: ffint.s.w $fa1, $fa1 ; LA32-NEXT: fadd.s $fa0, $fa0, $fa1 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f32_add_fimm1: ; LA64: # %bb.0: -; LA64-NEXT: addi.w $a0, $zero, 1 +; LA64-NEXT: lu12i.w $a0, 260096 ; LA64-NEXT: movgr2fr.w $fa1, $a0 -; LA64-NEXT: ffint.s.w $fa1, $fa1 ; LA64-NEXT: fadd.s $fa0, $fa0, $fa1 ; LA64-NEXT: jirl $zero, $ra, 0 %1 = fadd float %a, 1.0 @@ -70,16 +68,14 @@ define float @f32_positive_fimm1() nounwind { ; LA32-LABEL: f32_positive_fimm1: ; LA32: # %bb.0: -; LA32-NEXT: addi.w $a0, $zero, 1 +; LA32-NEXT: lu12i.w $a0, 260096 ; LA32-NEXT: movgr2fr.w $fa0, $a0 -; LA32-NEXT: ffint.s.w $fa0, $fa0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f32_positive_fimm1: ; LA64: # %bb.0: -; LA64-NEXT: addi.w $a0, $zero, 1 +; LA64-NEXT: lu12i.w $a0, 260096 ; LA64-NEXT: movgr2fr.w $fa0, $a0 -; LA64-NEXT: ffint.s.w $fa0, $fa0 ; LA64-NEXT: jirl $zero, $ra, 0 ret float 1.0 } diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/double-convert.ll @@ -116,9 +116,9 @@ define i32 @convert_double_to_u32(double %a) nounwind { ; LA32-LABEL: convert_double_to_u32: ; LA32: # %bb.0: -; LA32-NEXT: pcalau12i $a0, .LCPI7_0 -; LA32-NEXT: addi.w $a0, $a0, .LCPI7_0 -; LA32-NEXT: fld.d $fa1, $a0, 0 +; LA32-NEXT: lu12i.w $a0, 269824 +; LA32-NEXT: movgr2fr.w $fa1, $zero +; LA32-NEXT: movgr2frh.w $fa1, $a0 ; LA32-NEXT: fsub.d $fa2, $fa0, $fa1 ; LA32-NEXT: ftintrz.w.d $fa2, $fa2 ; LA32-NEXT: movfr2gr.s $a0, $fa2 @@ -173,9 +173,8 @@ ; ; LA64-LABEL: convert_double_to_u64: ; LA64: # %bb.0: -; LA64-NEXT: pcalau12i $a0, .LCPI9_0 -; LA64-NEXT: addi.d $a0, $a0, .LCPI9_0 -; LA64-NEXT: fld.d $fa1, $a0, 0 +; LA64-NEXT: lu52i.d $a0, $zero, 1086 +; LA64-NEXT: movgr2fr.d $fa1, $a0 ; LA64-NEXT: fsub.d $fa2, $fa0, $fa1 ; LA64-NEXT: ftintrz.l.d $fa2, $fa2 ; LA64-NEXT: movfr2gr.d $a0, $fa2 @@ -234,11 +233,11 @@ ; LA32-NEXT: lu12i.w $a2, 275200 ; LA32-NEXT: st.w $a2, $a1, 0 ; LA32-NEXT: st.w $a0, $sp, 8 -; LA32-NEXT: pcalau12i $a0, .LCPI12_0 -; LA32-NEXT: addi.w $a0, $a0, .LCPI12_0 -; LA32-NEXT: fld.d $fa0, $a0, 0 +; LA32-NEXT: lu12i.w $a0, -249088 +; LA32-NEXT: movgr2fr.w $fa0, $zero +; LA32-NEXT: movgr2frh.w $fa0, $a0 ; LA32-NEXT: fld.d $fa1, $sp, 8 -; LA32-NEXT: fsub.d $fa0, $fa1, $fa0 +; LA32-NEXT: fadd.d $fa0, $fa1, $fa0 ; LA32-NEXT: addi.w $sp, $sp, 16 ; LA32-NEXT: jirl $zero, $ra, 0 ; @@ -246,10 +245,10 @@ ; LA64: # %bb.0: ; LA64-NEXT: lu52i.d $a1, $zero, 1107 ; LA64-NEXT: movgr2fr.d $fa0, $a1 -; LA64-NEXT: pcalau12i $a1, .LCPI12_0 -; LA64-NEXT: addi.d $a1, $a1, .LCPI12_0 -; LA64-NEXT: fld.d $fa1, $a1, 0 -; LA64-NEXT: fsub.d $fa0, $fa0, $fa1 +; LA64-NEXT: lu12i.w $a1, 256 +; LA64-NEXT: lu52i.d $a1, $a1, -941 +; LA64-NEXT: movgr2fr.d $fa1, $a1 +; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 ; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 ; LA64-NEXT: lu52i.d $a1, $zero, 1075 ; LA64-NEXT: or $a0, $a0, $a1 @@ -276,10 +275,10 @@ ; LA64-NEXT: lu52i.d $a2, $zero, 1107 ; LA64-NEXT: or $a1, $a1, $a2 ; LA64-NEXT: movgr2fr.d $fa0, $a1 -; LA64-NEXT: pcalau12i $a1, .LCPI13_0 -; LA64-NEXT: addi.d $a1, $a1, .LCPI13_0 -; LA64-NEXT: fld.d $fa1, $a1, 0 -; LA64-NEXT: fsub.d $fa0, $fa0, $fa1 +; LA64-NEXT: lu12i.w $a1, 256 +; LA64-NEXT: lu52i.d $a1, $a1, -941 +; LA64-NEXT: movgr2fr.d $fa1, $a1 +; LA64-NEXT: fadd.d $fa0, $fa0, $fa1 ; LA64-NEXT: bstrpick.d $a0, $a0, 31, 0 ; LA64-NEXT: lu52i.d $a1, $zero, 1075 ; LA64-NEXT: or $a0, $a0, $a1 diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll --- a/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/float-convert.ll @@ -181,9 +181,8 @@ define i32 @convert_float_to_u32(float %a) nounwind { ; LA32F-LABEL: convert_float_to_u32: ; LA32F: # %bb.0: -; LA32F-NEXT: pcalau12i $a0, .LCPI6_0 -; LA32F-NEXT: addi.w $a0, $a0, .LCPI6_0 -; LA32F-NEXT: fld.s $fa1, $a0, 0 +; LA32F-NEXT: lu12i.w $a0, 323584 +; LA32F-NEXT: movgr2fr.w $fa1, $a0 ; LA32F-NEXT: fsub.s $fa2, $fa0, $fa1 ; LA32F-NEXT: ftintrz.w.s $fa2, $fa2 ; LA32F-NEXT: movfr2gr.s $a0, $fa2 @@ -200,9 +199,8 @@ ; ; LA32D-LABEL: convert_float_to_u32: ; LA32D: # %bb.0: -; LA32D-NEXT: pcalau12i $a0, .LCPI6_0 -; LA32D-NEXT: addi.w $a0, $a0, .LCPI6_0 -; LA32D-NEXT: fld.s $fa1, $a0, 0 +; LA32D-NEXT: lu12i.w $a0, 323584 +; LA32D-NEXT: movgr2fr.w $fa1, $a0 ; LA32D-NEXT: fsub.s $fa2, $fa0, $fa1 ; LA32D-NEXT: ftintrz.w.s $fa2, $fa2 ; LA32D-NEXT: movfr2gr.s $a0, $fa2 @@ -219,9 +217,8 @@ ; ; LA64F-LABEL: convert_float_to_u32: ; LA64F: # %bb.0: -; LA64F-NEXT: pcalau12i $a0, .LCPI6_0 -; LA64F-NEXT: addi.d $a0, $a0, .LCPI6_0 -; LA64F-NEXT: fld.s $fa1, $a0, 0 +; LA64F-NEXT: lu12i.w $a0, 323584 +; LA64F-NEXT: movgr2fr.w $fa1, $a0 ; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1 ; LA64F-NEXT: ftintrz.w.s $fa2, $fa2 ; LA64F-NEXT: movfr2gr.s $a0, $fa2 @@ -266,9 +263,8 @@ ; ; LA64F-LABEL: convert_float_to_u64: ; LA64F: # %bb.0: -; LA64F-NEXT: pcalau12i $a0, .LCPI7_0 -; LA64F-NEXT: addi.d $a0, $a0, .LCPI7_0 -; LA64F-NEXT: fld.s $fa1, $a0, 0 +; LA64F-NEXT: lu12i.w $a0, 389120 +; LA64F-NEXT: movgr2fr.w $fa1, $a0 ; LA64F-NEXT: fsub.s $fa2, $fa0, $fa1 ; LA64F-NEXT: ftintrz.w.s $fa2, $fa2 ; LA64F-NEXT: movfr2gr.s $a0, $fa2 @@ -285,9 +281,8 @@ ; ; LA64D-LABEL: convert_float_to_u64: ; LA64D: # %bb.0: -; LA64D-NEXT: pcalau12i $a0, .LCPI7_0 -; LA64D-NEXT: addi.d $a0, $a0, .LCPI7_0 -; LA64D-NEXT: fld.s $fa1, $a0, 0 +; LA64D-NEXT: lu12i.w $a0, 389120 +; LA64D-NEXT: movgr2fr.w $fa1, $a0 ; LA64D-NEXT: fsub.s $fa2, $fa0, $fa1 ; LA64D-NEXT: ftintrz.l.s $fa2, $fa2 ; LA64D-NEXT: movfr2gr.d $a0, $fa2 @@ -505,11 +500,11 @@ ; LA32D-NEXT: lu12i.w $a2, 275200 ; LA32D-NEXT: st.w $a2, $a1, 0 ; LA32D-NEXT: st.w $a0, $sp, 8 -; LA32D-NEXT: pcalau12i $a0, .LCPI14_0 -; LA32D-NEXT: addi.w $a0, $a0, .LCPI14_0 -; LA32D-NEXT: fld.d $fa0, $a0, 0 +; LA32D-NEXT: lu12i.w $a0, -249088 +; LA32D-NEXT: movgr2fr.w $fa0, $zero +; LA32D-NEXT: movgr2frh.w $fa0, $a0 ; LA32D-NEXT: fld.d $fa1, $sp, 8 -; LA32D-NEXT: fsub.d $fa0, $fa1, $fa0 +; LA32D-NEXT: fadd.d $fa0, $fa1, $fa0 ; LA32D-NEXT: fcvt.s.d $fa0, $fa0 ; LA32D-NEXT: addi.w $sp, $sp, 16 ; LA32D-NEXT: jirl $zero, $ra, 0