[spirv-writer] Add array constructors.
This CL emits array type constructors in the SPIR-V backend.
Change-Id: I796e81964df1af39ad1aacdd4ab8181852f661fa
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28900
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 0ae7a59..6b4866d 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -1097,8 +1097,6 @@
if (result_type->IsVector()) {
result_type = result_type->AsVector()->type();
- } else if (result_type->IsArray()) {
- result_type = result_type->AsArray()->type();
}
for (const auto& e : values) {
@@ -1115,10 +1113,12 @@
auto* value_type = e->result_type()->UnwrapPtrIfNeeded();
// If the result and value types are the same we can just use the object.
- // If the result is a matrix then we should have validated that the value
- // type is a correctly sized vector so we can just use it directly.
- if (result_type == value_type || result_type->IsMatrix()) {
+ // If the result is not a vector then we should have validated that the
+ // value type is a correctly sized vector so we can just use it directly.
+ if (result_type == value_type || result_type->IsMatrix() ||
+ result_type->IsArray() || result_type->IsStruct()) {
out << "_" << id;
+
ops.push_back(Operand::Int(id));
continue;
}
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index 6ca6cec..2121086 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -1610,12 +1610,89 @@
)");
}
-TEST_F(BuilderTest, DISABLED_Constructor_Type_Array_5_F32) {
- FAIL();
+TEST_F(BuilderTest, Constructor_Type_Array_5_F32) {
+ ast::type::F32Type f32;
+ ast::type::ArrayType ary(&f32, 5);
+
+ ast::ExpressionList params;
+ params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::TypeConstructorExpression cast(&ary, std::move(params));
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
+
+ Builder b(&mod);
+ b.push_function(Function{});
+ EXPECT_EQ(b.GenerateExpression(&cast), 6u);
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+%3 = OpTypeInt 32 0
+%4 = OpConstant %3 5
+%1 = OpTypeArray %2 %4
+%5 = OpConstant %2 2
+%6 = OpConstantComposite %1 %5 %5 %5 %5 %5
+)");
}
-TEST_F(BuilderTest, DISABLED_Constructor_Type_Array_5_Vec3) {
- FAIL();
+TEST_F(BuilderTest, Constructor_Type_Array_2_Vec3) {
+ ast::type::F32Type f32;
+ ast::type::VectorType vec(&f32, 3);
+ ast::type::ArrayType ary(&vec, 2);
+
+ ast::ExpressionList vec_params;
+ vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ vec_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::ExpressionList vec2_params;
+ vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+ vec2_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::ExpressionList params;
+ params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+ &vec, std::move(vec_params)));
+ params.push_back(std::make_unique<ast::TypeConstructorExpression>(
+ &vec, std::move(vec2_params)));
+
+ ast::TypeConstructorExpression cast(&ary, std::move(params));
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
+
+ Builder b(&mod);
+ b.push_function(Function{});
+ EXPECT_EQ(b.GenerateExpression(&cast), 8u);
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+%2 = OpTypeVector %3 3
+%4 = OpTypeInt 32 0
+%5 = OpConstant %4 2
+%1 = OpTypeArray %2 %5
+%6 = OpConstant %3 2
+%7 = OpConstantComposite %2 %6 %6 %6
+%8 = OpConstantComposite %1 %7 %7
+)");
}
TEST_F(BuilderTest, DISABLED_Constructor_Type_Struct) {