[validator] Move switch functional checks. Move the functional validation for `Switch` to the functional validator. Bug: 516717234 Change-Id: I980b74ac93fc51234492d521c949410c0b662a2d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/314535 Reviewed-by: James Price <jrprice@google.com> Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/functional_validator.cc b/src/tint/lang/core/ir/functional_validator.cc index 14d2c90..a4dc663 100644 --- a/src/tint/lang/core/ir/functional_validator.cc +++ b/src/tint/lang/core/ir/functional_validator.cc
@@ -307,6 +307,7 @@ [&](const Phony*) {}, // [&](const Store* s) { CheckStore(s); }, // [&](const StoreVectorElement* s) { CheckStoreVectorElement(s); }, // + [&](const Switch* s) { CheckSwitch(s); }, // [&](const Terminator* b) { CheckTerminator(b); }, // [&](const Var* var) { CheckVar(var); } // TODO(516717234): Add TINT_ICE_ON_NO_MATCH when all instructions covered @@ -1007,4 +1008,40 @@ first_continues_.Add(loop, c); } +void Functional::CheckSwitch(const Switch* s) { + if (s->Condition() && !s->Condition()->Type()->IsIntegerScalar()) { + auto* cond_ty = s->Condition() ? s->Condition()->Type() : nullptr; + AddError(s, Switch::kConditionOperandOffset) + << "condition type " << NameOf(cond_ty) << " must be an integer scalar"; + } + + bool found_default = false; + for (auto& case_ : s->Cases()) { + if (case_.selectors.IsEmpty()) { + AddError(s) << "case does not have any selectors"; + } + CheckBlock(case_.block); + + for (const auto& sel : case_.selectors) { + if (sel.IsDefault()) { + if (found_default) { + AddError(s) << "multiple default selectors in switch"; + } + found_default = true; + } else if (!sel.val->Type()->IsIntegerScalar()) { + AddError(s) << "case selector type " << NameOf(sel.val->Type()) + << " must be an integer scalar"; + } else if (s->Condition() && sel.val->Type() != s->Condition()->Type()) { + AddError(s) << "case selector type " << NameOf(sel.val->Type()) + << " must match the switch condition type " + << NameOf(s->Condition()->Type()); + } + } + } + + if (!found_default) { + AddError(s) << "missing default case for switch"; + } +} + } // namespace tint::core::ir::validator
diff --git a/src/tint/lang/core/ir/functional_validator.h b/src/tint/lang/core/ir/functional_validator.h index 1a6084f..b5891c7 100644 --- a/src/tint/lang/core/ir/functional_validator.h +++ b/src/tint/lang/core/ir/functional_validator.h
@@ -44,6 +44,7 @@ #include "src/tint/lang/core/ir/override.h" #include "src/tint/lang/core/ir/store.h" #include "src/tint/lang/core/ir/store_vector_element.h" +#include "src/tint/lang/core/ir/switch.h" #include "src/tint/lang/core/ir/var.h" #include "src/tint/utils/containers/hashmap.h" #include "src/tint/utils/diagnostic/diagnostic.h" @@ -125,6 +126,7 @@ void CheckOverride(const Override* o); void CheckStore(const Store* s); void CheckStoreVectorElement(const StoreVectorElement* s); + void CheckSwitch(const Switch* s); void CheckTerminator(const Terminator* b); void CheckVar(const Var* var);
diff --git a/src/tint/lang/core/ir/structural_validator.cc b/src/tint/lang/core/ir/structural_validator.cc index 5adff9a..d6e63f9 100644 --- a/src/tint/lang/core/ir/structural_validator.cc +++ b/src/tint/lang/core/ir/structural_validator.cc
@@ -3663,44 +3663,13 @@ CheckResults(s); CheckOperands(s, Switch::kNumOperands); - if (s->Condition() && !s->Condition()->Type()->IsIntegerScalar()) { - auto* cond_ty = s->Condition() ? s->Condition()->Type() : nullptr; - AddError(s, Switch::kConditionOperandOffset) - << "condition type " << NameOf(cond_ty) << " must be an integer scalar"; - } - tasks_.Push([this] { control_stack_.Pop(); }); - bool found_default = false; for (auto& cse : s->Cases()) { if (cse.block->Is<core::ir::MultiInBlock>()) { AddError(s) << "case block must be a block"; } - - if (cse.selectors.IsEmpty()) { - AddError(s) << "case does not have any selectors"; - } - QueueBlock(cse.block); - for (const auto& sel : cse.selectors) { - if (sel.IsDefault()) { - if (found_default) { - AddError(s) << "multiple default selectors in switch"; - } - found_default = true; - } else if (!sel.val->Type()->IsIntegerScalar()) { - AddError(s) << "case selector type " << NameOf(sel.val->Type()) - << " must be an integer scalar"; - } else if (s->Condition() && sel.val->Type() != s->Condition()->Type()) { - AddError(s) << "case selector type " << NameOf(sel.val->Type()) - << " must match the switch condition type " - << NameOf(s->Condition()->Type()); - } - } - } - - if (!found_default) { - AddError(s) << "missing default case for switch"; } tasks_.Push([this, s] { control_stack_.Push(s); });