mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00: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) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182053 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@@ -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.
|
||||||
|
@@ -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)>;
|
||||||
|
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
|
||||||
|
}
|
Reference in New Issue
Block a user