mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
[AArch64 NEON] Add more scenarios to use perm instructions when lowering shuffle_vector
This patch covered 2 more scenarios: 1. Two operands of shuffle_vector are the same, like %shuffle.i = shufflevector <8 x i8> %a, <8 x i8> %a, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> 2. One of operands is undef, like %shuffle.i = shufflevector <8 x i8> %a, <8 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> After this patch, perm instructions will have chance to be emitted instead of lots of INS. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199069 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b6e0946d40
commit
5c8b8e61df
@ -4242,7 +4242,7 @@ static bool isREVMask(ArrayRef<int> M, EVT VT, unsigned BlockSize) {
|
||||
|
||||
// isPermuteMask - Check whether the vector shuffle matches to UZP, ZIP and
|
||||
// TRN instruction.
|
||||
static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
static unsigned isPermuteMask(ArrayRef<int> M, EVT VT, bool isV2undef) {
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
if (NumElts < 4)
|
||||
return 0;
|
||||
@ -4251,7 +4251,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
|
||||
// Check UZP1
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != i * 2) {
|
||||
unsigned answer = i * 2;
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4262,7 +4265,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
// Check UZP2
|
||||
ismatch = true;
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != i * 2 + 1) {
|
||||
unsigned answer = i * 2 + 1;
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4273,7 +4279,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
// Check ZIP1
|
||||
ismatch = true;
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != i / 2 + NumElts * (i % 2)) {
|
||||
unsigned answer = i / 2 + NumElts * (i % 2);
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4284,7 +4293,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
// Check ZIP2
|
||||
ismatch = true;
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != (NumElts + i) / 2 + NumElts * (i % 2)) {
|
||||
unsigned answer = (NumElts + i) / 2 + NumElts * (i % 2);
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4295,7 +4307,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
// Check TRN1
|
||||
ismatch = true;
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != i + (NumElts - 1) * (i % 2)) {
|
||||
unsigned answer = i + (NumElts - 1) * (i % 2);
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4306,7 +4321,10 @@ static unsigned isPermuteMask(ArrayRef<int> M, EVT VT) {
|
||||
// Check TRN2
|
||||
ismatch = true;
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
if ((unsigned)M[i] != 1 + i + (NumElts - 1) * (i % 2)) {
|
||||
unsigned answer = 1 + i + (NumElts - 1) * (i % 2);
|
||||
if (isV2undef && answer >= NumElts)
|
||||
answer -= NumElts;
|
||||
if (M[i] != -1 && (unsigned)M[i] != answer) {
|
||||
ismatch = false;
|
||||
break;
|
||||
}
|
||||
@ -4343,9 +4361,18 @@ AArch64TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
|
||||
if (isREVMask(ShuffleMask, VT, 16))
|
||||
return DAG.getNode(AArch64ISD::NEON_REV16, dl, VT, V1);
|
||||
|
||||
unsigned ISDNo = isPermuteMask(ShuffleMask, VT);
|
||||
if (ISDNo)
|
||||
return DAG.getNode(ISDNo, dl, VT, V1, V2);
|
||||
unsigned ISDNo;
|
||||
if (V2.getOpcode() == ISD::UNDEF)
|
||||
ISDNo = isPermuteMask(ShuffleMask, VT, true);
|
||||
else
|
||||
ISDNo = isPermuteMask(ShuffleMask, VT, false);
|
||||
|
||||
if (ISDNo) {
|
||||
if (V2.getOpcode() == ISD::UNDEF)
|
||||
return DAG.getNode(ISDNo, dl, VT, V1, V1);
|
||||
else
|
||||
return DAG.getNode(ISDNo, dl, VT, V1, V2);
|
||||
}
|
||||
|
||||
// If the element of shuffle mask are all the same constant, we can
|
||||
// transform it into either NEON_VDUP or NEON_VDUPLANE
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user