This revision was automatically updated to reflect the committed changes. Closed by commit rC339832: Implementation of nested loops in cxx_loop_proto (authored by emmettneyman, committed by ).
Changed prior to commit: https://reviews.llvm.org/D50670?vs=160936&id=160937#toc Repository: rC Clang https://reviews.llvm.org/D50670 Files: tools/clang-fuzzer/cxx_loop_proto.proto tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
Index: tools/clang-fuzzer/cxx_loop_proto.proto =================================================================== --- tools/clang-fuzzer/cxx_loop_proto.proto +++ 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 LoopFunction { - required StatementSeq statements = 1; + optional StatementSeq inner_statements = 1; + required StatementSeq outer_statements = 2; } package clang_fuzzer; Index: tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp =================================================================== --- tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp +++ tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp @@ -30,17 +30,30 @@ 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 @@ 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 @@ } 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; } // --------------------------------- Index: tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp =================================================================== --- tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp +++ 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 @@ 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 @@ 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; } // ---------------------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits