[libFuzzer] make sure that 2-byte arguments of switch() are handled properly
[oota-llvm.git] / utils / PerfectShuffle / PerfectShuffle.cpp
index 5a0c2babfcc913b93579fd78b2a203e9443c5cc5..f80d88563168f5219dfecd1627012e9d95dcaf66 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include <iostream>
-#include <vector>
 #include <cassert>
 #include <cstdlib>
+#include <iomanip>
+#include <iostream>
+#include <vector>
 struct Operator;
 
 // Masks are 4-nibble hex numbers.  Values 0-7 in any nibble means that it takes
@@ -104,9 +105,11 @@ struct Operator {
   unsigned short ShuffleMask;
   unsigned short OpNum;
   const char *Name;
-  
-  Operator(unsigned short shufflemask, const char *name, unsigned opnum)
-    : ShuffleMask(shufflemask), OpNum(opnum), Name(name) {
+  unsigned Cost;
+
+  Operator(unsigned short shufflemask, const char *name, unsigned opnum,
+           unsigned cost = 1)
+    : ShuffleMask(shufflemask), OpNum(opnum), Name(name), Cost(cost) {
     TheOperators.push_back(this);
   }
   ~Operator() {
@@ -119,7 +122,8 @@ struct Operator {
   }
 
   const char *getName() const { return Name; }
-  
+  unsigned getCost() const { return Cost; }
+
   unsigned short getTransformedMask(unsigned short LHSMask, unsigned RHSMask) {
     // Extract the elements from LHSMask and RHSMask, as appropriate.
     unsigned Result = 0;
@@ -215,10 +219,10 @@ static void EvaluateOps(unsigned short Elt, unsigned short Vals[],
 int main() {
   // Seed the table with accesses to the LHS and RHS.
   ShufTab[0x0123].Cost = 0;
-  ShufTab[0x0123].Op = 0;
+  ShufTab[0x0123].Op = nullptr;
   ShufTab[0x0123].Arg0 = 0x0123;
   ShufTab[0x4567].Cost = 0;
-  ShufTab[0x4567].Op = 0;
+  ShufTab[0x4567].Op = nullptr;
   ShufTab[0x4567].Arg0 = 0x4567;
 
   // Seed the first-level of shuffles, shuffles whose inputs are the input to
@@ -302,7 +306,7 @@ int main() {
         // Evaluate op(LHS,LHS)
         unsigned ResultMask = Op->getTransformedMask(LHS, LHS);
 
-        unsigned Cost = ShufTab[LHS].Cost + 1;
+        unsigned Cost = ShufTab[LHS].Cost + Op->getCost();
         if (Cost < ShufTab[ResultMask].Cost) {
           ShufTab[ResultMask].Cost = Cost;
           ShufTab[ResultMask].Op = Op;
@@ -340,7 +344,7 @@ int main() {
           EvaluateOps(LHS, Vals, NumVals);
           EvaluateOps(RHS, Vals, NumVals);
 
-          unsigned Cost = NumVals + 1;
+          unsigned Cost = NumVals + Op->getCost();
           if (Cost < ShufTab[ResultMask].Cost) {
             ShufTab[ResultMask].Cost = Cost;
             ShufTab[ResultMask].Op = Op;
@@ -397,7 +401,7 @@ int main() {
     // LHS, and 13 bits of RHS = 32 bits.
     unsigned Val = (CostSat << 30) | (OpNum << 26) | (LHS << 13) | RHS;
 
-    std::cout << "  " << Val << "U,\t// ";
+    std::cout << "  " << std::setw(10) << Val << "U, // ";
     PrintMask(i, std::cout);
     std::cout << ": Cost " << ShufTab[i].Cost;
     std::cout << " " << (ShufTab[i].Op ? ShufTab[i].Op->getName() : "copy");
@@ -441,8 +445,6 @@ int main() {
 }
 
 
-#define GENERATE_ALTIVEC
-
 #ifdef GENERATE_ALTIVEC
 
 ///===---------------------------------------------------------------------===//
@@ -495,3 +497,76 @@ vsldoi<2> the_vsldoi2("vsldoi8" , OP_VSLDOI8);
 vsldoi<3> the_vsldoi3("vsldoi12", OP_VSLDOI12);
 
 #endif
+
+#define GENERATE_NEON
+
+#ifdef GENERATE_NEON
+enum {
+  OP_COPY = 0,   // Copy, used for things like <u,u,u,3> to say it is <0,1,2,3>
+  OP_VREV,
+  OP_VDUP0,
+  OP_VDUP1,
+  OP_VDUP2,
+  OP_VDUP3,
+  OP_VEXT1,
+  OP_VEXT2,
+  OP_VEXT3,
+  OP_VUZPL, // VUZP, left result
+  OP_VUZPR, // VUZP, right result
+  OP_VZIPL, // VZIP, left result
+  OP_VZIPR, // VZIP, right result
+  OP_VTRNL, // VTRN, left result
+  OP_VTRNR  // VTRN, right result
+};
+
+struct vrev : public Operator {
+  vrev() : Operator(0x1032, "vrev", OP_VREV) {}
+} the_vrev;
+
+template<unsigned Elt>
+struct vdup : public Operator {
+  vdup(const char *N, unsigned Opc)
+    : Operator(MakeMask(Elt, Elt, Elt, Elt), N, Opc) {}
+};
+
+vdup<0> the_vdup0("vdup0", OP_VDUP0);
+vdup<1> the_vdup1("vdup1", OP_VDUP1);
+vdup<2> the_vdup2("vdup2", OP_VDUP2);
+vdup<3> the_vdup3("vdup3", OP_VDUP3);
+
+template<unsigned N>
+struct vext : public Operator {
+  vext(const char *Name, unsigned Opc)
+    : Operator(MakeMask(N&7, (N+1)&7, (N+2)&7, (N+3)&7), Name, Opc) {
+  }
+};
+
+vext<1> the_vext1("vext1", OP_VEXT1);
+vext<2> the_vext2("vext2", OP_VEXT2);
+vext<3> the_vext3("vext3", OP_VEXT3);
+
+struct vuzpl : public Operator {
+  vuzpl() : Operator(0x0246, "vuzpl", OP_VUZPL, 2) {}
+} the_vuzpl;
+
+struct vuzpr : public Operator {
+  vuzpr() : Operator(0x1357, "vuzpr", OP_VUZPR, 2) {}
+} the_vuzpr;
+
+struct vzipl : public Operator {
+  vzipl() : Operator(0x0415, "vzipl", OP_VZIPL, 2) {}
+} the_vzipl;
+
+struct vzipr : public Operator {
+  vzipr() : Operator(0x2637, "vzipr", OP_VZIPR, 2) {}
+} the_vzipr;
+
+struct vtrnl : public Operator {
+  vtrnl() : Operator(0x0426, "vtrnl", OP_VTRNL, 2) {}
+} the_vtrnl;
+
+struct vtrnr : public Operator {
+  vtrnr() : Operator(0x1537, "vtrnr", OP_VTRNR, 2) {}
+} the_vtrnr;
+
+#endif