@@ -415,7 +415,7 @@ bool test_bounds(Expr test, const Interval &interval, Type t, const map<string,
415415 return true ;
416416}
417417
418- bool test_expression_bounds (FuzzingContext &fuzz, Expr test, int trials, int samples_per_trial) {
418+ bool test_expression_bounds (FuzzingContext &fuzz, Expr test, int trials, int samples_per_trial, bool minimize_failures = true ) {
419419 map<string, Expr> vars;
420420 for (int i = 0 ; i < fuzz_var_count; i++) {
421421 vars[fuzz_var (i)] = Expr ();
@@ -429,6 +429,7 @@ bool test_expression_bounds(FuzzingContext &fuzz, Expr test, int trials, int sam
429429 contains_risky_cast |= (op->type .is_int () &&
430430 op->type .bits () >= 32 &&
431431 !op->type .can_represent (op->value .type ()));
432+ self->visit_base (op);
432433 });
433434 if (contains_risky_cast) {
434435 return true ;
@@ -472,11 +473,26 @@ bool test_expression_bounds(FuzzingContext &fuzz, Expr test, int trials, int sam
472473 }
473474
474475 if (!test_bounds (test, interval, test.type (), vars)) {
475- std::cerr << " scope {\n " ;
476- for (auto v = vars.begin (); v != vars.end (); v++) {
477- std::cerr << " \t " << v->first << " : " << scope.get (v->first ) << " \n " ;
476+ // Try to minimize it to an incorrect sub-expression
477+ bool found_failure = false ;
478+ if (minimize_failures) {
479+ std::cerr << " Attempting to minimize failure...\n " ;
480+ mutate_with (test, [&](auto *self, const Expr &e) {
481+ self->mutate_base (e);
482+ if (!found_failure && !e.same_as (test)) {
483+ found_failure |= !test_expression_bounds (fuzz, e, trials * 10 , samples_per_trial * 10 , false );
484+ }
485+ return e;
486+ });
487+ }
488+
489+ if (!found_failure) {
490+ std::cerr << " scope {\n " ;
491+ for (auto v = vars.begin (); v != vars.end (); v++) {
492+ std::cerr << " \t " << v->first << " : " << scope.get (v->first ) << " \n " ;
493+ }
494+ std::cerr << " }\n " ;
478495 }
479- std::cerr << " }\n " ;
480496 return false ;
481497 }
482498 }
0 commit comments