[spirv-writer] Fixup constructor with bitcast parameters.

Currently if a constructor contains constructors we consider it const.
This falls down with the new type constructor syntax if the types don't
match. In the case they don't match we no longer consider the
constructor const as we'll generate OpBitcast and OpCopyObject
instructions which we need to build the composite from.

Bug: tint: 263
Change-Id: Ic85f58c8410e862a2ec30c7d93c9b87a61822f6d
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/29523
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-10-07 14:06:28 +00:00 committed by Commit Bot service account
parent c9110b93cb
commit a388d56d99
2 changed files with 53 additions and 2 deletions

View File

@ -1100,6 +1100,8 @@ uint32_t Builder::GenerateTypeConstructorExpression(
std::ostringstream out;
out << "__const";
auto* result_type = init->type()->UnwrapAliasPtrAlias();
OperandList ops;
bool constructor_is_const = true;
for (const auto& e : values) {
@ -1109,11 +1111,19 @@ uint32_t Builder::GenerateTypeConstructorExpression(
return 0;
}
constructor_is_const = false;
break;
} else if (result_type->IsVector()) {
// Even if we have constructor parameters if the types are different then
// the constructor is not const as we'll generate OpBitcast or
// OpCopyObject instructions.
auto* subtype = result_type->AsVector()->type()->UnwrapAliasPtrAlias();
if (subtype != e->result_type()->UnwrapAliasPtrAlias()) {
constructor_is_const = false;
break;
}
}
}
auto* result_type = init->type()->UnwrapAliasPtrAlias();
bool can_cast_or_copy = result_type->is_scalar();
if (result_type->IsVector() && result_type->AsVector()->type()->is_scalar()) {
auto* value_type = values[0]->result_type()->UnwrapAliasPtrAlias();

View File

@ -171,6 +171,43 @@ TEST_F(BuilderTest, Constructor_Type_IdentifierExpression_Param) {
)");
}
TEST_F(BuilderTest, Constructor_Vector_Bitcast_Params) {
ast::type::I32Type i32;
ast::type::U32Type u32;
ast::type::VectorType vec(&u32, 2);
ast::ExpressionList vals;
vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1)));
vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::SintLiteral>(&i32, 1)));
ast::TypeConstructorExpression t(&vec, std::move(vals));
Context ctx;
ast::Module mod;
TypeDeterminer td(&ctx, &mod);
EXPECT_TRUE(td.DetermineResultType(&t)) << td.error();
Builder b(&mod);
b.push_function(Function{});
EXPECT_EQ(b.GenerateExpression(&t), 7u);
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
%1 = OpTypeVector %2 2
%3 = OpTypeInt 32 1
%4 = OpConstant %3 1
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(%5 = OpBitcast %2 %4
%6 = OpBitcast %2 %4
%7 = OpCompositeConstruct %1 %5 %6
)");
}
TEST_F(BuilderTest, Constructor_Type_NonConst_Value_Fails) {
ast::type::F32Type f32;
ast::type::VectorType vec(&f32, 2);
@ -188,7 +225,11 @@ TEST_F(BuilderTest, Constructor_Type_NonConst_Value_Fails) {
ast::TypeConstructorExpression t(&vec, std::move(vals));
Context ctx;
ast::Module mod;
TypeDeterminer td(&ctx, &mod);
EXPECT_TRUE(td.DetermineResultType(&t)) << td.error();
Builder b(&mod);
EXPECT_EQ(b.GenerateConstructorExpression(nullptr, &t, true), 0u);
EXPECT_TRUE(b.has_error());