From f24380e78ecc8a2db1b2116867d878b1e7c6f6ed Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 6 Apr 2006 22:28:36 +0000 Subject: [PATCH] Match vpku[hw]um(x,x). Convert vsldoi(x,x) to work the same way other (x,x) cases work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27467 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelLowering.cpp | 91 +++++++++++++------------- lib/Target/PowerPC/PPCISelLowering.h | 10 +-- lib/Target/PowerPC/PPCInstrAltivec.td | 39 +++++++---- 3 files changed, 74 insertions(+), 66 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index a7608657ef2..686f2fa0696 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -276,20 +276,36 @@ static bool isConstantOrUndef(SDOperand Op, unsigned Val) { /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a /// VPKUHUM instruction. -bool PPC::isVPKUHUMShuffleMask(SDNode *N) { - for (unsigned i = 0; i != 16; ++i) - if (!isConstantOrUndef(N->getOperand(i), i*2+1)) - return false; +bool PPC::isVPKUHUMShuffleMask(SDNode *N, bool isUnary) { + if (!isUnary) { + for (unsigned i = 0; i != 16; ++i) + if (!isConstantOrUndef(N->getOperand(i), i*2+1)) + return false; + } else { + for (unsigned i = 0; i != 8; ++i) + if (!isConstantOrUndef(N->getOperand(i), i*2+1) || + !isConstantOrUndef(N->getOperand(i+8), i*2+1)) + return false; + } return true; } /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a /// VPKUWUM instruction. -bool PPC::isVPKUWUMShuffleMask(SDNode *N) { - for (unsigned i = 0; i != 16; i += 2) - if (!isConstantOrUndef(N->getOperand(i ), i*2+2) || - !isConstantOrUndef(N->getOperand(i+1), i*2+3)) - return false; +bool PPC::isVPKUWUMShuffleMask(SDNode *N, bool isUnary) { + if (!isUnary) { + for (unsigned i = 0; i != 16; i += 2) + if (!isConstantOrUndef(N->getOperand(i ), i*2+2) || + !isConstantOrUndef(N->getOperand(i+1), i*2+3)) + return false; + } else { + for (unsigned i = 0; i != 8; i += 2) + if (!isConstantOrUndef(N->getOperand(i ), i*2+2) || + !isConstantOrUndef(N->getOperand(i+1), i*2+3) || + !isConstantOrUndef(N->getOperand(i+8), i*2+2) || + !isConstantOrUndef(N->getOperand(i+9), i*2+3)) + return false; + } return true; } @@ -332,7 +348,7 @@ bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize, bool isUnary) { /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift /// amount, otherwise return -1. -int PPC::isVSLDOIShuffleMask(SDNode *N) { +int PPC::isVSLDOIShuffleMask(SDNode *N, bool isUnary) { assert(N->getOpcode() == ISD::BUILD_VECTOR && N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); // Find the first non-undef value in the shuffle mask. @@ -348,37 +364,17 @@ int PPC::isVSLDOIShuffleMask(SDNode *N) { if (ShiftAmt < i) return -1; ShiftAmt -= i; - // Check the rest of the elements to see if they are consequtive. - for (++i; i != 16; ++i) - if (!isConstantOrUndef(N->getOperand(i), ShiftAmt+i)) - return -1; - - return ShiftAmt; -} - -/// isVSLDOIRotateShuffleMask - If this is a vsldoi rotate shuffle mask, -/// return the shift amount, otherwise return -1. Note that vlsdoi(x,x) will -/// result in the shuffle being changed to shuffle(x,undef, ...) with -/// transformed byte numbers. -int PPC::isVSLDOIRotateShuffleMask(SDNode *N) { - assert(N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!"); - // Find the first non-undef value in the shuffle mask. - unsigned i; - for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i) - /*search*/; - - if (i == 16) return -1; // all undef. - - // Otherwise, check to see if the rest of the elements are consequtively - // numbered from this value. - unsigned ShiftAmt = cast(N->getOperand(i))->getValue(); - if (ShiftAmt < i) return -1; - ShiftAmt -= i; - - // Check the rest of the elements to see if they are consequtive. - for (++i; i != 16; ++i) - if (!isConstantOrUndef(N->getOperand(i), (ShiftAmt+i) & 15)) - return -1; + if (!isUnary) { + // Check the rest of the elements to see if they are consequtive. + for (++i; i != 16; ++i) + if (!isConstantOrUndef(N->getOperand(i), ShiftAmt+i)) + return -1; + } else { + // Check the rest of the elements to see if they are consequtive. + for (++i; i != 16; ++i) + if (!isConstantOrUndef(N->getOperand(i), (ShiftAmt+i) & 15)) + return -1; + } return ShiftAmt; } @@ -872,7 +868,9 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { if (PPC::isSplatShuffleMask(PermMask.Val, 1) || PPC::isSplatShuffleMask(PermMask.Val, 2) || PPC::isSplatShuffleMask(PermMask.Val, 4) || - PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1 || + PPC::isVPKUWUMShuffleMask(PermMask.Val, true) || + PPC::isVPKUHUMShuffleMask(PermMask.Val, true) || + PPC::isVSLDOIShuffleMask(PermMask.Val, true) != -1 || PPC::isVMRGLShuffleMask(PermMask.Val, 1, true) || PPC::isVMRGLShuffleMask(PermMask.Val, 2, true) || PPC::isVMRGLShuffleMask(PermMask.Val, 4, true) || @@ -883,9 +881,12 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { } } - if (PPC::isVPKUWUMShuffleMask(PermMask.Val) || - PPC::isVPKUHUMShuffleMask(PermMask.Val) || - PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 || + // Altivec has a variety of "shuffle immediates" that take two vector inputs + // and produce a fixed permutation. If any of these match, do not lower to + // VPERM. + if (PPC::isVPKUWUMShuffleMask(PermMask.Val, false) || + PPC::isVPKUHUMShuffleMask(PermMask.Val, false) || + PPC::isVSLDOIShuffleMask(PermMask.Val, false) != -1 || PPC::isVMRGLShuffleMask(PermMask.Val, 1, false) || PPC::isVMRGLShuffleMask(PermMask.Val, 2, false) || PPC::isVMRGLShuffleMask(PermMask.Val, 4, false) || diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 559256b4d11..c6c91af7243 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -104,11 +104,11 @@ namespace llvm { namespace PPC { /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a /// VPKUHUM instruction. - bool isVPKUHUMShuffleMask(SDNode *N); + bool isVPKUHUMShuffleMask(SDNode *N, bool isUnary); /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a /// VPKUWUM instruction. - bool isVPKUWUMShuffleMask(SDNode *N); + bool isVPKUWUMShuffleMask(SDNode *N, bool isUnary); /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes). @@ -120,11 +120,7 @@ namespace llvm { /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift /// amount, otherwise return -1. - int isVSLDOIShuffleMask(SDNode *N); - - /// isVSLDOIRotateShuffleMask - If this is a vsldoi rotate shuffle mask, - /// return the shift amount, otherwise return -1. This matches vsldoi(x,x). - int isVSLDOIRotateShuffleMask(SDNode *N); + int isVSLDOIShuffleMask(SDNode *N, bool isUnary); /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element that is suitable for input to diff --git a/lib/Target/PowerPC/PPCInstrAltivec.td b/lib/Target/PowerPC/PPCInstrAltivec.td index 2120a02582f..d01908e5dd2 100644 --- a/lib/Target/PowerPC/PPCInstrAltivec.td +++ b/lib/Target/PowerPC/PPCInstrAltivec.td @@ -18,12 +18,20 @@ /// VPKUHUM_shuffle_mask/VPKUWUM_shuffle_mask - Return true if this is a valid /// shuffle mask for the VPKUHUM or VPKUWUM instructions. def VPKUHUM_shuffle_mask : PatLeaf<(build_vector), [{ - return PPC::isVPKUHUMShuffleMask(N); + return PPC::isVPKUHUMShuffleMask(N, false); }]>; def VPKUWUM_shuffle_mask : PatLeaf<(build_vector), [{ - return PPC::isVPKUWUMShuffleMask(N); + return PPC::isVPKUWUMShuffleMask(N, false); }]>; +def VPKUHUM_unary_shuffle_mask : PatLeaf<(build_vector), [{ + return PPC::isVPKUHUMShuffleMask(N, true); +}]>; +def VPKUWUM_unary_shuffle_mask : PatLeaf<(build_vector), [{ + return PPC::isVPKUWUMShuffleMask(N, true); +}]>; + + def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{ return PPC::isVMRGLShuffleMask(N, 1, false); }]>; @@ -64,20 +72,20 @@ def VMRGHW_unary_shuffle_mask : PatLeaf<(build_vector), [{ def VSLDOI_get_imm : SDNodeXForm; def VSLDOI_shuffle_mask : PatLeaf<(build_vector), [{ - return PPC::isVSLDOIShuffleMask(N) != -1; + return PPC::isVSLDOIShuffleMask(N, false) != -1; }], VSLDOI_get_imm>; -/// VSLDOI_rotate* - These are used to match vsldoi(X,X), which is turned into +/// VSLDOI_unary* - These are used to match vsldoi(X,X), which is turned into /// vector_shuffle(X,undef,mask) by the dag combiner. -def VSLDOI_rotate_get_imm : SDNodeXForm; -def VSLDOI_rotate_shuffle_mask : PatLeaf<(build_vector), [{ - return PPC::isVSLDOIRotateShuffleMask(N) != -1; -}], VSLDOI_rotate_get_imm>; +def VSLDOI_unary_shuffle_mask : PatLeaf<(build_vector), [{ + return PPC::isVSLDOIShuffleMask(N, true) != -1; +}], VSLDOI_unary_get_imm>; // VSPLT*_get_imm xform function: convert vector_shuffle mask to VSPLT* imm. @@ -581,9 +589,13 @@ def : Pat<(v4f32 (bitconvert (v4i32 VRRC:$src))), (v4f32 VRRC:$src)>; // Shuffles. -// Match vsldoi(x,x) -def:Pat<(vector_shuffle (v16i8 VRRC:$vA),undef, VSLDOI_rotate_shuffle_mask:$in), - (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_rotate_shuffle_mask:$in)>; +// Match vsldoi(x,x), vpkuwum(x,x), vpkuhum(x,x) +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VSLDOI_unary_shuffle_mask:$in), + (VSLDOI VRRC:$vA, VRRC:$vA, VSLDOI_unary_shuffle_mask:$in)>; +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUWUM_unary_shuffle_mask:$in), + (VPKUWUM VRRC:$vA, VRRC:$vA)>; +def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef,VPKUHUM_unary_shuffle_mask:$in), + (VPKUHUM VRRC:$vA, VRRC:$vA)>; // Match vmrg*(x,x) def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGLB_unary_shuffle_mask:$in), @@ -599,7 +611,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))>; -- 2.34.1