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.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -102,7 +102,6 @@ MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override; - SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const; SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 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 @@ -52,7 +52,7 @@ setOperationAction(ISD::SRL_PARTS, GRLenVT, Custom); setOperationAction(ISD::FP_TO_SINT, GRLenVT, Custom); - setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom); + setOperationAction(ISD::GlobalAddress, GRLenVT, Custom); if (Subtarget.is64Bit()) { setOperationAction(ISD::SHL, MVT::i32, Custom); @@ -125,8 +125,6 @@ assert(Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() && "Unexpected custom legalisation"); return SDValue(); - case ISD::ConstantPool: - return lowerConstantPool(Op, DAG); case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); case ISD::BITCAST: @@ -186,28 +184,6 @@ return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Trunc); } -SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op, - SelectionDAG &DAG) const { - SDLoc DL(Op); - EVT Ty = Op.getValueType(); - ConstantPoolSDNode *N = cast(Op); - - // FIXME: Only support PC-relative addressing to access the symbol. - // Target flags will be added later. - if (!isPositionIndependent()) { - SDValue ConstantN = DAG.getTargetConstantPool( - N->getConstVal(), Ty, N->getAlign(), N->getOffset()); - SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, ConstantN), - 0); - SDValue Addr(DAG.getMachineNode(Subtarget.is64Bit() ? LoongArch::ADDI_D - : LoongArch::ADDI_W, - DL, Ty, AddrHi, ConstantN), - 0); - return Addr; - } - report_fatal_error("Unable to lower ConstantPool"); -} - SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); @@ -873,5 +849,6 @@ return false; if (VT == MVT::f64 && !Subtarget.hasBasicD()) return false; - return (Imm.isZero() || Imm.isExactlyValue(+1.0)); + + return true; } 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 } @@ -35,16 +35,21 @@ define double @f64_constant_pi() nounwind { ; LA32-LABEL: f64_constant_pi: ; LA32: # %bb.0: -; LA32-NEXT: pcalau12i $a0, .LCPI2_0 -; LA32-NEXT: addi.w $a0, $a0, .LCPI2_0 -; LA32-NEXT: fld.d $fa0, $a0, 0 +; LA32-NEXT: lu12i.w $a0, 262290 +; LA32-NEXT: ori $a0, $a0, 507 +; LA32-NEXT: lu12i.w $a1, 345154 +; LA32-NEXT: ori $a1, $a1, 3352 +; LA32-NEXT: movgr2fr.w $fa0, $a1 +; LA32-NEXT: movgr2frh.w $fa0, $a0 ; LA32-NEXT: jirl $zero, $ra, 0 ; ; LA64-LABEL: f64_constant_pi: ; LA64: # %bb.0: -; LA64-NEXT: pcalau12i $a0, .LCPI2_0 -; LA64-NEXT: addi.d $a0, $a0, .LCPI2_0 -; LA64-NEXT: fld.d $fa0, $a0, 0 +; LA64-NEXT: lu12i.w $a0, 345154 +; LA64-NEXT: ori $a0, $a0, 3352 +; LA64-NEXT: lu32i.d $a0, -450053 +; LA64-NEXT: lu52i.d $a0, $a0, 1024 +; LA64-NEXT: movgr2fr.d $fa0, $a0 ; LA64-NEXT: jirl $zero, $ra, 0 ret double 3.1415926535897931159979634685441851615905761718750 } @@ -52,18 +57,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 +76,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