From 1c03712543c90830352c9334cec7b4d30314187f Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Tue, 17 Mar 2026 18:03:22 +0100 Subject: [PATCH 1/5] Made casts explicit in the IRPrinter and StmtToHtml --- src/IRPrinter.cpp | 2 +- src/StmtToHTML.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/IRPrinter.cpp b/src/IRPrinter.cpp index e95286af03ee..7b02f90e61a6 100644 --- a/src/IRPrinter.cpp +++ b/src/IRPrinter.cpp @@ -796,7 +796,7 @@ void IRPrinter::visit(const StringImm *op) { } void IRPrinter::visit(const Cast *op) { - stream << type(op->type); + stream << kw("cast<") << type(op->type) << kw(">"); openf(); print_no_parens(op->value); closef(); diff --git a/src/StmtToHTML.cpp b/src/StmtToHTML.cpp index 37de0023b04d..6b5dd0da4ca2 100644 --- a/src/StmtToHTML.cpp +++ b/src/StmtToHTML.cpp @@ -1429,19 +1429,21 @@ class HTMLCodePrinter : public IRVisitor { void visit(const Cast *op) override { std::string type_str = type_to_string(op->type); print_opening_tag("span", "Cast"); - print_opening_tag("span", "matched"); + print_opening_tag("span", "matched keyword"); + print_text("cast<"); print_type(op->type); - print_text("("); + print_text(">"); print_closing_tag("span"); + print_html_element("span", "matched", "(", type_str); print(op->value); - print_html_element("span", "matched", ")"); + print_html_element("span", "matched", ")", type_str); print_closing_tag("span"); } void visit(const Reinterpret *op) override { std::string type_str = type_to_string(op->type); print_opening_tag("span", "Reinterpret"); - print_opening_tag("span", "matched Symbol", type_str); + print_opening_tag("span", "matched keyword", type_str); print_text("reinterpret<"); print_type(op->type); print_text(">"); From 34e01b651dc535a9952bd53db37a435078706936 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Tue, 17 Mar 2026 22:52:56 +0100 Subject: [PATCH 2/5] IRPrinter: Let and LetStmt have explicit type: let varname : type = value; IRPrinter types have been shortened to the concise versions. IRPrinter immediates use suffixes, or true/false in case of UInt(1). --- src/IRPrinter.cpp | 30 ++++++++++++++++++++++-------- src/StmtToHTML.cpp | 4 ++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/IRPrinter.cpp b/src/IRPrinter.cpp index 7b02f90e61a6..334775681641 100644 --- a/src/IRPrinter.cpp +++ b/src/IRPrinter.cpp @@ -31,20 +31,20 @@ using std::vector; ostream &operator<<(ostream &out, const Type &type) { switch (type.code()) { case Type::Int: - out << "int"; + out << "i"; break; case Type::UInt: - out << "uint"; + out << "u"; break; case Type::Float: - out << "float"; + out << "f"; break; case Type::Handle: // ensure that 'const' (etc) qualifiers are emitted when appropriate out << "(" << type_to_c_type(type, false) << ")"; break; case Type::BFloat: - out << "bfloat"; + out << "bf"; break; } if (!type.is_handle()) { @@ -724,12 +724,16 @@ void IRPrinter::visit(const IntImm *op) { if (op->type == Int(32)) { stream << imm_int(op->value); } else { - stream << typep(op->type) << imm_int(op->value); + stream << ansi_imm_int << op->value << "_i" << op->type.bits() << ansi_reset; } } void IRPrinter::visit(const UIntImm *op) { - stream << typep(op->type) << imm_int(op->value); + if (op->type.bits() == 1) { + stream << ansi_imm_int << (op->value ? "true" : "false") << ansi_reset; + } else { + stream << ansi_imm_int << op->value << "_u" << op->type.bits() << ansi_reset; + } } void IRPrinter::visit(const FloatImm *op) { @@ -796,10 +800,20 @@ void IRPrinter::visit(const StringImm *op) { } void IRPrinter::visit(const Cast *op) { +#if 0 + // More explicit style of denoting a cast, which we did not yet agree upon. + // Leaving it in as commted out code, because it might be useful at some point. stream << kw("cast<") << type(op->type) << kw(">"); openf(); print_no_parens(op->value); closef(); +#else + std::stringstream ss; + ss << op->type; + openf(ss.str().c_str()); + print_no_parens(op->value); + closef(); +#endif } void IRPrinter::visit(const Reinterpret *op) { @@ -1084,7 +1098,7 @@ void IRPrinter::visit(const Let *op) { if (!implicit_parens) { stream << paren("("); } - stream << paren("let ") << var(op->name) << paren(" = "); + stream << paren("let ") << var(op->name) << paren(" : ") << paren(op->value.type()) << paren(" = "); print(op->value); stream << paren(" in "); if (!is_summary) { @@ -1098,7 +1112,7 @@ void IRPrinter::visit(const Let *op) { void IRPrinter::visit(const LetStmt *op) { ScopedBinding<> bind(known_type, op->name); - stream << get_indent() << kw("let ") << var(op->name) << kw(" = "); + stream << get_indent() << ansi_kw << "let " << ansi_reset << op->name << ansi_kw << " : " << op->value.type() << " = " << ansi_reset; { ScopedValue reset_paren_depth(paren_depth, 0); print_no_parens(op->value); diff --git a/src/StmtToHTML.cpp b/src/StmtToHTML.cpp index 6b5dd0da4ca2..6fbda159cc8e 100644 --- a/src/StmtToHTML.cpp +++ b/src/StmtToHTML.cpp @@ -1430,9 +1430,13 @@ class HTMLCodePrinter : public IRVisitor { std::string type_str = type_to_string(op->type); print_opening_tag("span", "Cast"); print_opening_tag("span", "matched keyword"); +#if 0 print_text("cast<"); print_type(op->type); print_text(">"); +#else + print_text(type_str); +#endif print_closing_tag("span"); print_html_element("span", "matched", "(", type_str); print(op->value); From 14a649a259b7fd5c33165ebc90368900ee4ba439 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Tue, 17 Mar 2026 23:21:44 +0100 Subject: [PATCH 3/5] Fixup for correctness/callable_errors --- test/correctness/callable_errors.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/correctness/callable_errors.cpp b/test/correctness/callable_errors.cpp index 2c0abce5407f..159d20bbc05c 100644 --- a/test/correctness/callable_errors.cpp +++ b/test/correctness/callable_errors.cpp @@ -112,9 +112,9 @@ void test_bad_untyped_calls() { expect_failure(c(&context, Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); expect_failure(c(&context, Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); expect_failure(c(&context, Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); - expect_failure(c(&context, 42, 2, 1.0f, result1), "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'uint8' and dimension 2"); - expect_failure(c(&context, in1, 2.25, 1.0f, result1), "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'int32' and dimension 0"); - expect_failure(c(&context, in1, 2, 1, result1), "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'float32' and dimension 0"); + expect_failure(c(&context, 42, 2, 1.0f, result1), "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'u8' and dimension 2"); + expect_failure(c(&context, in1, 2.25, 1.0f, result1), "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'i32' and dimension 0"); + expect_failure(c(&context, in1, 2, 1, result1), "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'f32' and dimension 0"); expect_failure(c(&context, in1, 2, 1.0f, (const halide_buffer_t *)nullptr), "Buffer argument fn2 is nullptr"); expect_failure(c(&context, in1, 2, 1.0f, (halide_buffer_t *)nullptr), "Buffer argument fn2 is nullptr"); expect_failure(c(&context, in1, 2, 1.0f, Buffer()), "Buffer argument fn2 is nullptr"); @@ -162,16 +162,16 @@ void test_bad_typed_calls() { // Calls to make_std_function fail c.make_std_function>(); - expect_failure(-1, "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'uint8' and dimension 2"); + expect_failure(-1, "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'u8' and dimension 2"); c.make_std_function, bool, float, Buffer>(); - expect_failure(-1, "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'int32' and dimension 0"); + expect_failure(-1, "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'i32' and dimension 0"); c.make_std_function, int32_t, bool, Buffer>(); - expect_failure(-1, "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'float32' and dimension 0"); + expect_failure(-1, "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'f32' and dimension 0"); c.make_std_function, int32_t, float, bool>(); - expect_failure(-1, "Argument 4 of 4 ('fn3') was expected to be a buffer of type 'uint8' and dimension 2"); + expect_failure(-1, "Argument 4 of 4 ('fn3') was expected to be a buffer of type 'u8' and dimension 2"); } // Test custom error handler in the JITUserContext From db318129eb7b94a0c6ace224176441caa4468b22 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Tue, 17 Mar 2026 23:22:00 +0100 Subject: [PATCH 4/5] Reflect changes in StmtToHtml. --- src/StmtToHTML.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/StmtToHTML.cpp b/src/StmtToHTML.cpp index 6fbda159cc8e..e7638aef240a 100644 --- a/src/StmtToHTML.cpp +++ b/src/StmtToHTML.cpp @@ -1580,7 +1580,9 @@ class HTMLCodePrinter : public IRVisitor { print_opening_tag("span", "matched"); print_text("("); print_html_element("span", "keyword", "let "); - print_variable(op->name, op->type); + print_variable(op->name, op->value.type()); + print_html_element("span", "Operator Assign", " : "); + print_type(op->type); print_html_element("span", "Operator Assign", " = "); print_closing_tag("span"); print(op->value); @@ -1599,6 +1601,8 @@ class HTMLCodePrinter : public IRVisitor { print_opening_tag("span", "matched"); print_html_element("span", "keyword", "let "); print_variable(op->name, op->value.type()); + print_html_element("span", "Operator Assign", " : "); + print_type(op->value.type()); print_html_element("span", "Operator Assign", " = "); print_closing_tag("span"); // matched print(op->value); From 79a83ba6f7a5067ba81819b6e4e0968b9484887a Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Wed, 18 Mar 2026 00:19:17 +0100 Subject: [PATCH 5/5] Fixup test_internal for IRPrinter. Fixup correctness/callable_errors --- src/IRPrinter.cpp | 4 ++-- test/correctness/callable_errors.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/IRPrinter.cpp b/src/IRPrinter.cpp index 334775681641..f092848ae009 100644 --- a/src/IRPrinter.cpp +++ b/src/IRPrinter.cpp @@ -262,8 +262,8 @@ void IRPrinter::test() { ostringstream source; source << allocate; std::string correct_source = - "allocate buf[float32 * 1023] in Stack\n" - "let y = 17\n" + "allocate buf[f32 * 1023] in Stack\n" + "let y : i32 = 17\n" "assert(y >= 3, halide_error_param_too_small_i64(\"y\", y, 3))\n" "produce buf {\n" " parallel (x, -2, y + 2) {\n" diff --git a/test/correctness/callable_errors.cpp b/test/correctness/callable_errors.cpp index 159d20bbc05c..2aa21e1ae8f7 100644 --- a/test/correctness/callable_errors.cpp +++ b/test/correctness/callable_errors.cpp @@ -67,9 +67,9 @@ void test_bad_untyped_calls() { expect_failure(c(Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); expect_failure(c(Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); expect_failure(c(Buffer(), 2, 1.0f, result1), "Buffer argument p_img is nullptr"); - expect_failure(c(42, 2, 1.0f, result1), "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'uint8' and dimension 2"); - expect_failure(c(in1, 2.25, 1.0f, result1), "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'int32' and dimension 0"); - expect_failure(c(in1, 2, 1, result1), "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'float32' and dimension 0"); + expect_failure(c(42, 2, 1.0f, result1), "Argument 1 of 4 ('p_img') was expected to be a buffer of type 'u8' and dimension 2"); + expect_failure(c(in1, 2.25, 1.0f, result1), "Argument 2 of 4 ('p_int') was expected to be a scalar of type 'i32' and dimension 0"); + expect_failure(c(in1, 2, 1, result1), "Argument 3 of 4 ('p_float') was expected to be a scalar of type 'f32' and dimension 0"); expect_failure(c(in1, 2, 1.0f, (const halide_buffer_t *)nullptr), "Buffer argument fn1 is nullptr"); expect_failure(c(in1, 2, 1.0f, (halide_buffer_t *)nullptr), "Buffer argument fn1 is nullptr"); expect_failure(c(in1, 2, 1.0f, Buffer()), "Buffer argument fn1 is nullptr");