From ae7e7cb3d3ec657b7e6dd94cf036cdc65c182f59 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 16 May 2013 21:17:15 +0000 Subject: [PATCH] [mips] Improve instruction selection for pattern (store (fp_to_sint $src), $ptr). Previously, three instructions were needed: trunc.w.s $f0, $f2 mfc1 $4, $f0 sw $4, 0($2) Now we need only two: trunc.w.s $f0, $f2 swc1 $f0, 0($2) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182053 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 30 ++++++++++++- lib/Target/Mips/MipsISelLowering.h | 4 ++ lib/Target/Mips/MipsInstrFPU.td | 15 +++---- test/CodeGen/Mips/sint-fp-store_pattern.ll | 52 ++++++++++++++++++++++ 4 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/Mips/sint-fp-store_pattern.ll diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ed62da5ecb1..b344ddabc9c 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -156,6 +156,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::FPCmp: return "MipsISD::FPCmp"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; + case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI"; case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI"; case MipsISD::Mult: return "MipsISD::Mult"; @@ -249,6 +250,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); if (!TM.Options.NoNaNsFPMath) { setOperationAction(ISD::FABS, MVT::f32, Custom); @@ -264,6 +266,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SELECT, MVT::i64, Custom); setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); } if (!HasMips64) { @@ -743,6 +746,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::ADD: return lowerADD(Op, DAG); + case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); } return SDValue(); } @@ -2027,6 +2031,22 @@ static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7); } +// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). +static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG) { + SDValue Val = SD->getValue(); + + if (Val.getOpcode() != ISD::FP_TO_SINT) + return SDValue(); + + EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); + SDValue Tr = DAG.getNode(MipsISD::TruncIntFP, Val.getDebugLoc(), FPTy, + Val.getOperand(0)); + + return DAG.getStore(SD->getChain(), SD->getDebugLoc(), Tr, SD->getBasePtr(), + SD->getPointerInfo(), SD->isVolatile(), + SD->isNonTemporal(), SD->getAlignment()); +} + SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { StoreSDNode *SD = cast(Op); EVT MemVT = SD->getMemoryVT(); @@ -2036,7 +2056,7 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { ((MemVT == MVT::i32) || (MemVT == MVT::i64))) return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle()); - return SDValue(); + return lowerFP_TO_SINT_STORE(SD, DAG); } SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { @@ -2060,6 +2080,14 @@ SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { DAG.getConstant(0, ValTy)); } +SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, + SelectionDAG &DAG) const { + EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); + SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, Op.getDebugLoc(), FPTy, + Op.getOperand(0)); + return DAG.getNode(ISD::BITCAST, Op.getDebugLoc(), Op.getValueType(), Trunc); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 68f05ff80a2..ff645e27e27 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -60,6 +60,9 @@ namespace llvm { CMovFP_T, CMovFP_F, + // FP-to-int truncation node. + TruncIntFP, + // Return Ret, @@ -361,6 +364,7 @@ namespace llvm { SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerADD(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 6dc57e07092..e2acf284da3 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -30,6 +30,7 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, SDTCisVT<2, i32>]>; def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; +def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; @@ -42,6 +43,7 @@ def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain, SDNPOptInGlue]>; +def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>; def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>; def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", SDT_MipsExtractElementF64>; @@ -485,13 +487,12 @@ def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>; -def : MipsPat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S FGR32:$src))>; +def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_W_S FGR32:$src)>; let Predicates = [NotFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), (PseudoCVT_D32_W CPURegs:$src)>; - def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), - (MFC1 (TRUNC_W_D32 AFGR64:$src))>; + def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>; def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>; } @@ -507,11 +508,9 @@ let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)), (PseudoCVT_D64_L CPU64Regs:$src)>; - def : MipsPat<(i32 (fp_to_sint FGR64:$src)), - (MFC1 (TRUNC_W_D64 FGR64:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR32:$src)), (DMFC1 (TRUNC_L_S FGR32:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR64:$src)), - (DMFC1 (TRUNC_L_D64 FGR64:$src))>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>; + def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>; def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>; diff --git a/test/CodeGen/Mips/sint-fp-store_pattern.ll b/test/CodeGen/Mips/sint-fp-store_pattern.ll new file mode 100644 index 00000000000..23a8aeae91a --- /dev/null +++ b/test/CodeGen/Mips/sint-fp-store_pattern.ll @@ -0,0 +1,52 @@ +; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=32 +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=64 + +@gint_ = external global i32 +@gLL_ = external global i64 + +; 32: store_int_float_: +; 32: trunc.w.s $f[[R0:[0-9]+]], $f{{[0-9]+}} +; 32: swc1 $f[[R0]], + +define void @store_int_float_(float %a) { +entry: + %conv = fptosi float %a to i32 + store i32 %conv, i32* @gint_, align 4 + ret void +} + +; 32: store_int_double_: +; 32: trunc.w.d $f[[R0:[0-9]+]], $f{{[0-9]+}} +; 32: swc1 $f[[R0]], +; 64: store_int_double_: +; 64: trunc.w.d $f[[R0:[0-9]+]], $f{{[0-9]+}} +; 64: swc1 $f[[R0]], + +define void @store_int_double_(double %a) { +entry: + %conv = fptosi double %a to i32 + store i32 %conv, i32* @gint_, align 4 + ret void +} + +; 64: store_LL_float_: +; 64: trunc.l.s $f[[R0:[0-9]+]], $f{{[0-9]+}} +; 64: sdc1 $f[[R0]], + +define void @store_LL_float_(float %a) { +entry: + %conv = fptosi float %a to i64 + store i64 %conv, i64* @gLL_, align 8 + ret void +} + +; 64: store_LL_double_: +; 64: trunc.l.d $f[[R0:[0-9]+]], $f{{[0-9]+}} +; 64: sdc1 $f[[R0]], + +define void @store_LL_double_(double %a) { +entry: + %conv = fptosi double %a to i64 + store i64 %conv, i64* @gLL_, align 8 + ret void +} -- 2.34.1