spirv builder: allow unsigned int cases for switch statements
Change-Id: If7a8955961b56925cae538249d4e17495d3f8e1b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42901
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 26b2c8e..0d673f7 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -2618,12 +2618,13 @@
case_ids.push_back(block_id);
for (auto* selector : item->selectors()) {
- if (!selector->Is<ast::SintLiteral>()) {
+ auto* int_literal = selector->As<ast::IntLiteral>();
+ if (!int_literal) {
error_ = "expected integer literal for switch case label";
return false;
}
- params.push_back(Operand::Int(selector->As<ast::SintLiteral>()->value()));
+ params.push_back(Operand::Int(int_literal->value_as_u32()));
params.push_back(Operand::Int(block_id));
}
}
diff --git a/src/writer/spirv/builder_switch_test.cc b/src/writer/spirv/builder_switch_test.cc
index c0ee18f..9dcf3da 100644
--- a/src/writer/spirv/builder_switch_test.cc
+++ b/src/writer/spirv/builder_switch_test.cc
@@ -136,6 +136,81 @@
)");
}
+TEST_F(BuilderTest, Switch_WithCase_Unsigned) {
+ // switch(a) {
+ // case 1u:
+ // v = 1;
+ // case 2u:
+ // v = 2;
+ // }
+
+ auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
+ auto* a = Global("a", ty.u32(), ast::StorageClass::kPrivate);
+
+ auto* case_1_body = create<ast::BlockStatement>(
+ ast::StatementList{create<ast::AssignmentStatement>(Expr("v"), Expr(1))});
+
+ auto* case_2_body = create<ast::BlockStatement>(
+ ast::StatementList{create<ast::AssignmentStatement>(Expr("v"), Expr(2))});
+
+ ast::CaseSelectorList selector_1;
+ selector_1.push_back(Literal(1u));
+
+ ast::CaseSelectorList selector_2;
+ selector_2.push_back(Literal(2u));
+
+ ast::CaseStatementList cases;
+ cases.push_back(create<ast::CaseStatement>(selector_1, case_1_body));
+ cases.push_back(create<ast::CaseStatement>(selector_2, case_2_body));
+
+ auto* expr = create<ast::SwitchStatement>(Expr("a"), cases);
+
+ WrapInFunction(expr);
+
+ auto* func = Func("a_func", {}, ty.i32(), ast::StatementList{},
+ ast::FunctionDecorationList{});
+
+ spirv::Builder& b = Build();
+
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+
+ EXPECT_TRUE(b.GenerateSwitchStatement(expr)) << b.error();
+
+ EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
+OpName %5 "a"
+OpName %10 "a_func"
+%3 = OpTypeInt 32 1
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
+%7 = OpTypeInt 32 0
+%6 = OpTypePointer Private %7
+%8 = OpConstantNull %7
+%5 = OpVariable %6 Private %8
+%9 = OpTypeFunction %3
+%17 = OpConstant %3 1
+%18 = OpConstant %3 2
+%10 = OpFunction %3 None %9
+%11 = OpLabel
+%13 = OpLoad %7 %5
+OpSelectionMerge %12 None
+OpSwitch %13 %14 1 %15 2 %16
+%15 = OpLabel
+OpStore %1 %17
+OpBranch %12
+%16 = OpLabel
+OpStore %1 %18
+OpBranch %12
+%14 = OpLabel
+OpBranch %12
+%12 = OpLabel
+OpReturn
+OpFunctionEnd
+)");
+}
+
TEST_F(BuilderTest, Switch_WithDefault) {
// switch(true) {
// default: