From: Emmett Neyman Date: Wed, 15 Aug 2018 23:05:48 +0000 (+0000) Subject: Implementation of nested loops in cxx_loop_proto X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=958ba22e482103494bc72bb460ef770284e5181f;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339832 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/clang-fuzzer/cxx_loop_proto.proto b/tools/clang-fuzzer/cxx_loop_proto.proto index f2b47ed43d..760904b579 100644 --- a/tools/clang-fuzzer/cxx_loop_proto.proto +++ b/tools/clang-fuzzer/cxx_loop_proto.proto @@ -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; diff --git a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp index 7d8f6650aa..698e0fed8b 100644 --- a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp +++ b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp @@ -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 &os, const Const &x) { 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 &os, const StatementSeq &x) { 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