[mips][msa] Added support for matching max, maxi, min, mini from normal IR (i.e. not intrinsics)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191291 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Sanders
2013-09-24 12:18:31 +00:00
parent 38a10ff063
commit 89d13c1b38
7 changed files with 1254 additions and 71 deletions

View File

@@ -673,17 +673,57 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
EVT Ty = N->getValueType(0);
if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
return SDValue();
if (Ty.is128BitVector() && Ty.isInteger()) {
// Try the following combines:
// (vselect (setcc $a, $b, SETLT), $b, $a)) -> (vsmax $a, $b)
// (vselect (setcc $a, $b, SETLE), $b, $a)) -> (vsmax $a, $b)
// (vselect (setcc $a, $b, SETLT), $a, $b)) -> (vsmin $a, $b)
// (vselect (setcc $a, $b, SETLE), $a, $b)) -> (vsmin $a, $b)
// (vselect (setcc $a, $b, SETULT), $b, $a)) -> (vumax $a, $b)
// (vselect (setcc $a, $b, SETULE), $b, $a)) -> (vumax $a, $b)
// (vselect (setcc $a, $b, SETULT), $a, $b)) -> (vumin $a, $b)
// (vselect (setcc $a, $b, SETULE), $a, $b)) -> (vumin $a, $b)
// SETGT/SETGE/SETUGT/SETUGE variants of these will show up initially but
// will be expanded to equivalent SETLT/SETLE/SETULT/SETULE versions by the
// legalizer.
SDValue Op0 = N->getOperand(0);
SDValue SetCC = N->getOperand(0);
if (Op0->getOpcode() != ISD::SETCC)
return SDValue();
if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
return SDValue();
ISD::CondCode CondCode = cast<CondCodeSDNode>(Op0->getOperand(2))->get();
bool Signed;
return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
N->getOperand(2), SetCC.getOperand(2));
if (CondCode == ISD::SETLT || CondCode == ISD::SETLE)
Signed = true;
else if (CondCode == ISD::SETULT || CondCode == ISD::SETULE)
Signed = false;
else
return SDValue();
SDValue Op1 = N->getOperand(1);
SDValue Op2 = N->getOperand(2);
SDValue Op0Op0 = Op0->getOperand(0);
SDValue Op0Op1 = Op0->getOperand(1);
if (Op1 == Op0Op0 && Op2 == Op0Op1)
return DAG.getNode(Signed ? MipsISD::VSMIN : MipsISD::VUMIN, SDLoc(N),
Ty, Op1, Op2);
else if (Op1 == Op0Op1 && Op2 == Op0Op0)
return DAG.getNode(Signed ? MipsISD::VSMAX : MipsISD::VUMAX, SDLoc(N),
Ty, Op1, Op2);
} else if ((Ty == MVT::v2i16) || (Ty == MVT::v4i8)) {
SDValue SetCC = N->getOperand(0);
if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
return SDValue();
return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
SetCC.getOperand(0), SetCC.getOperand(1),
N->getOperand(1), N->getOperand(2), SetCC.getOperand(2));
}
return SDValue();
}
static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
@@ -1288,6 +1328,50 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
case Intrinsic::mips_ldi_w:
case Intrinsic::mips_ldi_d:
return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
case Intrinsic::mips_max_s_b:
case Intrinsic::mips_max_s_h:
case Intrinsic::mips_max_s_w:
case Intrinsic::mips_max_s_d:
return lowerMSABinaryIntr(Op, DAG, MipsISD::VSMAX);
case Intrinsic::mips_max_u_b:
case Intrinsic::mips_max_u_h:
case Intrinsic::mips_max_u_w:
case Intrinsic::mips_max_u_d:
return lowerMSABinaryIntr(Op, DAG, MipsISD::VUMAX);
case Intrinsic::mips_maxi_s_b:
case Intrinsic::mips_maxi_s_h:
case Intrinsic::mips_maxi_s_w:
case Intrinsic::mips_maxi_s_d:
return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VSMAX,
lowerMSASplatImm(Op, 2, DAG));
case Intrinsic::mips_maxi_u_b:
case Intrinsic::mips_maxi_u_h:
case Intrinsic::mips_maxi_u_w:
case Intrinsic::mips_maxi_u_d:
return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VUMAX,
lowerMSASplatImm(Op, 2, DAG));
case Intrinsic::mips_min_s_b:
case Intrinsic::mips_min_s_h:
case Intrinsic::mips_min_s_w:
case Intrinsic::mips_min_s_d:
return lowerMSABinaryIntr(Op, DAG, MipsISD::VSMIN);
case Intrinsic::mips_min_u_b:
case Intrinsic::mips_min_u_h:
case Intrinsic::mips_min_u_w:
case Intrinsic::mips_min_u_d:
return lowerMSABinaryIntr(Op, DAG, MipsISD::VUMIN);
case Intrinsic::mips_mini_s_b:
case Intrinsic::mips_mini_s_h:
case Intrinsic::mips_mini_s_w:
case Intrinsic::mips_mini_s_d:
return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VSMIN,
lowerMSASplatImm(Op, 2, DAG));
case Intrinsic::mips_mini_u_b:
case Intrinsic::mips_mini_u_h:
case Intrinsic::mips_mini_u_w:
case Intrinsic::mips_mini_u_d:
return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VUMIN,
lowerMSASplatImm(Op, 2, DAG));
case Intrinsic::mips_mulv_b:
case Intrinsic::mips_mulv_h:
case Intrinsic::mips_mulv_w: