[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:
parent
c9110b93cb
commit
a388d56d99
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue