[ir] Fix issues with InboundSiblingBranches.
In each of the `continue`, break-if` and `next-iteration` instructions
we have to remove the inbound sibling branches on `Destroy`.
The `continue` instruction when you did a `SetLoop` was incorrectly
using the `Body` branch of the loop instead of the `Continuing` branch.
Change-Id: I4efe166180941154502fcfa75a51253d5858085f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/244354
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/break_if.cc b/src/tint/lang/core/ir/break_if.cc
index 0191868..9ab1be7 100644
--- a/src/tint/lang/core/ir/break_if.cc
+++ b/src/tint/lang/core/ir/break_if.cc
@@ -62,6 +62,13 @@
BreakIf::~BreakIf() = default;
+void BreakIf::Destroy() {
+ if (loop_) {
+ loop_->Body()->RemoveInboundSiblingBranch(this);
+ }
+ Instruction::Destroy();
+}
+
BreakIf* BreakIf::Clone(CloneContext& ctx) {
auto* loop = ctx.Remap(loop_);
auto* cond = ctx.Remap(Condition());
diff --git a/src/tint/lang/core/ir/break_if.h b/src/tint/lang/core/ir/break_if.h
index 132ea20..a5be066 100644
--- a/src/tint/lang/core/ir/break_if.h
+++ b/src/tint/lang/core/ir/break_if.h
@@ -71,6 +71,9 @@
~BreakIf() override;
+ /// @copydoc Instruction::Destroy()
+ void Destroy() override;
+
/// @copydoc Instruction::Clone()
BreakIf* Clone(CloneContext& ctx) override;
diff --git a/src/tint/lang/core/ir/break_if_test.cc b/src/tint/lang/core/ir/break_if_test.cc
index b1c1cc7..be3e5a7 100644
--- a/src/tint/lang/core/ir/break_if_test.cc
+++ b/src/tint/lang/core/ir/break_if_test.cc
@@ -129,5 +129,18 @@
EXPECT_THAT(loop2->Exits(), testing::ElementsAre(brk));
}
+TEST_F(IR_BreakIfTest, Destroy) {
+ auto* loop = b.Loop();
+ auto* cond = b.Constant(true);
+ auto* inst = b.BreakIf(loop, cond);
+
+ ASSERT_EQ(1u, loop->Body()->InboundSiblingBranches().Length());
+ EXPECT_EQ(inst, loop->Body()->InboundSiblingBranches()[0]);
+
+ inst->Destroy();
+
+ EXPECT_EQ(0u, loop->Body()->InboundSiblingBranches().Length());
+}
+
} // namespace
} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/continue.cc b/src/tint/lang/core/ir/continue.cc
index c36abe1..ae32299 100644
--- a/src/tint/lang/core/ir/continue.cc
+++ b/src/tint/lang/core/ir/continue.cc
@@ -54,6 +54,13 @@
Continue::~Continue() = default;
+void Continue::Destroy() {
+ if (loop_) {
+ loop_->Continuing()->RemoveInboundSiblingBranch(this);
+ }
+ Instruction::Destroy();
+}
+
Continue* Continue::Clone(CloneContext& ctx) {
auto* loop = ctx.Remap(Loop());
auto args = ctx.Remap<Continue::kDefaultNumOperands>(Args());
@@ -63,11 +70,11 @@
void Continue::SetLoop(ir::Loop* loop) {
if (loop_ && loop_->Body()) {
- loop_->Body()->RemoveInboundSiblingBranch(this);
+ loop_->Continuing()->RemoveInboundSiblingBranch(this);
}
loop_ = loop;
if (loop) {
- loop->Body()->AddInboundSiblingBranch(this);
+ loop->Continuing()->AddInboundSiblingBranch(this);
}
}
diff --git a/src/tint/lang/core/ir/continue.h b/src/tint/lang/core/ir/continue.h
index dab2080..a5eecd7 100644
--- a/src/tint/lang/core/ir/continue.h
+++ b/src/tint/lang/core/ir/continue.h
@@ -61,6 +61,9 @@
/// @copydoc Instruction::Clone()
Continue* Clone(CloneContext& ctx) override;
+ /// @copydoc Instruction::Destroy()
+ void Destroy() override;
+
/// @returns the loop owning the continue block
ir::Loop* Loop() { return loop_; }
diff --git a/src/tint/lang/core/ir/continue_test.cc b/src/tint/lang/core/ir/continue_test.cc
index 85a5e7e..a9f4518 100644
--- a/src/tint/lang/core/ir/continue_test.cc
+++ b/src/tint/lang/core/ir/continue_test.cc
@@ -101,5 +101,17 @@
EXPECT_EQ(2_u, val1->As<core::constant::Scalar<u32>>()->ValueAs<u32>());
}
+TEST_F(IR_ContinueTest, Destroy) {
+ auto* loop = b.Loop();
+ auto* inst = b.Continue(loop);
+
+ ASSERT_EQ(1u, loop->Continuing()->InboundSiblingBranches().Length());
+ EXPECT_EQ(inst, loop->Continuing()->InboundSiblingBranches()[0]);
+
+ inst->Destroy();
+
+ EXPECT_EQ(0u, loop->Continuing()->InboundSiblingBranches().Length());
+}
+
} // namespace
} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/next_iteration.cc b/src/tint/lang/core/ir/next_iteration.cc
index bba8de8..425f505 100644
--- a/src/tint/lang/core/ir/next_iteration.cc
+++ b/src/tint/lang/core/ir/next_iteration.cc
@@ -54,6 +54,13 @@
NextIteration::~NextIteration() = default;
+void NextIteration::Destroy() {
+ if (loop_) {
+ loop_->Body()->RemoveInboundSiblingBranch(this);
+ }
+ Instruction::Destroy();
+}
+
NextIteration* NextIteration::Clone(CloneContext& ctx) {
auto* new_loop = ctx.Clone(loop_);
auto args = ctx.Remap<NextIteration::kDefaultNumOperands>(Args());
diff --git a/src/tint/lang/core/ir/next_iteration.h b/src/tint/lang/core/ir/next_iteration.h
index 825f8c0..13e1723 100644
--- a/src/tint/lang/core/ir/next_iteration.h
+++ b/src/tint/lang/core/ir/next_iteration.h
@@ -59,6 +59,9 @@
~NextIteration() override;
+ /// @copydoc Instruction::Destroy()
+ void Destroy() override;
+
/// @copydoc Instruction::Clone()
NextIteration* Clone(CloneContext& ctx) override;
diff --git a/src/tint/lang/core/ir/next_iteration_test.cc b/src/tint/lang/core/ir/next_iteration_test.cc
index 6a7a6e3..b2cc9185 100644
--- a/src/tint/lang/core/ir/next_iteration_test.cc
+++ b/src/tint/lang/core/ir/next_iteration_test.cc
@@ -84,5 +84,17 @@
EXPECT_EQ(new_loop, new_inst->Loop());
}
+TEST_F(IR_NextIterationTest, Destroy) {
+ auto* loop = b.Loop();
+ auto* inst = b.NextIteration(loop);
+
+ ASSERT_EQ(1u, loop->Body()->InboundSiblingBranches().Length());
+ EXPECT_EQ(inst, loop->Body()->InboundSiblingBranches()[0]);
+
+ inst->Destroy();
+
+ EXPECT_EQ(0u, loop->Body()->InboundSiblingBranches().Length());
+}
+
} // namespace
} // namespace tint::core::ir