[ir] Check for duplicate result usage.
Update the validator to catch a duplicate result usage in a single
instruction.
Fixed: 440157913
Change-Id: I3a85c83870d5627542117f6db501dfc0b94f4df7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/259054
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index f3e2491..82b765d 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -1732,10 +1732,16 @@
}
bool passed = true;
+ Hashset<const InstructionResult*, 4> seen_instruction_results;
for (size_t i = 0; i < inst->Results().Length(); i++) {
if (DAWN_UNLIKELY(!CheckResult(inst, i))) {
passed = false;
}
+
+ if (!seen_instruction_results.Add(inst->Result(i))) {
+ AddResultError(inst, i) << "result was seen previously as a result";
+ passed = false;
+ }
}
return passed;
}
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index ab3fb26..5a5cdc5 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -1075,6 +1075,26 @@
)")) << res.Failure();
}
+TEST_F(IR_ValidatorTest, Instruction_DuplicateResultOneCall) {
+ auto* f = b.Function("my_func", ty.void_());
+
+ b.Append(f->Block(), [&] {
+ auto* l = b.Loop();
+ auto* r1 = b.InstructionResult(ty.u32());
+ l->SetResults(Vector{r1, r1});
+ b.Append(l->Body(), [&] { b.Unreachable(); });
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_THAT(res.Failure().reason,
+ testing::HasSubstr(R"(:3:13 error: loop: result was seen previously as a result
+ %2:u32, %2:u32 = loop [b: $B2] { # loop_1
+ ^^^^^^)"))
+ << res.Failure();
+}
+
TEST_F(IR_ValidatorTest, Instruction_WrongInstructionResultInstruction) {
auto* f = b.Function("my_func", ty.void_());