Changes in directory llvm/lib/Target/PowerPC:
PPCISelLowering.cpp updated: 1.155 -> 1.156 --- Log message: Pull some code out into a helper function. Effeciently codegen even splats in the range [-32,30]. This allows us to codegen <30,30,30,30> as: vspltisw v0, 15 vadduwm v2, v0, v0 instead of as a cp load. --- Diffs of the changes: (+26 -16) PPCISelLowering.cpp | 42 ++++++++++++++++++++++++++---------------- 1 files changed, 26 insertions(+), 16 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.155 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.156 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.155 Mon Apr 17 00:28:54 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr 17 01:00:21 2006 @@ -1041,6 +1041,23 @@ return true; } +/// BuildSplatI - Build a canonical splati of Val with an element size of +/// SplatSize. Cast the result to VT. +static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT, + SelectionDAG &DAG) { + assert(Val >= -16 && Val <= 15 && "vsplti is out of range!"); + static const MVT::ValueType VTys[] = { // canonical VT to use for each size. + MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32 + }; + MVT::ValueType CanonicalVT = VTys[SplatSize-1]; + + // Build a canonical splat for this value. + SDOperand Elt = DAG.getConstant(Val, MVT::getVectorBaseType(CanonicalVT)); + std::vector<SDOperand> Ops(MVT::getVectorNumElements(CanonicalVT), Elt); + SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops); + return DAG.getNode(ISD::BIT_CONVERT, VT, Res); +} + // 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, and if it // selects to a single instruction, return Op. Otherwise, if we can codegen @@ -1079,23 +1096,16 @@ // If the sign extended value is in the range [-16,15], use VSPLTI[bhw]. int32_t SextVal= int32_t(SplatBits << (32-8*SplatSize)) >> (32-8*SplatSize); - if (SextVal >= -16 && SextVal <= 15) { - const MVT::ValueType VTys[] = { // canonical VT to use for each size. - MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32 - }; - MVT::ValueType CanonicalVT = VTys[SplatSize-1]; - - // If this is a non-canonical splat for this value, - if (Op.getValueType() != CanonicalVT || HasAnyUndefs) { - SDOperand Elt = DAG.getConstant(SplatBits, - MVT::getVectorBaseType(CanonicalVT)); - std::vector<SDOperand> 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; - } + if (SextVal >= -16 && SextVal <= 15) + return BuildSplatI(SextVal, SplatSize, Op.getValueType(), DAG); + // If this value is in the range [-32,30] and is even, use: + // tmp = VSPLTI[bhw], result = add tmp, tmp + if (SextVal >= -32 && SextVal <= 30 && (SextVal & 1) == 0) { + Op = BuildSplatI(SextVal >> 1, SplatSize, Op.getValueType(), DAG); + return DAG.getNode(ISD::ADD, Op.getValueType(), Op, Op); + } + // If this is 0x8000_0000 x 4, turn into vspltisw + vslw. If it is // 0x7FFF_FFFF x 4, turn it into not(0x8000_0000). These are important _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits