Recognize Neon VREV shuffles during legalization instead of selection.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78850 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 0d2d7d2..f348fe2 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -484,6 +484,9 @@
   case ARMISD::VST2D:         return "ARMISD::VST2D";
   case ARMISD::VST3D:         return "ARMISD::VST3D";
   case ARMISD::VST4D:         return "ARMISD::VST4D";
+  case ARMISD::VREV64:        return "ARMISD::VREV64";
+  case ARMISD::VREV32:        return "ARMISD::VREV32";
+  case ARMISD::VREV16:        return "ARMISD::VREV16";
   }
 }
 
@@ -2336,7 +2339,7 @@
 /// isVREVMask - Check if a vector shuffle corresponds to a VREV
 /// instruction with the specified blocksize.  (The order of the elements
 /// within each block of the vector is reversed.)
-bool ARM::isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) {
+static bool isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) {
   assert((BlockSize==16 || BlockSize==32 || BlockSize==64) &&
          "Only possible block sizes for VREV are: 16, 32, 64");
 
@@ -2432,6 +2435,18 @@
 }
 
 static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
+  ShuffleVectorSDNode *SVN = dyn_cast<ShuffleVectorSDNode>(Op.getNode());
+  assert(SVN != 0 && "Expected a ShuffleVectorSDNode in LowerVECTOR_SHUFFLE");
+  DebugLoc dl = Op.getDebugLoc();
+  EVT VT = Op.getValueType();
+
+  if (isVREVMask(SVN, 64))
+    return DAG.getNode(ARMISD::VREV64, dl, VT, SVN->getOperand(0));
+  if (isVREVMask(SVN, 32))
+    return DAG.getNode(ARMISD::VREV32, dl, VT, SVN->getOperand(0));
+  if (isVREVMask(SVN, 16))
+    return DAG.getNode(ARMISD::VREV16, dl, VT, SVN->getOperand(0));
+
   return Op;
 }