diff --git a/src/AddImageChecks.cpp b/src/AddImageChecks.cpp index e9ca8ae25be9..72f2596fe12b 100644 --- a/src/AddImageChecks.cpp +++ b/src/AddImageChecks.cpp @@ -106,11 +106,21 @@ class TrimStmtToPartsThatAccessBuffers : public IRMutator { using IRMutator::visit; Expr visit(const Call *op) override { - touches_buffer |= (buffers.count(op->name) > 0); + touches_buffer |= + (buffers.count(op->name) > 0) || + (buffers.count(op->name + "." + std::to_string(op->value_index))); + // Output Tuple params are in the buffers map under their qualified + // tuple name, not the Func name. return IRMutator::visit(op); } Stmt visit(const Provide *op) override { - touches_buffer |= (buffers.find(op->name) != buffers.end()); + if (op->values.size() == 1) { + touches_buffer |= (buffers.find(op->name) != buffers.end()); + } else { + // It's a Tuple. Just check if the first Tuple component corresponds + // to an output buffer. If it does, they all do. + touches_buffer |= (buffers.find(op->name + ".0") != buffers.end()); + } return IRMutator::visit(op); } Expr visit(const Variable *op) override { diff --git a/test/error/CMakeLists.txt b/test/error/CMakeLists.txt index ee9d47923469..f85ede60d7a8 100644 --- a/test/error/CMakeLists.txt +++ b/test/error/CMakeLists.txt @@ -94,6 +94,7 @@ tests(GROUPS error thread_id_outside_block_id.cpp too_many_args.cpp tuple_arg_select_undef.cpp + tuple_output_bounds_check.cpp tuple_val_select_undef.cpp unbounded_input.cpp unbounded_output.cpp diff --git a/test/error/tuple_output_bounds_check.cpp b/test/error/tuple_output_bounds_check.cpp new file mode 100644 index 000000000000..53b3a26a8337 --- /dev/null +++ b/test/error/tuple_output_bounds_check.cpp @@ -0,0 +1,26 @@ +#include "Halide.h" + +using namespace Halide; + +int main(int argc, char **argv) { + // The code below used to not inject appropriate bounds checks. + // See https://github.com/halide/Halide/issues/7343 + + Var x; + + const int size = 1024; + + Func h; + h(x) = {0, 0}; + RDom r(0, size); + h(r) = {h(r - 100)[0], 0}; + + Var xo, xi; + h.split(x, xo, xi, 16, TailStrategy::RoundUp); + + Buffer r0(size); + Buffer r1(size); + h.realize({r0, r1}); + + return 0; +}