From: Chris Lattner Date: Wed, 12 Apr 2006 17:37:20 +0000 (+0000) Subject: Rename get_VSPLI_elt -> get_VSPLTI_elt X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e87192a854ff0f2f1904dd9ea282eb36059bb5af;p=oota-llvm.git Rename get_VSPLI_elt -> get_VSPLTI_elt Canonicalize BUILD_VECTOR's that match VSPLTI's into a single type for each form, eliminating a bunch of Pat patterns in the .td file and allowing us to CSE stuff more aggressively. This implements PowerPC/buildvec_canonicalize.ll:VSPLTI git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27614 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 5a33d6ab7f6..80f9cc053bd 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -429,11 +429,11 @@ unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) { return cast(N->getOperand(0))->getValue() / EltSize; } -/// get_VSPLI_elt - If this is a build_vector of constants which can be formed +/// get_VSPLTI_elt - If this is a build_vector of constants which can be formed /// by using a vspltis[bhw] instruction of the specified element size, return /// the constant being splatted. The ByteSize field indicates the number of /// bytes of each element [124] -> [bhw]. -SDOperand PPC::get_VSPLI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { +SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { SDOperand OpVal(0, 0); // If ByteSize of the splat is bigger than the element size of the @@ -920,7 +920,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Load it out. return DAG.getLoad(Op.getValueType(), Store, FIdx, DAG.getSrcValue(NULL)); } - case ISD::BUILD_VECTOR: + case ISD::BUILD_VECTOR: { // If this is a case we can't handle, return null and let the default // expansion code take care of it. If we CAN select this case, return Op. @@ -937,13 +937,34 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return Op; } - if (PPC::get_VSPLI_elt(Op.Val, 1, DAG).Val || // vspltisb - PPC::get_VSPLI_elt(Op.Val, 2, DAG).Val || // vspltish - PPC::get_VSPLI_elt(Op.Val, 4, DAG).Val) // vspltisw + // Check to see if this is something we can use VSPLTI* to form. + MVT::ValueType CanonicalVT = MVT::Other; + SDNode *CST = 0; + + if ((CST = PPC::get_VSPLTI_elt(Op.Val, 4, DAG).Val)) // vspltisw + CanonicalVT = MVT::v4i32; + else if ((CST = PPC::get_VSPLTI_elt(Op.Val, 2, DAG).Val)) // vspltish + CanonicalVT = MVT::v8i16; + else if ((CST = PPC::get_VSPLTI_elt(Op.Val, 1, DAG).Val)) // vspltisb + CanonicalVT = MVT::v16i8; + + // If this matches one of the vsplti* patterns, force it to the canonical + // type for the pattern. + if (CST) { + if (Op.getValueType() != CanonicalVT) { + // Convert the splatted element to the right element type. + SDOperand Elt = DAG.getNode(ISD::TRUNCATE, + MVT::getVectorBaseType(CanonicalVT), + SDOperand(CST, 0)); + std::vector Ops(MVT::getVectorNumElements(CanonicalVT), Elt); + SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops); + Op = DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res); + } return Op; + } return SDOperand(); - + } case ISD::VECTOR_SHUFFLE: { SDOperand V1 = Op.getOperand(0); SDOperand V2 = Op.getOperand(1); diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 48f9e1aa428..e4304efe02a 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -131,11 +131,11 @@ namespace llvm { /// specified isSplatShuffleMask VECTOR_SHUFFLE mask. unsigned getVSPLTImmediate(SDNode *N, unsigned EltSize); - /// get_VSPLI_elt - If this is a build_vector of constants which can be + /// get_VSPLTI_elt - If this is a build_vector of constants which can be /// formed by using a vspltis[bhw] instruction of the specified element /// size, return the constant being splatted. The ByteSize field indicates /// the number of bytes of each element [124] -> [bhw]. - SDOperand get_VSPLI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); + SDOperand get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); } class PPCTargetLowering : public TargetLowering { diff --git a/lib/Target/PowerPC/PPCInstrAltivec.td b/lib/Target/PowerPC/PPCInstrAltivec.td index 39304c876f5..9fdf4ee1251 100644 --- a/lib/Target/PowerPC/PPCInstrAltivec.td +++ b/lib/Target/PowerPC/PPCInstrAltivec.td @@ -111,26 +111,26 @@ def VSPLTW_shuffle_mask : PatLeaf<(build_vector), [{ // VSPLTISB_get_imm xform function: convert build_vector to VSPLTISB imm. def VSPLTISB_get_imm : SDNodeXForm; def vecspltisb : PatLeaf<(build_vector), [{ - return PPC::get_VSPLI_elt(N, 1, *CurDAG).Val != 0; + return PPC::get_VSPLTI_elt(N, 1, *CurDAG).Val != 0; }], VSPLTISB_get_imm>; // VSPLTISH_get_imm xform function: convert build_vector to VSPLTISH imm. def VSPLTISH_get_imm : SDNodeXForm; def vecspltish : PatLeaf<(build_vector), [{ - return PPC::get_VSPLI_elt(N, 2, *CurDAG).Val != 0; + return PPC::get_VSPLTI_elt(N, 2, *CurDAG).Val != 0; }], VSPLTISH_get_imm>; // VSPLTISW_get_imm xform function: convert build_vector to VSPLTISW imm. def VSPLTISW_get_imm : SDNodeXForm; def vecspltisw : PatLeaf<(build_vector), [{ - return PPC::get_VSPLI_elt(N, 4, *CurDAG).Val != 0; + return PPC::get_VSPLTI_elt(N, 4, *CurDAG).Val != 0; }], VSPLTISW_get_imm>; //===----------------------------------------------------------------------===// @@ -439,13 +439,13 @@ def VSRW : VX1_Int< 644, "vsrw" , int_ppc_altivec_vsrw>; def VSPLTISB : VXForm_3<780, (ops VRRC:$vD, s5imm:$SIMM), "vspltisb $vD, $SIMM", VecPerm, - [(set VRRC:$vD, (v4f32 vecspltisb:$SIMM))]>; + [(set VRRC:$vD, (v16i8 vecspltisb:$SIMM))]>; def VSPLTISH : VXForm_3<844, (ops VRRC:$vD, s5imm:$SIMM), "vspltish $vD, $SIMM", VecPerm, - [(set VRRC:$vD, (v4f32 vecspltish:$SIMM))]>; + [(set VRRC:$vD, (v8i16 vecspltish:$SIMM))]>; def VSPLTISW : VXForm_3<908, (ops VRRC:$vD, s5imm:$SIMM), "vspltisw $vD, $SIMM", VecPerm, - [(set VRRC:$vD, (v4f32 vecspltisw:$SIMM))]>; + [(set VRRC:$vD, (v4i32 vecspltisw:$SIMM))]>; // Vector Pack. def VPKPX : VX1_Int<782, "vpkpx", int_ppc_altivec_vpkpx>; @@ -540,7 +540,7 @@ def : Pat<(int_ppc_altivec_dstst GPRC:$rA, GPRC:$rB, imm:$STRM), def : Pat<(int_ppc_altivec_dststt GPRC:$rA, GPRC:$rB, imm:$STRM), (DSTST 1, imm:$STRM, GPRC:$rA, GPRC:$rB)>; -// Undef/Zero. +// Undef. def : Pat<(v16i8 (undef)), (v16i8 (IMPLICIT_DEF_VRRC))>; def : Pat<(v8i16 (undef)), (v8i16 (IMPLICIT_DEF_VRRC))>; def : Pat<(v4i32 (undef)), (v4i32 (IMPLICIT_DEF_VRRC))>; @@ -602,19 +602,6 @@ def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHH_unary_shuffle_mask:$in), def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHW_unary_shuffle_mask:$in), (VMRGHW VRRC:$vA, VRRC:$vA)>; -// Immediate vector formation with vsplti*. -def : Pat<(v16i8 vecspltisb:$invec), (v16i8 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v16i8 vecspltish:$invec), (v16i8 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v16i8 vecspltisw:$invec), (v16i8 (VSPLTISW vecspltisw:$invec))>; - -def : Pat<(v8i16 vecspltisb:$invec), (v8i16 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v8i16 vecspltish:$invec), (v8i16 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v8i16 vecspltisw:$invec), (v8i16 (VSPLTISW vecspltisw:$invec))>; - -def : Pat<(v4i32 vecspltisb:$invec), (v4i32 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v4i32 vecspltish:$invec), (v4i32 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v4i32 vecspltisw:$invec), (v4i32 (VSPLTISW vecspltisw:$invec))>; - // Logical Operations def : Pat<(v16i8 (vnot VRRC:$vA)), (v16i8 (VNOR VRRC:$vA, VRRC:$vA))>; def : Pat<(v8i16 (vnot VRRC:$vA)), (v8i16 (VNOR VRRC:$vA, VRRC:$vA))>;