Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.117 -> 1.118 X86ISelLowering.h updated: 1.35 -> 1.36 X86InstrSSE.td updated: 1.14 -> 1.15 --- Log message: - VECTOR_SHUFFLE of v4i32 / v4f32 with undef second vector always matches PSHUFD. We can make permutes entries which point to the undef pointing anything we want. - Change some names to appease Chris. --- Diffs of the changes: (+55 -45) X86ISelLowering.cpp | 52 +++++++++++++++++++++++++++------------------------- X86ISelLowering.h | 15 ++++++++------- X86InstrSSE.td | 33 ++++++++++++++++++++------------- 3 files changed, 55 insertions(+), 45 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.117 llvm/lib/Target/X86/X86ISelLowering.cpp:1.118 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.117 Tue Mar 21 22:18:34 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Mar 22 02:01:21 2006 @@ -1368,27 +1368,6 @@ (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())); } -/// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand -/// specifies a shuffle of elements that is suitable for input to PSHUFD. -bool X86::isPSHUFDMask(SDNode *N) { - assert(N->getOpcode() == ISD::BUILD_VECTOR); - - if (N->getNumOperands() != 4) - 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); - assert(isa<ConstantSDNode>(Elt) && "Invalid VECTOR_SHUFFLE mask!"); - for (unsigned i = 1, e = N->getNumOperands(); i != e; ++i) { - assert(isa<ConstantSDNode>(N->getOperand(i)) && - "Invalid VECTOR_SHUFFLE mask!"); - if (cast<ConstantSDNode>(N->getOperand(i))->getValue() >= 4) return false; - } - - return true; -} - /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. bool X86::isSplatMask(SDNode *N) { @@ -1412,9 +1391,10 @@ return cast<ConstantSDNode>(Elt)->getValue() < N->getNumOperands(); } -/// getShuffleImmediate - Return the appropriate immediate to shuffle -/// the specified isShuffleMask VECTOR_SHUFFLE mask. -unsigned X86::getShuffleImmediate(SDNode *N) { +/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* +/// instructions. +unsigned X86::getShuffleSHUFImmediate(SDNode *N) { unsigned NumOperands = N->getNumOperands(); unsigned Shift = (NumOperands == 4) ? 2 : 1; unsigned Mask = 0; @@ -1428,6 +1408,28 @@ return Mask; } +/// getShufflePSHUFDImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFD instruction. +unsigned X86::getShufflePSHUFDImmediate(SDNode *N) { + unsigned NumOperands = N->getNumOperands(); + unsigned Mask = 0; + + assert(NumOperands == 4 && "Expect v4f32 / v4i32 vector operand"); + + unsigned i = NumOperands - 1; + do { + uint64_t Val = cast<ConstantSDNode>(N->getOperand(i))->getValue(); + // Second vector operand must be undef. We can have it point to anything + // we want. + if (Val >= NumOperands) Val = 0; + Mask |= Val; + Mask <<= 2; + --i; + } while (i != 0); + + return Mask; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -2217,7 +2219,7 @@ return DAG.getNode(X86ISD::UNPCKLP, VT, V1, V1); // Leave the VECTOR_SHUFFLE alone. It matches SHUFP*. return SDOperand(); - } else if (VT == MVT::v4f32 && X86::isPSHUFDMask(PermMask.Val)) + } else if (VT == MVT::v4f32) // Leave the VECTOR_SHUFFLE alone. It matches PSHUFD. return SDOperand(); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.35 llvm/lib/Target/X86/X86ISelLowering.h:1.36 --- llvm/lib/Target/X86/X86ISelLowering.h:1.35 Tue Mar 21 20:53:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Mar 22 02:01:21 2006 @@ -179,17 +179,18 @@ /// Define some predicates that are used for node matching. namespace X86 { - /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand - /// specifies a shuffle of elements that is suitable for input to PSHUFD. - bool isPSHUFDMask(SDNode *N); - /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); - /// getShuffleImmediate - Return the appropriate immediate to shuffle - /// the specified isShuffleMask VECTOR_SHUFFLE mask. - unsigned getShuffleImmediate(SDNode *N); + /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle + /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* + /// instructions. + unsigned getShuffleSHUFImmediate(SDNode *N); + + /// getShufflePSHUFDImmediate - Return the appropriate immediate to shuffle + /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFD instruction. + unsigned getShufflePSHUFDImmediate(SDNode *N); } //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.14 llvm/lib/Target/X86/X86InstrSSE.td:1.15 --- llvm/lib/Target/X86/X86InstrSSE.td:1.14 Wed Mar 22 01:10:28 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Wed Mar 22 02:01:21 2006 @@ -41,19 +41,21 @@ def loadv4f32 : PatFrag<(ops node:$ptr), (v4f32 (load node:$ptr))>; def loadv2f64 : PatFrag<(ops node:$ptr), (v2f64 (load node:$ptr))>; -// SHUFFLE_get_imm xform function: convert vector_shuffle mask to PSHUF*, -// SHUF* etc. imm. -def SHUFFLE_get_imm : SDNodeXForm<build_vector, [{ - return getI8Imm(X86::getShuffleImmediate(N)); +// SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to PSHUF*, +// SHUFP* etc. imm. +def SHUFFLE_get_shuf_imm : SDNodeXForm<build_vector, [{ + return getI8Imm(X86::getShuffleSHUFImmediate(N)); }]>; -def SHUFFLE_splat_mask : PatLeaf<(build_vector), [{ +def SHUFFLE_get_pshufd_imm : SDNodeXForm<build_vector, [{ + return getI8Imm(X86::getShufflePSHUFDImmediate(N)); +}]>; + +def SHUFP_splat_mask : PatLeaf<(build_vector), [{ return X86::isSplatMask(N); -}], SHUFFLE_get_imm>; +}], SHUFFLE_get_shuf_imm>; -def PSHUFD_shuffle_mask : PatLeaf<(build_vector), [{ - return X86::isPSHUFDMask(N); -}], SHUFFLE_get_imm>; +def PSHUFD_shuffle_mask : PatLeaf<(build_vector), [{}], SHUFFLE_get_pshufd_imm>; //===----------------------------------------------------------------------===// // SSE scalar FP Instructions @@ -801,13 +803,18 @@ // Splat v4f32 / v4i32 -def : Pat<(vector_shuffle (v4f32 VR128:$src), (undef), SHUFFLE_splat_mask:$sm), - (v4f32 (SHUFPSrr VR128:$src, VR128:$src, SHUFFLE_splat_mask:$sm))>; -def : Pat<(vector_shuffle (v4i32 VR128:$src), (undef), SHUFFLE_splat_mask:$sm), - (v4i32 (SHUFPSrr VR128:$src, VR128:$src, SHUFFLE_splat_mask:$sm))>; +def : Pat<(vector_shuffle (v4f32 VR128:$src), (undef), SHUFP_splat_mask:$sm), + (v4f32 (SHUFPSrr VR128:$src, VR128:$src, SHUFP_splat_mask:$sm))>; +def : Pat<(vector_shuffle (v4i32 VR128:$src), (undef), SHUFP_splat_mask:$sm), + (v4i32 (SHUFPSrr VR128:$src, VR128:$src, SHUFP_splat_mask:$sm))>; // Splat v2f64 / v2i64 def : Pat<(X86unpcklp (v2f64 VR128:$src1), VR128:$src2), (v2f64 (UNPCKLPDrr VR128:$src1, VR128:$src2))>; def : Pat<(X86unpcklp (v2i64 VR128:$src1), VR128:$src2), (v2i64 (UNPCKLPDrr VR128:$src1, VR128:$src2))>; + +// Shuffle v4i32, undef +def : Pat<(vector_shuffle (v4i32 VR128:$src1), (undef), + PSHUFD_shuffle_mask:$src2), + (v4i32 (PSHUFDrr VR128:$src1, PSHUFD_shuffle_mask:$src2))>; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits