mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[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) llvm-svn: 182053
This commit is contained in:
parent
21effc7220
commit
3848727973
@ -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<StoreSDNode>(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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
|
@ -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)>;
|
||||
|
52
test/CodeGen/Mips/sint-fp-store_pattern.ll
Normal file
52
test/CodeGen/Mips/sint-fp-store_pattern.ll
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user