]> granicus.if.org Git - clang/commitdiff
[clang-fuzzer] Made loop_proto more "vectorizable".
authorMatt Morehouse <mascasa@google.com>
Fri, 8 Jun 2018 00:33:35 +0000 (00:33 +0000)
committerMatt Morehouse <mascasa@google.com>
Fri, 8 Jun 2018 00:33:35 +0000 (00:33 +0000)
Edited loop_proto and its converter to make more "vectorizable" code
according to kcc's comment in D47666
  - Removed all while loops
  - Can only index into array with induction variable

Patch By: emmettneyman

Differential Revision: https://reviews.llvm.org/D47920

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334252 91177308-0d34-0410-b5e6-96231b3b80d8

tools/clang-fuzzer/cxx_loop_proto.proto
tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp

index 5dae576940f90477adf450fa342fc167b360c18e..98b9bbf2a0bf85761e1fb25ecc1a1040b0c028fe 100644 (file)
 /// \file
 ///  This file describes a subset of C++ as a protobuf. It is used to
 ///  more easily find interesting inputs for fuzzing Clang. This subset
-///  extends the one defined in cxx_proto.proto by adding the option that
-///  a VarRef can use the for loop's counter variable.
+///  differs from the one defined in cxx_proto.proto by eliminating while
+///  loops and Lvalues. The goal is that the C++ code generated will be
+///  more likely to stress the LLVM loop vectorizer.
 ///
 //===----------------------------------------------------------------------===//
 
-
 syntax = "proto2";
 
-message VarRef {
-  required int32 varnum = 1;
-  required bool is_loop_var = 2;
-}
-
-message Lvalue {
-  required VarRef varref = 1;
-}
-
 message Const {
   required int32 val = 1;
 }
@@ -55,34 +46,25 @@ message BinaryOp {
 
 message Rvalue {
   oneof rvalue_oneof {
-    VarRef varref = 1;
-    Const cons = 2;
-    BinaryOp binop = 3;
+    Const cons = 1;
+    BinaryOp binop = 2;
   }
 }
 
 message AssignmentStatement {
-  required Lvalue lvalue = 1;
   required Rvalue rvalue = 2;
 }
 
-
 message IfElse {
   required Rvalue cond = 1;
   required StatementSeq if_body = 2;
   required StatementSeq else_body = 3;
 }
 
-message While {
-  required Rvalue cond = 1;
-  required StatementSeq body = 2;
-}
-
 message Statement {
   oneof stmt_oneof {
     AssignmentStatement assignment = 1;
     IfElse              ifelse     = 2;
-    While               while_loop = 3;
   }
 }
 
index a0007fb6f9e414169043aac3c55f2d6f507d010e..fa6ba307ace8cff4ab9983f49bdef58489ba3d4d 100644 (file)
@@ -7,10 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// Implements functions for converting between protobufs and C++. Extends
+// Implements functions for converting between protobufs and C++. Differs from
 // proto_to_cxx.cpp by wrapping all the generated C++ code in a single for
 // loop. Also coutputs a different function signature that includes a
-// size_t parameter for the loop to use.
+// size_t parameter for the loop to use. The C++ code generated is meant to
+// stress the LLVM loop vectorizer.
+//
+// Still a work in progress.
 //
 //===----------------------------------------------------------------------===//
 
@@ -33,19 +36,7 @@ std::ostream &operator<<(std::ostream &os, const StatementSeq &x);
 std::ostream &operator<<(std::ostream &os, const Const &x) {
   return os << "(" << x.val() << ")";
 }
-std::ostream &operator<<(std::ostream &os, const VarRef &x) {
-  if (x.is_loop_var()) {
-    return os << "a[loop_ctr]";
-  } else {
-    return os << "a[" << static_cast<uint32_t>(x.varnum()) << " % s]";
-  }
-}
-std::ostream &operator<<(std::ostream &os, const Lvalue &x) {
-  return os << x.varref();
-}
 std::ostream &operator<<(std::ostream &os, const Rvalue &x) {
-  if (x.has_varref())
-    return os << x.varref();
   if (x.has_cons())
     return os << x.cons();
   if (x.has_binop())
@@ -101,23 +92,18 @@ std::ostream &operator<<(std::ostream &os, const BinaryOp &x) {
   return os << x.right() << ")";
 }
 std::ostream &operator<<(std::ostream &os, const AssignmentStatement &x) {
-  return os << x.lvalue() << "=" << x.rvalue();
+  return os << "a[i]=" << x.rvalue();
 }
 std::ostream &operator<<(std::ostream &os, const IfElse &x) {
   return os << "if (" << x.cond() << "){\n"
             << x.if_body() << "} else { \n"
             << x.else_body() << "}\n";
 }
-std::ostream &operator<<(std::ostream &os, const While &x) {
-  return os << "while (" << x.cond() << "){\n" << x.body() << "}\n";
-}
 std::ostream &operator<<(std::ostream &os, const Statement &x) {
   if (x.has_assignment())
     return os << x.assignment() << ";\n";
   if (x.has_ifelse())
     return os << x.ifelse();
-  if (x.has_while_loop())
-    return os << x.while_loop();
   return os << "(void)0;\n";
 }
 std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {
@@ -127,7 +113,7 @@ std::ostream &operator<<(std::ostream &os, const StatementSeq &x) {
 }
 std::ostream &operator<<(std::ostream &os, const LoopFunction &x) {
   return os << "void foo(int *a, size_t s) {\n"
-            << "for (int loop_ctr = 0; loop_ctr < s; loop_ctr++){\n"
+            << "for (int i=0; i<s; i++){\n"
             << x.statements() << "}\n}\n";
 }
 
@@ -141,7 +127,7 @@ std::string LoopFunctionToString(const LoopFunction &input) {
 std::string LoopProtoToCxx(const uint8_t *data, size_t size) {
   LoopFunction message;
   if (!message.ParsePartialFromArray(data, size))
-    return "#error invalid proto, may not be binary encoded\n";
+    return "#error invalid proto\n";
   return LoopFunctionToString(message);
 }