[tint][ir] Use CheckOperandsMatchTarget() for exit instructions
Fixes swapped argument / result type in error diagnostic, and consolidates common logic.
Also subjectively better error diagnostic.
Change-Id: Ife422aebacaf30a8b31f90d6932f03f330a63f7b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/188984
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index c31ff3b..b72475c 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -1337,24 +1337,9 @@
return;
}
- auto results = e->ControlInstruction()->Results();
auto args = e->Args();
- if (results.Length() != args.Length()) {
- AddError(e) << ("args count (") << args.Length()
- << ") does not match control instruction result count (" << results.Length()
- << ")";
- AddNote(e->ControlInstruction()) << "control instruction";
- return;
- }
-
- for (size_t i = 0; i < results.Length(); ++i) {
- if (results[i] && args[i] && results[i]->Type() != args[i]->Type()) {
- AddError(e, i) << "argument type " << style::Type(results[i]->Type()->FriendlyName())
- << " does not match control instruction type "
- << style::Type(args[i]->Type()->FriendlyName());
- AddNote(e->ControlInstruction()) << "control instruction";
- }
- }
+ CheckOperandsMatchTarget(e, e->ArgsOperandOffset(), args.Length(), e->ControlInstruction(),
+ e->ControlInstruction()->Results());
tint::Switch(
e, //
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 76125b4..820182a 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -1914,9 +1914,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_if: args count (1) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_if: provides 1 value but 'if' expects 2 values
exit_if 1i # if_1
^^^^^^^^^^
@@ -1924,7 +1923,7 @@
$B2: { # true
^^^
-:3:5 note: control instruction
+:3:5 note: 'if' declared here
%2:i32, %3:f32 = if true [t: $B2] { # if_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1958,9 +1957,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_if: args count (3) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_if: provides 3 values but 'if' expects 2 values
exit_if 1i, 2.0f, 3i # if_1
^^^^^^^^^^^^^^^^^^^^
@@ -1968,7 +1966,7 @@
$B2: { # true
^^^
-:3:5 note: control instruction
+:3:5 note: 'if' declared here
%2:i32, %3:f32 = if true [t: $B2] { # if_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2019,9 +2017,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:21 error: exit_if: argument type 'f32' does not match control instruction type 'i32'
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:21 error: exit_if: operand with type 'i32' does not match 'if' target type 'f32'
exit_if 1i, 2i # if_1
^^
@@ -2029,9 +2026,9 @@
$B2: { # true
^^^
-:3:5 note: control instruction
+:3:13 note: %3 declared here
%2:i32, %3:f32 = if true [t: $B2] { # if_1
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ^^^^^^
note: # Disassembly
%my_func = func():void {
@@ -2307,9 +2304,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_switch: args count (1) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_switch: provides 1 value but 'switch' expects 2 values
exit_switch 1i # switch_1
^^^^^^^^^^^^^^
@@ -2317,7 +2313,7 @@
$B2: { # case
^^^
-:3:5 note: control instruction
+:3:5 note: 'switch' declared here
%2:i32, %3:f32 = switch true [c: (default, $B2)] { # switch_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2351,9 +2347,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_switch: args count (3) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_switch: provides 3 values but 'switch' expects 2 values
exit_switch 1i, 2.0f, 3i # switch_1
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2361,7 +2356,7 @@
$B2: { # case
^^^
-:3:5 note: control instruction
+:3:5 note: 'switch' declared here
%2:i32, %3:f32 = switch true [c: (default, $B2)] { # switch_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2415,7 +2410,7 @@
ASSERT_NE(res, Success);
EXPECT_EQ(
res.Failure().reason.Str(),
- R"(:5:25 error: exit_switch: argument type 'f32' does not match control instruction type 'i32'
+ R"(:5:25 error: exit_switch: operand with type 'i32' does not match 'switch' target type 'f32'
exit_switch 1i, 2i # switch_1
^^
@@ -2423,9 +2418,9 @@
$B2: { # case
^^^
-:3:5 note: control instruction
+:3:13 note: %3 declared here
%2:i32, %3:f32 = switch true [c: (default, $B2)] { # switch_1
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ^^^^^^
note: # Disassembly
%my_func = func():void {
@@ -3601,9 +3596,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_loop: args count (1) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_loop: provides 1 value but 'loop' expects 2 values
exit_loop 1i # loop_1
^^^^^^^^^^^^
@@ -3611,7 +3605,7 @@
$B2: { # body
^^^
-:3:5 note: control instruction
+:3:5 note: 'loop' declared here
%2:i32, %3:f32 = loop [b: $B2, c: $B3] { # loop_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3648,9 +3642,8 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(
- res.Failure().reason.Str(),
- R"(:5:9 error: exit_loop: args count (3) does not match control instruction result count (2)
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:5:9 error: exit_loop: provides 3 values but 'loop' expects 2 values
exit_loop 1i, 2.0f, 3i # loop_1
^^^^^^^^^^^^^^^^^^^^^^
@@ -3658,7 +3651,7 @@
$B2: { # body
^^^
-:3:5 note: control instruction
+:3:5 note: 'loop' declared here
%2:i32, %3:f32 = loop [b: $B2, c: $B3] { # loop_1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -3715,7 +3708,7 @@
ASSERT_NE(res, Success);
EXPECT_EQ(
res.Failure().reason.Str(),
- R"(:5:23 error: exit_loop: argument type 'f32' does not match control instruction type 'i32'
+ R"(:5:23 error: exit_loop: operand with type 'i32' does not match 'loop' target type 'f32'
exit_loop 1i, 2i # loop_1
^^
@@ -3723,9 +3716,9 @@
$B2: { # body
^^^
-:3:5 note: control instruction
+:3:13 note: %3 declared here
%2:i32, %3:f32 = loop [b: $B2, c: $B3] { # loop_1
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ^^^^^^
note: # Disassembly
%my_func = func():void {