Skip to content

Commit

Permalink
tint IR fuzzer: add -dump option WGSL and shader output
Browse files Browse the repository at this point in the history
Also plumb through the fuzzer Options via a Context struct, as we do for
the AST fuzzer. Update all fuzzer functions to accept this Context arg.

This change also allows us to add the dxc path to Options and use that
to call DXC against generated HLSL in a follow-up CL.

Bug: 381442284
Bug: 380270956
Change-Id: Ifa2fc83f49aef92d0e481fa280874be8e11094e3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/218614
Reviewed-by: James Price <[email protected]>
Reviewed-by: Ryan Harrison <[email protected]>
Commit-Queue: Antonio Maiorano <[email protected]>
  • Loading branch information
amaiorano authored and Dawn LUCI CQ committed Dec 9, 2024
1 parent c394864 commit 644bf00
Show file tree
Hide file tree
Showing 36 changed files with 161 additions and 55 deletions.
23 changes: 16 additions & 7 deletions src/tint/cmd/fuzz/ir/fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ void Register(const IRFuzzer& fuzzer) {
if (auto val = core::ir::Validate(ir.Get()); val != Success) {
TINT_ICE() << val.Failure();
}
[[maybe_unused]] auto result = fn(ir.Get(), data);
// Copy relevant options from wgsl::Context to ir::Context
fuzz::ir::Context ir_context;
ir_context.options.filter = context.options.filter;
ir_context.options.run_concurrently = context.options.run_concurrently;
ir_context.options.verbose = context.options.verbose;
ir_context.options.dump = context.options.dump;
[[maybe_unused]] auto result = fn(ir.Get(), ir_context, data);
},
});
#endif
Expand All @@ -108,6 +114,9 @@ void Run(const std::function<tint::core::ir::Module()>& acquire_module,
// leading to non-determinism, which we must avoid.
TINT_STATIC_INIT(Fuzzers().Sort([](auto& a, auto& b) { return a.name < b.name; }));

Context context;
context.options = options;

bool ran_atleast_once = false;

// Run each of the program fuzzer functions
Expand All @@ -122,25 +131,25 @@ void Run(const std::function<tint::core::ir::Module()>& acquire_module,
}
ran_atleast_once = true;

threads.Push(std::thread([i, &acquire_module, &data, &options] {
threads.Push(std::thread([i, &acquire_module, &data, &context] {
auto& fuzzer = Fuzzers()[i];
currently_running = fuzzer.name;
if (options.verbose) {
if (context.options.verbose) {
std::cout << " • [" << i << "] Running: " << currently_running << '\n';
}
auto mod = acquire_module();
if (tint::core::ir::Validate(mod, fuzzer.pre_capabilities) != tint::Success) {
// Failing before running indicates that this input violates the pre-conditions
// for this pass, so should be skipped.
if (options.verbose) {
if (context.options.verbose) {
std::cout
<< " Failed to validate against fuzzer capabilities before running\n";
}
return;
}

if (auto result = fuzzer.fn(mod, data); result != Success) {
if (options.verbose) {
if (auto result = fuzzer.fn(mod, context, data); result != Success) {
if (context.options.verbose) {
std::cout << " Failed to execute fuzzer: " << result.Failure() << "\n";
}
}
Expand Down Expand Up @@ -180,7 +189,7 @@ void Run(const std::function<tint::core::ir::Module()>& acquire_module,
continue;
}

if (auto result = fuzzer.fn(mod, data); result != Success) {
if (auto result = fuzzer.fn(mod, context, data); result != Success) {
if (options.verbose) {
std::cout << " Failed to execute fuzzer: " << result.Failure() << "\n";
}
Expand Down
28 changes: 19 additions & 9 deletions src/tint/cmd/fuzz/ir/fuzz.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ struct Options {
bool run_concurrently = false;
/// If true, print the fuzzer name to stdout before running.
bool verbose = false;
/// If true, dump shader input/output text to stdout
bool dump = false;
};

/// Context holds information about the fuzzer options and the input program.
struct Context {
/// The options used for Run()
Options options;
};

/// IRFuzzer describes a fuzzer function that takes a IR module as input
Expand All @@ -65,11 +73,11 @@ struct IRFuzzer {
/// additional arguments which are deserialized from the fuzzer input.
template <typename... ARGS>
static IRFuzzer Create(std::string_view name,
Result<SuccessType> (*fn)(core::ir::Module&, ARGS...),
Result<SuccessType> (*fn)(core::ir::Module&, const Context&, ARGS...),
core::ir::Capabilities pre_capabilities,
core::ir::Capabilities post_capabilities) {
if constexpr (sizeof...(ARGS) > 0) {
auto fn_with_decode = [fn](core::ir::Module& module,
auto fn_with_decode = [fn](core::ir::Module& module, const Context& context,
Slice<const std::byte> data) -> Result<SuccessType> {
if (!data.data) {
return Failure{"Invalid data"};
Expand All @@ -82,16 +90,16 @@ struct IRFuzzer {
}

auto all_args =
std::tuple_cat(std::tuple<core::ir::Module&>{module}, data_args.Get());
std::tuple_cat(std::tuple<core::ir::Module&, const Context&>{module, context},
data_args.Get());
return std::apply(*fn, all_args);
};
return IRFuzzer{name, std::move(fn_with_decode), pre_capabilities, post_capabilities};
} else {
return IRFuzzer{
name,
[fn](core::ir::Module& module, Slice<const std::byte>) -> Result<SuccessType> {
return fn(module);
},
[fn](core::ir::Module& module, const Context& context,
Slice<const std::byte>) -> Result<SuccessType> { return fn(module, context); },
pre_capabilities,
post_capabilities,
};
Expand All @@ -105,7 +113,7 @@ struct IRFuzzer {
/// additional arguments which are deserialized from the fuzzer input.
template <typename... ARGS>
static IRFuzzer Create(std::string_view name,
Result<SuccessType> (*fn)(core::ir::Module&, ARGS...),
Result<SuccessType> (*fn)(core::ir::Module&, const Context&, ARGS...),
core::ir::Capabilities capabilities) {
return Create(name, fn, capabilities, capabilities);
}
Expand All @@ -115,7 +123,9 @@ struct IRFuzzer {
/// The fuzzer function
/// Takes in the module and any sidecar data, returns true iff transform succeeded in running,
/// otherwise false
std::function<Result<SuccessType>(core::ir::Module&, Slice<const std::byte> data)> fn;
std::function<
Result<SuccessType>(core::ir::Module&, const Context&, Slice<const std::byte> data)>
fn;
/// The IR capabilities that are used before the fuzzer runs.
core::ir::Capabilities pre_capabilities;
/// The IR capabilities that are used after the fuzzer runs.
Expand All @@ -132,7 +142,7 @@ void Register([[maybe_unused]] const IRFuzzer& fuzzer);
/// @param options the options for running the fuzzers
/// @param data additional data used for fuzzing
void Run(const std::function<tint::core::ir::Module()>& acquire_module,
const Options& options,
const Context& context,
Slice<const std::byte> data);
#endif // TINT_BUILD_IR_BINARY

Expand Down
4 changes: 2 additions & 2 deletions src/tint/cmd/fuzz/wgsl/fuzz.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ struct ProgramFuzzer {
} else {
return ProgramFuzzer{
name,
[fn](const Program& program, const Context& options, Slice<const std::byte>) {
fn(program, options);
[fn](const Program& program, const Context& context, Slice<const std::byte>) {
fn(program, context);
},
};
}
Expand Down
6 changes: 3 additions & 3 deletions src/tint/cmd/fuzz/wgsl/main_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ void print_dxc_path_found(const std::string& dxc_path) {
// Log whether the DXC library was found or not once at initialization.
auto dxc = tint::Command::LookPath(dxc_path);
if (dxc.Found()) {
std::cout << "DXC library found: " << dxc.Path() << std::endl;
std::cout << "DXC library found: " << dxc.Path() << "\n";
} else {
std::cout << "DXC library not found: " << dxc_path << std::endl;
std::cout << "DXC library not found: " << dxc_path << "\n";
}
#endif
}
Expand Down Expand Up @@ -139,7 +139,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
print_dxc_path_found(options.dxc);
#if defined(TINT_ASAN_ENABLED) && !defined(NDEBUG)
// TODO(crbug.com/352402877): Avoid DXC timeouts on asan + debug fuzzer builds
std::cout << "DXC validation disabled in asan + debug builds" << std::endl;
std::cout << "DXC validation disabled in asan + debug builds" << "\n";
options.dxc = "";
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
namespace tint::core::ir::binary {
namespace {

Result<SuccessType> IRBinaryRoundtripFuzzer(core::ir::Module& module) {
Result<SuccessType> IRBinaryRoundtripFuzzer(core::ir::Module& module, const fuzz::ir::Context&) {
auto encoded = EncodeToBinary(module);
if (encoded != Success) {
// Failing to encode, not ICE'ing, indicates that an internal limit to the IR binary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& AddEmptyEntryPointFuzzer = AddEmptyEntryPoint;
Result<SuccessType> AddEmptyEntryPointFuzzer(Module& ir, const fuzz::ir::Context&) {
return AddEmptyEntryPoint(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace {
// impl function cannot be passed in directly to fuzzing infra
Result<SuccessType> ArrayLengthFromUniformFuzzer(
Module& module,
const fuzz::ir::Context&,
BindingPoint ubo_binding,
const std::unordered_map<BindingPoint, uint32_t>& bindpoint_to_size_index) {
if (auto res = ArrayLengthFromUniform(module, ubo_binding, bindpoint_to_size_index);
Expand Down
4 changes: 3 additions & 1 deletion src/tint/lang/core/ir/transform/bgra8unorm_polyfill_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& Bgra8UnormPolyfillFuzzer = Bgra8UnormPolyfill;
Result<SuccessType> Bgra8UnormPolyfillFuzzer(Module& ir, const fuzz::ir::Context&) {
return Bgra8UnormPolyfill(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
6 changes: 5 additions & 1 deletion src/tint/lang/core/ir/transform/binary_polyfill_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& BinaryPolyfillFuzzer = BinaryPolyfill;
Result<SuccessType> BinaryPolyfillFuzzer(Module& ir,
const fuzz::ir::Context&,
const BinaryPolyfillConfig& config) {
return BinaryPolyfill(ir, config);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
7 changes: 6 additions & 1 deletion src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& BindingRemapperFuzzer = BindingRemapper;
Result<SuccessType> BindingRemapperFuzzer(
Module& ir,
const fuzz::ir::Context&,
const std::unordered_map<BindingPoint, BindingPoint>& binding_points) {
return BindingRemapper(ir, binding_points);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& BlockDecoratedStructsFuzzer = BlockDecoratedStructs;
Result<SuccessType> BlockDecoratedStructsFuzzer(Module& ir, const fuzz::ir::Context&) {
return BlockDecoratedStructs(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
6 changes: 5 additions & 1 deletion src/tint/lang/core/ir/transform/builtin_polyfill_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& BuiltinPolyfillFuzzer = BuiltinPolyfill;
Result<SuccessType> BuiltinPolyfillFuzzer(Module& ir,
const fuzz::ir::Context&,
const BuiltinPolyfillConfig& config) {
return BuiltinPolyfill(ir, config);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& CombineAccessInstructionsFuzzer = CombineAccessInstructions;
Result<SuccessType> CombineAccessInstructionsFuzzer(Module& ir, const fuzz::ir::Context&) {
return CombineAccessInstructions(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
6 changes: 5 additions & 1 deletion src/tint/lang/core/ir/transform/conversion_polyfill_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& ConversionPolyfillFuzzer = ConversionPolyfill;
Result<SuccessType> ConversionPolyfillFuzzer(Module& ir,
const fuzz::ir::Context&,
const ConversionPolyfillConfig& config) {
return ConversionPolyfill(ir, config);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
4 changes: 3 additions & 1 deletion src/tint/lang/core/ir/transform/demote_to_helper_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& DemoteToHelperFuzzer = DemoteToHelper;
Result<SuccessType> DemoteToHelperFuzzer(Module& ir, const fuzz::ir::Context&) {
return DemoteToHelper(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& DirectVariableAccessFuzzer = DirectVariableAccess;
Result<SuccessType> DirectVariableAccessFuzzer(Module& ir,
const fuzz::ir::Context&,
const DirectVariableAccessOptions& options) {
return DirectVariableAccess(ir, options);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& MultiplanarExternalTextureFuzzer = MultiplanarExternalTexture;
Result<SuccessType> MultiplanarExternalTextureFuzzer(
Module& ir,
const fuzz::ir::Context&,
const tint::transform::multiplanar::BindingsMap& multiplanar_map) {
return MultiplanarExternalTexture(ir, multiplanar_map);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
4 changes: 3 additions & 1 deletion src/tint/lang/core/ir/transform/preserve_padding_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& PreservePaddingFuzzer = PreservePadding;
Result<SuccessType> PreservePaddingFuzzer(Module& ir, const fuzz::ir::Context&) {
return PreservePadding(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& RemoveTerminatorArgsFuzzer = RemoveTerminatorArgs;
Result<SuccessType> RemoveTerminatorArgsFuzzer(Module& ir, const fuzz::ir::Context&) {
return RemoveTerminatorArgs(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
4 changes: 3 additions & 1 deletion src/tint/lang/core/ir/transform/rename_conflicts_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& RenameConflictsFuzzer = RenameConflicts;
Result<SuccessType> RenameConflictsFuzzer(Module& ir, const fuzz::ir::Context&) {
return RenameConflicts(ir);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
4 changes: 3 additions & 1 deletion src/tint/lang/core/ir/transform/robustness_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
namespace tint::core::ir::transform {
namespace {

Result<SuccessType> RobustnessFuzzer(Module& module, RobustnessConfig config) {
Result<SuccessType> RobustnessFuzzer(Module& module,
const fuzz::ir::Context&,
RobustnessConfig config) {
if (!config.bindings_ignored.empty()) {
// TODO(jrprice): Handle config.bindings_ignored.
return Failure{"config.bindings_ignored is not empty"};
Expand Down
2 changes: 1 addition & 1 deletion src/tint/lang/core/ir/transform/std140_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ bool CanRun(Module& module) {
return true;
}

Result<SuccessType> Std140Fuzzer(Module& module) {
Result<SuccessType> Std140Fuzzer(Module& module, const fuzz::ir::Context&) {
if (!CanRun(module)) {
return Failure{"Cannot run module"};
}
Expand Down
6 changes: 5 additions & 1 deletion src/tint/lang/core/ir/transform/substitute_overrides_fuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
namespace tint::core::ir::transform {
namespace {

constexpr auto& SubstituteOverridesFuzzer = SubstituteOverrides;
Result<SuccessType> SubstituteOverridesFuzzer(Module& ir,
const fuzz::ir::Context&,
const SubstituteOverridesConfig& cfg) {
return SubstituteOverrides(ir, cfg);
}

} // namespace
} // namespace tint::core::ir::transform
Expand Down
Loading

0 comments on commit 644bf00

Please sign in to comment.