-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fuzz: Port correctness/cse fuzzer over to libfuzzer #7543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include "Halide.h" | ||
|
||
#include <fuzzer/FuzzedDataProvider.h> | ||
#include <time.h> | ||
|
||
using namespace Halide; | ||
using namespace Halide::Internal; | ||
using std::vector; | ||
|
||
Expr random_expr(FuzzedDataProvider &fdp, int depth, vector<Expr> &exprs) { | ||
if (depth <= 0) { | ||
return fdp.ConsumeIntegralInRange<int>(-5, 4); | ||
} | ||
|
||
if (!exprs.empty() && fdp.ConsumeBool()) { | ||
// Reuse an existing expression | ||
return exprs[fdp.ConsumeIntegralInRange<size_t>(0, exprs.size() - 1)]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks fine, explicitly references size()-1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or better yet, use PickValueInArray()? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PickValueInArray doesn't work on vectors... see implementation although this is probably annoying enough that I might just create a PR with the LLVM project. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, I see, got it. (Not sure if LLVM change is worth the hassle, I gather that libfuzzer is unmaintained at this point as there are now bigger and better fuzzing engines) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (But could always just make a local |
||
} | ||
|
||
Expr next; | ||
switch (fdp.ConsumeIntegralInRange<int>(0, 8)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks ok. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the idea is that a value of 8 is intended to hit the default case, we should add a comment to that effect There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah that's what it looks like, I was mostly just attempting to replicate the original logic but while I'm at it I can probably make this clearer too. |
||
case 0: | ||
next = Var("x"); | ||
break; | ||
case 1: | ||
next = Var("y"); | ||
break; | ||
case 2: | ||
next = Var("z"); | ||
break; | ||
case 3: | ||
// Any binary op is equally good | ||
next = random_expr(fdp, depth - 1, exprs); | ||
next += random_expr(fdp, depth - 1, exprs); | ||
break; | ||
case 4: { | ||
Expr a = random_expr(fdp, depth - 2, exprs); | ||
Expr b = random_expr(fdp, depth - 2, exprs); | ||
Expr c = random_expr(fdp, depth - 2, exprs); | ||
Expr d = random_expr(fdp, depth - 2, exprs); | ||
next = select(a > b, c, d); | ||
break; | ||
} | ||
case 5: { | ||
Expr a = random_expr(fdp, depth - 1, exprs); | ||
Expr b = random_expr(fdp, depth - 1, exprs); | ||
next = Let::make("x", a, b); | ||
break; | ||
} | ||
case 6: { | ||
Expr a = random_expr(fdp, depth - 1, exprs); | ||
Expr b = random_expr(fdp, depth - 1, exprs); | ||
next = Let::make("y", a, b); | ||
break; | ||
} | ||
case 7: { | ||
Expr a = random_expr(fdp, depth - 1, exprs); | ||
Expr b = random_expr(fdp, depth - 1, exprs); | ||
next = Let::make("z", a, b); | ||
break; | ||
} | ||
default: | ||
next = fdp.ConsumeIntegralInRange<int>(-5, 4); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks ok. |
||
} | ||
exprs.push_back(next); | ||
return next; | ||
} | ||
|
||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | ||
FuzzedDataProvider fdp(data, size); | ||
vector<Expr> exprs; | ||
Expr orig = random_expr(fdp, 5, exprs); | ||
|
||
Expr csed = common_subexpression_elimination(orig); | ||
|
||
Expr check = (orig == csed); | ||
check = Let::make("x", 1, check); | ||
check = Let::make("y", 2, check); | ||
check = Let::make("z", 3, check); | ||
Stmt check_stmt = uniquify_variable_names(Evaluate::make(check)); | ||
check = check_stmt.as<Evaluate>()->value; | ||
|
||
// Don't use can_prove, because it recursively calls cse, which just confuses matters. | ||
assert(is_const_one(simplify(check))); | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine #7546 origional
rng() % 10 - 5