r339832 - Implementation of nested loops in cxx_loop_proto

Emmett Neyman via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 15 16:05:48 PDT 2018


Author: emmettneyman
Date: Wed Aug 15 16:05:48 2018
New Revision: 339832

URL: http://llvm.org/viewvc/llvm-project?rev=339832&view=rev
Log:
Implementation of nested loops in cxx_loop_proto

Summary: Extended `cxx_loop_proto` to have neste for loops. Modified `loop_proto_to_llvm` and `loop_proto_to_cxx` to handle the new protos. All protos have a set of statements designated as "inner loop" statements and a set of statements designated as "outer loop" statements.

Reviewers: morehouse, kcc

Reviewed By: morehouse

Subscribers: cfe-commits, llvm-commits

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

Modified:
    cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto
    cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
    cfe/trunk/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp

Modified: cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto?rev=339832&r1=339831&r2=339832&view=diff
==============================================================================
--- cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto (original)
+++ cfe/trunk/tools/clang-fuzzer/cxx_loop_proto.proto Wed Aug 15 16:05:48 2018
@@ -9,10 +9,11 @@
 ///
 /// \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
-///  differs from the one defined in cxx_proto.proto by eliminating while
-///  loops and conditionals. The goal is that the C++ code generated will be
-///  more likely to stress the LLVM loop vectorizer.
+///  more easily find interesting inputs for fuzzing LLVM's vectorizer.
+///  This subset differs from the one defined in cxx_proto.proto by eliminating
+///  while loops and conditionals. The goal is that the C++ code generated will
+///  be more likely to stress the LLVM loop vectorizer. The code generated will
+///  contain either a single loop or two nested loops.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -74,7 +75,8 @@ message StatementSeq {
 }
 
 message LoopFunction {
-  required StatementSeq statements = 1;
+  optional StatementSeq inner_statements = 1;
+  required StatementSeq outer_statements = 2;
 }
 
 package clang_fuzzer;

Modified: cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp?rev=339832&r1=339831&r2=339832&view=diff
==============================================================================
--- cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp (original)
+++ cfe/trunk/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp Wed Aug 15 16:05:48 2018
@@ -8,10 +8,10 @@
 //===----------------------------------------------------------------------===//
 //
 // 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. The C++ code generated is meant to
-// stress the LLVM loop vectorizer.
+// proto_to_cxx.cpp by wrapping all the generated C++ code in either a single
+// for loop or two nested loops. Also outputs a different function signature
+// that includes a 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.
 //
@@ -28,6 +28,17 @@
 
 namespace clang_fuzzer {
 
+static bool inner_loop = false;
+class InnerLoop {
+  public:
+  InnerLoop() {
+    inner_loop = true;
+  }
+  ~InnerLoop() {
+    inner_loop = false;
+  }
+};
+
 // Forward decls.
 std::ostream &operator<<(std::ostream &os, const BinaryOp &x);
 std::ostream &operator<<(std::ostream &os, const StatementSeq &x);
@@ -37,13 +48,14 @@ std::ostream &operator<<(std::ostream &o
   return os << "(" << x.val() << ")";
 }
 std::ostream &operator<<(std::ostream &os, const VarRef &x) {
+  std::string which_loop = inner_loop ? "j" : "i";
   switch (x.arr()) {
     case VarRef::ARR_A:
-      return os << "a[i]";
+      return os << "a[" << which_loop << "]";
     case VarRef::ARR_B:
-      return os << "b[i]";
+      return os << "b[" << which_loop << "]";
     case VarRef::ARR_C:
-      return os << "c[i]";
+      return os << "c[" << which_loop << "]";
   }
 }
 std::ostream &operator<<(std::ostream &os, const Rvalue &x) {
@@ -108,10 +120,27 @@ std::ostream &operator<<(std::ostream &o
     os << st;
   return os;
 }
+void NestedLoopToString(std::ostream &os, const LoopFunction &x) {
+  os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n"
+     << "for (int i=0; i<s; i++){\n"
+     << "for (int j=0; j<s; j++){\n";
+  {
+    InnerLoop IL;
+    os << x.inner_statements() << "}\n";
+  }
+  os << x.outer_statements() << "}\n}\n";
+}
+void SingleLoopToString(std::ostream &os, const LoopFunction &x) {
+  os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n"
+     << "for (int i=0; i<s; i++){\n"
+     << x.outer_statements() << "}\n}\n";
+}
 std::ostream &operator<<(std::ostream &os, const LoopFunction &x) {
-  return os << "void foo(int *a, int *b, int *__restrict__ c, size_t s) {\n"
-            << "for (int i=0; i<s; i++){\n"
-            << x.statements() << "}\n}\n";
+  if (x.has_inner_statements())
+    NestedLoopToString(os, x);
+  else
+    SingleLoopToString(os, x);
+  return os;
 }
 
 // ---------------------------------

Modified: cfe/trunk/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp?rev=339832&r1=339831&r2=339832&view=diff
==============================================================================
--- cfe/trunk/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp (original)
+++ cfe/trunk/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp Wed Aug 15 16:05:48 2018
@@ -30,17 +30,30 @@ std::string BinopToString(std::ostream &
 std::string StateSeqToString(std::ostream &os, const StatementSeq &x);
 
 // Counter variable to generate new LLVM IR variable names and wrapper function
-std::string get_var() {
+static std::string get_var() {
   static int ctr = 0;
   return "%var" + std::to_string(ctr++);
 }
 
+static bool inner_loop = false;
+class InnerLoop {
+  public:
+  InnerLoop() {
+    inner_loop = true;
+  }
+  ~InnerLoop() {
+    inner_loop = false;
+  }
+};
+
+
 // Proto to LLVM.
 
 std::string ConstToString(const Const &x) {
   return std::to_string(x.val());
 }
 std::string VarRefToString(std::ostream &os, const VarRef &x) {
+  std::string which_loop = inner_loop ? "inner" : "outer";
   std::string arr;
   switch(x.arr()) {
   case VarRef::ARR_A:
@@ -54,7 +67,8 @@ std::string VarRefToString(std::ostream
     break;
   }
   std::string ptr_var = get_var();
-  os << ptr_var << " = getelementptr inbounds i32, i32* " << arr << ", i64 %ct\n";
+  os << ptr_var << " = getelementptr inbounds i32, i32* " << arr
+     << ", i64 %" << which_loop << "_ct\n";
   return ptr_var;
 }
 std::string RvalueToString(std::ostream &os, const Rvalue &x) {
@@ -122,25 +136,61 @@ std::ostream &operator<<(std::ostream &o
   }
   return os;
 }
+void NestedLoopToString(std::ostream &os, const LoopFunction &x) {
+  os << "target triple = \"x86_64-unknown-linux-gnu\"\n"
+     << "define void @foo(i32* %a, i32* %b, i32* noalias %c, i64 %s) {\n"
+     << "outer_loop_start:\n"
+     << "%cmp = icmp sgt i64 %s, 0\n"
+     << "br i1 %cmp, label %inner_loop_start, label %end\n"
+     << "outer_loop:\n"
+     << x.outer_statements()
+     << "%o_ct_new = add i64 %outer_ct, 1\n"
+     << "%jmp_outer = icmp eq i64 %o_ct_new, %s\n"
+     << "br i1 %jmp_outer, label %end, label %inner_loop_start\n"
+     << "inner_loop_start:\n"
+     << "%outer_ct = phi i64 [%o_ct_new, %outer_loop], [0, %outer_loop_start]\n"
+     << "br label %inner_loop\n"
+     << "inner_loop:\n"
+     << "%inner_ct = phi i64 [0, %inner_loop_start], [%i_ct_new, %inner_loop]\n";
+  {
+    InnerLoop IL;
+    os << x.inner_statements();
+  }
+  os << "%i_ct_new = add i64 %inner_ct, 1\n"
+     << "%jmp_inner = icmp eq i64 %i_ct_new, %s\n"
+     << "br i1 %jmp_inner, label %outer_loop, label %inner_loop, !llvm.loop !0\n"
+     << "end:\n"
+     << "ret void\n"
+     << "}\n"
+     << "!0 = distinct !{!0, !1, !2}\n"
+     << "!1 = !{!\"llvm.loop.vectorize.enable\", i1 true}\n"
+     << "!2 = !{!\"llvm.loop.vectorize.width\", i32 " << kArraySize << "}\n";
+}
+void SingleLoopToString(std::ostream &os, const LoopFunction &x) {
+  os << "target triple = \"x86_64-unknown-linux-gnu\"\n"
+     << "define void @foo(i32* %a, i32* %b, i32* noalias %c, i64 %s) {\n"
+     << "%cmp = icmp sgt i64 %s, 0\n"
+     << "br i1 %cmp, label %start, label %end\n"
+     << "start:\n"
+     << "br label %loop\n"
+     << "end:\n"
+     << "ret void\n"
+     << "loop:\n"
+     << "%outer_ct = phi i64 [ %ctnew, %loop ], [ 0, %start ]\n"
+     << x.outer_statements()
+     << "%ctnew = add i64 %outer_ct, 1\n"
+     << "%j = icmp eq i64 %ctnew, %s\n"
+     << "br i1 %j, label %end, label %loop, !llvm.loop !0\n}\n"
+     << "!0 = distinct !{!0, !1, !2}\n"
+     << "!1 = !{!\"llvm.loop.vectorize.enable\", i1 true}\n"
+     << "!2 = !{!\"llvm.loop.vectorize.width\", i32 " << kArraySize << "}\n";
+}
 std::ostream &operator<<(std::ostream &os, const LoopFunction &x) {
-  return os << "target triple = \"x86_64-unknown-linux-gnu\"\n"
-            << "define void @foo(i32* %a, i32* %b, i32* %c, i64 %s) {\n"
-            << "%1 = icmp sgt i64 %s, 0\n"
-            << "br i1 %1, label %start, label %end\n"
-            << "start:\n"
-            << "br label %loop\n"
-            << "end:\n"
-            << "ret void\n"
-            << "loop:\n"
-            << " %ct   = phi i64 [ %ctnew, %loop ], [ 0, %start ]\n"
-            << x.statements()
-            << "%ctnew = add i64 %ct, 1\n"
-            << "%j = icmp eq i64 %ctnew, %s\n"
-            << "br i1 %j, label %end, label %loop, !llvm.loop !0\n}\n"
-            << "!0 = distinct !{!0, !1, !2}\n"
-            << "!1 = !{!\"llvm.loop.vectorize.enable\", i1 true}\n"
-            << "!2 = !{!\"llvm.loop.vectorize.width\", i32 " << kArraySize
-            << "}\n";
+  if (x.has_inner_statements())
+    NestedLoopToString(os, x);
+  else
+    SingleLoopToString(os, x);
+  return os;
 }
 
 // ---------------------------------




More information about the cfe-commits mailing list