From 591eab88442690bb4f07a4683015d01e58f7f997 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 24 Apr 2007 21:16:55 +0000 Subject: [PATCH] Support for the special case of a vector with the canonical form: vector_shuffle v1, v2, <2, 6, 3, 7> I.e. vector_shuffle v, undef, <2, 2, 3, 3> MMX only has a shuffle for v4i16 vectors. It needs to use the unpackh for this type of operation. llvm-svn: 36403 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 32 +++++++++++++++++++++++-- llvm/lib/Target/X86/X86ISelLowering.h | 5 ++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e63545d88778..996ffe94ecc0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -379,6 +379,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i8, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); + setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); + setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); } if (Subtarget->hasSSE1()) { @@ -1776,7 +1778,7 @@ bool X86::isUNPCKL_v_undef_Mask(SDNode *N) { assert(N->getOpcode() == ISD::BUILD_VECTOR); unsigned NumElems = N->getNumOperands(); - if (NumElems != 4 && NumElems != 8 && NumElems != 16) + if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16) return false; for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) { @@ -1792,6 +1794,29 @@ bool X86::isUNPCKL_v_undef_Mask(SDNode *N) { return true; } +/// isUNPCKH_v_undef_Mask - Special case of isUNPCKHMask for canonical form +/// of vector_shuffle v, v, <2, 6, 3, 7>, i.e. vector_shuffle v, undef, +/// <2, 2, 3, 3> +bool X86::isUNPCKH_v_undef_Mask(SDNode *N) { + assert(N->getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N->getNumOperands(); + if (NumElems != 2 && NumElems != 4 && NumElems != 8 && NumElems != 16) + return false; + + for (unsigned i = 0, j = NumElems / 2; i != NumElems; i += 2, ++j) { + SDOperand BitI = N->getOperand(i); + SDOperand BitI1 = N->getOperand(i + 1); + + if (!isUndefOrEqual(BitI, j)) + return false; + if (!isUndefOrEqual(BitI1, j)) + return false; + } + + return true; +} + /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element. @@ -2432,7 +2457,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) { } } - // Let legalizer expand 2-wide build_vector's. + // Let legalizer expand 2-wide build_vectors. if (EVTBits == 64) return SDOperand(); @@ -2591,6 +2616,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { } if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) || + X86::isUNPCKH_v_undef_Mask(PermMask.Val) || X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) return Op; @@ -2619,6 +2645,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) { // Commute is back and try unpck* again. Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG); if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) || + X86::isUNPCKH_v_undef_Mask(PermMask.Val) || X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) return Op; @@ -4231,6 +4258,7 @@ X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { isPSHUFHW_PSHUFLWMask(Mask.Val) || X86::isUNPCKLMask(Mask.Val) || X86::isUNPCKL_v_undef_Mask(Mask.Val) || + X86::isUNPCKH_v_undef_Mask(Mask.Val) || X86::isUNPCKHMask(Mask.Val)); } diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 88064d37c6e6..87022faab42c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -231,6 +231,11 @@ namespace llvm { /// <0, 0, 1, 1> bool isUNPCKL_v_undef_Mask(SDNode *N); + /// isUNPCKH_v_undef_Mask - Special case of isUNPCKHMask for canonical form + /// of vector_shuffle v, v, <2, 6, 3, 7>, i.e. vector_shuffle v, undef, + /// <2, 2, 3, 3> + bool isUNPCKH_v_undef_Mask(SDNode *N); + /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element.