mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-26 22:26:16 +00:00
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
This commit is contained in:
parent
64fa7a7296
commit
f24380e78e
@ -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) {
|
||||
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) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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<ConstantSDNode>(N->getOperand(i))->getValue();
|
||||
if (ShiftAmt < i) return -1;
|
||||
ShiftAmt -= i;
|
||||
|
||||
} 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) ||
|
||||
|
@ -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
|
||||
|
@ -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<build_vector, [{
|
||||
return getI32Imm(PPC::isVSLDOIShuffleMask(N));
|
||||
return getI32Imm(PPC::isVSLDOIShuffleMask(N, false));
|
||||
}]>;
|
||||
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<build_vector, [{
|
||||
return getI32Imm(PPC::isVSLDOIRotateShuffleMask(N));
|
||||
def VSLDOI_unary_get_imm : SDNodeXForm<build_vector, [{
|
||||
return getI32Imm(PPC::isVSLDOIShuffleMask(N, true));
|
||||
}]>;
|
||||
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))>;
|
||||
|
Loading…
Reference in New Issue
Block a user