Changes in directory llvm/lib/Target/PowerPC:
PPCISelDAGToDAG.cpp updated: 1.169 -> 1.170 PPCISelLowering.cpp updated: 1.103 -> 1.104 PPCInstrInfo.td updated: 1.196 -> 1.197 --- Log message: Add support for generating vspltw, instead of a vperm instruction with a constant pool load. This generates significantly nicer code for splats. When tblgen gets bugfixed, we can remove the custom selection code. --- Diffs of the changes: (+41 -13) PPCISelDAGToDAG.cpp | 16 ++++++++++++++++ PPCISelLowering.cpp | 28 +++++++++++++++++++--------- PPCInstrInfo.td | 10 ++++++---- 3 files changed, 41 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.169 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.170 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.169 Thu Mar 16 19:40:33 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Mon Mar 20 00:51:10 2006 @@ -927,6 +927,22 @@ switch (N->getOpcode()) { default: break; + case ISD::VECTOR_SHUFFLE: + // FIXME: This should be autogenerated from the .td file, it is here for now + // due to bugs in tblgen. + if (Op.getOperand(1).getOpcode() == ISD::UNDEF && + (Op.getValueType() == MVT::v4f32 || Op.getValueType() == MVT::v4i32) && + PPC::isSplatShuffleMask(Op.getOperand(2).Val)) { + SDOperand N0; + Select(N0, N->getOperand(0)); + + Result = CodeGenMap[Op] = + SDOperand(CurDAG->getTargetNode(PPC::VSPLTW, MVT::v4f32, + getI32Imm(PPC::getVSPLTImmediate(Op.getOperand(2).Val)), + N0), 0); + return; + } + assert(0 && "ILLEGAL VECTOR_SHUFFLE!"); case ISD::SETCC: Result = SelectSETCC(Op); return; Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.103 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.104 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.103 Mon Mar 20 00:37:44 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Mon Mar 20 00:51:10 2006 @@ -245,6 +245,12 @@ /// VSPLTB/VSPLTH/VSPLTW. bool PPC::isSplatShuffleMask(SDNode *N) { assert(N->getOpcode() == ISD::BUILD_VECTOR); + + // We can only splat 8-bit, 16-bit, and 32-bit quantities. + if (N->getNumOperands() != 4 && N->getNumOperands() != 8 && + N->getNumOperands() != 16) + return false; + // This is a splat operation if each element of the permute is the same, and // if the value doesn't reference the second vector. SDOperand Elt = N->getOperand(0); @@ -263,11 +269,10 @@ /// specified isSplatShuffleMask VECTOR_SHUFFLE mask. unsigned PPC::getVSPLTImmediate(SDNode *N) { assert(isSplatShuffleMask(N)); - return cast<ConstantSDNode>(N)->getValue(); + return cast<ConstantSDNode>(N->getOperand(0))->getValue(); } - /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -602,17 +607,22 @@ DAG.getSrcValue(NULL)); } case ISD::VECTOR_SHUFFLE: { - // FIXME: Cases that are handled by instructions that take permute - // immediates (such as vsplt*) shouldn't be lowered here! Also handle cases - // that are cheaper to do as multiple such instructions than as a constant - // pool load/vperm pair. + SDOperand V1 = Op.getOperand(0); + SDOperand V2 = Op.getOperand(1); + SDOperand PermMask = Op.getOperand(2); + + // Cases that are handled by instructions that take permute immediates + // (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be + // selected by the instruction selector. + if (PPC::isSplatShuffleMask(PermMask.Val) && V2.getOpcode() == ISD::UNDEF) + break; + + // TODO: Handle more cases, and also handle cases that are cheaper to do as + // multiple such instructions than as a constant pool load/vperm pair. // Lower this to a VPERM(V1, V2, V3) expression, where V3 is a constant // vector that will get spilled to the constant pool. - SDOperand V1 = Op.getOperand(0); - SDOperand V2 = Op.getOperand(1); if (V2.getOpcode() == ISD::UNDEF) V2 = V1; - SDOperand PermMask = Op.getOperand(2); // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except // that it is in input element units, not in bytes. Convert now. Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.196 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.197 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.196 Mon Mar 20 00:15:45 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Mon Mar 20 00:51:10 2006 @@ -1032,10 +1032,12 @@ "vsplth $vD, $vB, $UIMM", VecPerm, []>; -//def VSPLTW : VXForm_1<652, (ops VRRC:$vD, u5imm:$UIMM, VRRC:$vB), -// "vspltw $vD, $vB, $UIMM", VecPerm, -// [(set VRRC:$vD, (vector_shuffle (v4f32 VRRC:$vB), (undef), -// VSPLT_shuffle_mask:$UIMM))]>; +def VSPLTW : VXForm_1<652, (ops VRRC:$vD, u5imm:$UIMM, VRRC:$vB), + "vspltw $vD, $vB, $UIMM", VecPerm, + [/* + (set VRRC:$vD, (vector_shuffle (v4f32 VRRC:$vB), (undef), + VSPLT_shuffle_mask:$UIMM))*/]>; + // FIXME: ALSO ADD SUPPORT FOR v4i32! // VX-Form Pseudo Instructions _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits