[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
This commit is contained in:
Akira Hatanaka
2013-05-16 21:17:15 +00:00
parent 6b67ffd68b
commit ae7e7cb3d3
4 changed files with 92 additions and 9 deletions

View File

@@ -156,6 +156,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::FPCmp: return "MipsISD::FPCmp"; case MipsISD::FPCmp: return "MipsISD::FPCmp";
case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T";
case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F";
case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP";
case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI"; case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI";
case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI"; case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI";
case MipsISD::Mult: return "MipsISD::Mult"; case MipsISD::Mult: return "MipsISD::Mult";
@@ -249,6 +250,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::VASTART, MVT::Other, Custom);
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
if (!TM.Options.NoNaNsFPMath) { if (!TM.Options.NoNaNsFPMath) {
setOperationAction(ISD::FABS, MVT::f32, Custom); setOperationAction(ISD::FABS, MVT::f32, Custom);
@@ -264,6 +266,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::SELECT, MVT::i64, Custom); setOperationAction(ISD::SELECT, MVT::i64, Custom);
setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::LOAD, MVT::i64, Custom);
setOperationAction(ISD::STORE, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
} }
if (!HasMips64) { if (!HasMips64) {
@@ -743,6 +746,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::LOAD: return lowerLOAD(Op, DAG);
case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG);
case ISD::ADD: return lowerADD(Op, DAG); case ISD::ADD: return lowerADD(Op, DAG);
case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);
} }
return SDValue(); return SDValue();
} }
@@ -2027,6 +2031,22 @@ static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG,
return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7); 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 { SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
StoreSDNode *SD = cast<StoreSDNode>(Op); StoreSDNode *SD = cast<StoreSDNode>(Op);
EVT MemVT = SD->getMemoryVT(); EVT MemVT = SD->getMemoryVT();
@@ -2036,7 +2056,7 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
((MemVT == MVT::i32) || (MemVT == MVT::i64))) ((MemVT == MVT::i32) || (MemVT == MVT::i64)))
return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle()); return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle());
return SDValue(); return lowerFP_TO_SINT_STORE(SD, DAG);
} }
SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const {
@@ -2060,6 +2080,14 @@ SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const {
DAG.getConstant(0, ValTy)); 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 // Calling Convention Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@@ -60,6 +60,9 @@ namespace llvm {
CMovFP_T, CMovFP_T,
CMovFP_F, CMovFP_F,
// FP-to-int truncation node.
TruncIntFP,
// Return // Return
Ret, Ret,
@@ -361,6 +364,7 @@ namespace llvm {
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerADD(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 /// isEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization. /// for tail call optimization.

View File

@@ -30,6 +30,7 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>,
SDTCisVT<2, i32>]>; SDTCisVT<2, i32>]>;
def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
SDTCisSameAs<1, 2>]>; SDTCisSameAs<1, 2>]>;
def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
SDTCisVT<1, i32>, SDTCisVT<1, i32>,
SDTCisSameAs<1, 2>]>; 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 MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
[SDNPHasChain, SDNPOptInGlue]>; [SDNPHasChain, SDNPOptInGlue]>;
def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>; def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>; SDT_MipsExtractElementF64>;
@@ -485,13 +487,12 @@ def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>;
def : MipsPat<(f32 fpimm0neg), (FNEG_S (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<(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 { let Predicates = [NotFP64bit, HasStdEnc] in {
def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), def : MipsPat<(f64 (sint_to_fp CPURegs:$src)),
(PseudoCVT_D32_W CPURegs:$src)>; (PseudoCVT_D32_W CPURegs:$src)>;
def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>;
(MFC1 (TRUNC_W_D32 AFGR64:$src))>;
def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_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)>; 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)), def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)),
(PseudoCVT_D64_L CPU64Regs:$src)>; (PseudoCVT_D64_L CPU64Regs:$src)>;
def : MipsPat<(i32 (fp_to_sint FGR64:$src)), def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>;
(MFC1 (TRUNC_W_D64 FGR64:$src))>; def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>;
def : MipsPat<(i64 (fp_to_sint FGR32:$src)), (DMFC1 (TRUNC_L_S FGR32:$src))>; def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>;
def : MipsPat<(i64 (fp_to_sint FGR64:$src)),
(DMFC1 (TRUNC_L_D64 FGR64:$src))>;
def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_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)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>;

View File

@@ -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
}