From 2287f33424368c2a604b2ab58e316adaaad41a9a Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Tue, 5 May 2020 14:21:19 +0000 Subject: [PATCH] [spirv-writer] Add null initializers where needed. The WGSL spec requires initializers for Output, Private and Function variables. This CL adds initializers where needed. Bug: tint:75 Change-Id: Id97f85a67ead2ffc41d6bdd1b71bf7034b04502a Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20980 Reviewed-by: David Neto --- BUILD.gn | 3 + src/CMakeLists.txt | 3 + src/ast/bool_literal_test.cc | 1 + src/ast/float_literal_test.cc | 1 + src/ast/int_literal_test.cc | 1 + src/ast/literal.cc | 10 + src/ast/literal.h | 5 + src/ast/null_literal.cc | 37 +++ src/ast/null_literal.h | 46 ++++ src/ast/null_literal_test.cc | 51 ++++ src/ast/uint_literal_test.cc | 1 + src/writer/spirv/builder.cc | 26 +- .../spirv/builder_accessor_expression_test.cc | 240 ++++++++++-------- src/writer/spirv/builder_assign_test.cc | 48 ++-- src/writer/spirv/builder_call_test.cc | 19 +- .../spirv/builder_cast_expression_test.cc | 11 +- .../builder_constructor_expression_test.cc | 30 ++- src/writer/spirv/builder_entry_point_test.cc | 9 +- .../spirv/builder_function_variable_test.cc | 10 +- .../spirv/builder_global_variable_test.cc | 30 ++- .../spirv/builder_ident_expression_test.cc | 18 +- src/writer/spirv/builder_if_test.cc | 138 +++++----- src/writer/spirv/builder_loop_test.cc | 42 +-- 23 files changed, 511 insertions(+), 269 deletions(-) create mode 100644 src/ast/null_literal.cc create mode 100644 src/ast/null_literal.h create mode 100644 src/ast/null_literal_test.cc diff --git a/BUILD.gn b/BUILD.gn index 80be5fcbd8..fe75d7bdfc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -268,6 +268,8 @@ source_set("libtint_core_src") { "src/ast/node.h", "src/ast/nop_statement.cc", "src/ast/nop_statement.h", + "src/ast/null_literal.cc", + "src/ast/null_literal.h", "src/ast/pipeline_stage.cc", "src/ast/pipeline_stage.h", "src/ast/return_statement.cc", @@ -598,6 +600,7 @@ source_set("tint_unittests_core_src") { "src/ast/member_accessor_expression_test.cc", "src/ast/module_test.cc", "src/ast/nop_statement_test.cc", + "src/ast/null_literal_test.cc", "src/ast/return_statement_test.cc", "src/ast/scalar_constructor_expression_test.cc", "src/ast/set_decoration_test.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61bc317f5e..c07fdd9458 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,6 +105,8 @@ set(TINT_LIB_SRCS ast/node.h ast/nop_statement.cc ast/nop_statement.h + ast/null_literal.cc + ast/null_literal.h ast/pipeline_stage.cc ast/pipeline_stage.h ast/return_statement.cc @@ -283,6 +285,7 @@ set(TINT_TEST_SRCS ast/member_accessor_expression_test.cc ast/module_test.cc ast/nop_statement_test.cc + ast/null_literal_test.cc ast/binary_expression_test.cc ast/return_statement_test.cc ast/scalar_constructor_expression_test.cc diff --git a/src/ast/bool_literal_test.cc b/src/ast/bool_literal_test.cc index 10697ee7ce..b8dc640056 100644 --- a/src/ast/bool_literal_test.cc +++ b/src/ast/bool_literal_test.cc @@ -46,6 +46,7 @@ TEST_F(BoolLiteralTest, Is) { EXPECT_FALSE(b.IsInt()); EXPECT_FALSE(b.IsFloat()); EXPECT_FALSE(b.IsUint()); + EXPECT_FALSE(b.IsNull()); } TEST_F(BoolLiteralTest, ToStr) { diff --git a/src/ast/float_literal_test.cc b/src/ast/float_literal_test.cc index 6f1101806a..960a7dd42a 100644 --- a/src/ast/float_literal_test.cc +++ b/src/ast/float_literal_test.cc @@ -37,6 +37,7 @@ TEST_F(FloatLiteralTest, Is) { EXPECT_FALSE(f.IsInt()); EXPECT_TRUE(f.IsFloat()); EXPECT_FALSE(f.IsUint()); + EXPECT_FALSE(f.IsNull()); } TEST_F(FloatLiteralTest, ToStr) { diff --git a/src/ast/int_literal_test.cc b/src/ast/int_literal_test.cc index f3f9f81835..9bb2307e65 100644 --- a/src/ast/int_literal_test.cc +++ b/src/ast/int_literal_test.cc @@ -38,6 +38,7 @@ TEST_F(IntLiteralTest, Is) { EXPECT_TRUE(i.IsInt()); EXPECT_FALSE(i.IsFloat()); EXPECT_FALSE(i.IsUint()); + EXPECT_FALSE(i.IsNull()); } TEST_F(IntLiteralTest, ToStr) { diff --git a/src/ast/literal.cc b/src/ast/literal.cc index d8d64c04ed..489a32c671 100644 --- a/src/ast/literal.cc +++ b/src/ast/literal.cc @@ -19,6 +19,7 @@ #include "src/ast/bool_literal.h" #include "src/ast/float_literal.h" #include "src/ast/int_literal.h" +#include "src/ast/null_literal.h" #include "src/ast/uint_literal.h" namespace tint { @@ -40,6 +41,10 @@ bool Literal::IsInt() const { return false; } +bool Literal::IsNull() const { + return false; +} + bool Literal::IsUint() const { return false; } @@ -59,6 +64,11 @@ IntLiteral* Literal::AsInt() { return static_cast(this); } +NullLiteral* Literal::AsNull() { + assert(IsNull()); + return static_cast(this); +} + UintLiteral* Literal::AsUint() { assert(IsUint()); return static_cast(this); diff --git a/src/ast/literal.h b/src/ast/literal.h index f7ae47057d..54079cd29f 100644 --- a/src/ast/literal.h +++ b/src/ast/literal.h @@ -25,6 +25,7 @@ namespace ast { class BoolLiteral; class FloatLiteral; class IntLiteral; +class NullLiteral; class UintLiteral; /// Base class for a literal value @@ -38,6 +39,8 @@ class Literal { virtual bool IsFloat() const; /// @returns true if this is a signed int literal virtual bool IsInt() const; + /// @returns true if this is a null literal + virtual bool IsNull() const; /// @returns true if this is a unsigned int literal virtual bool IsUint() const; @@ -47,6 +50,8 @@ class Literal { FloatLiteral* AsFloat(); /// @returns the literal as a int literal IntLiteral* AsInt(); + /// @returns the literal as a null literal + NullLiteral* AsNull(); /// @returns the literal as a unsigned int literal UintLiteral* AsUint(); diff --git a/src/ast/null_literal.cc b/src/ast/null_literal.cc new file mode 100644 index 0000000000..7d4475199c --- /dev/null +++ b/src/ast/null_literal.cc @@ -0,0 +1,37 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/ast/null_literal.h" + +namespace tint { +namespace ast { + +NullLiteral::NullLiteral(ast::type::Type* type) : Literal(type) {} + +NullLiteral::~NullLiteral() = default; + +bool NullLiteral::IsNull() const { + return true; +} + +std::string NullLiteral::to_str() const { + return "null " + type()->type_name(); +} + +std::string NullLiteral::name() const { + return "__null" + type()->type_name(); +} + +} // namespace ast +} // namespace tint diff --git a/src/ast/null_literal.h b/src/ast/null_literal.h new file mode 100644 index 0000000000..943117dae4 --- /dev/null +++ b/src/ast/null_literal.h @@ -0,0 +1,46 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_AST_NULL_LITERAL_H_ +#define SRC_AST_NULL_LITERAL_H_ + +#include + +#include "src/ast/literal.h" + +namespace tint { +namespace ast { + +/// A null literal +class NullLiteral : public Literal { + public: + /// Constructor + /// @param type the type + NullLiteral(ast::type::Type* type); + ~NullLiteral() override; + + /// @returns true if this is a null literal + bool IsNull() const override; + + /// @returns the name for this literal. This name is unique to this value. + std::string name() const override; + + /// @returns the literal as a string + std::string to_str() const override; +}; + +} // namespace ast +} // namespace tint + +#endif // SRC_AST_NULL_LITERAL_H_ \ No newline at end of file diff --git a/src/ast/null_literal_test.cc b/src/ast/null_literal_test.cc new file mode 100644 index 0000000000..67354f697d --- /dev/null +++ b/src/ast/null_literal_test.cc @@ -0,0 +1,51 @@ +// Copyright 2020 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/ast/null_literal.h" + +#include "gtest/gtest.h" +#include "src/ast/type/i32_type.h" + +namespace tint { +namespace ast { +namespace { + +using NullLiteralTest = testing::Test; + +TEST_F(NullLiteralTest, Is) { + ast::type::I32Type i32; + NullLiteral i{&i32}; + EXPECT_FALSE(i.IsBool()); + EXPECT_FALSE(i.IsInt()); + EXPECT_FALSE(i.IsFloat()); + EXPECT_FALSE(i.IsUint()); + EXPECT_TRUE(i.IsNull()); +} + +TEST_F(NullLiteralTest, ToStr) { + ast::type::I32Type i32; + NullLiteral i{&i32}; + + EXPECT_EQ(i.to_str(), "null __i32"); +} + +TEST_F(NullLiteralTest, Name_I32) { + ast::type::I32Type i32; + NullLiteral i{&i32}; + EXPECT_EQ("__null__i32", i.name()); +} + +} // namespace +} // namespace ast +} // namespace tint \ No newline at end of file diff --git a/src/ast/uint_literal_test.cc b/src/ast/uint_literal_test.cc index a1402b3c44..841ad2253d 100644 --- a/src/ast/uint_literal_test.cc +++ b/src/ast/uint_literal_test.cc @@ -37,6 +37,7 @@ TEST_F(UintLiteralTest, Is) { EXPECT_FALSE(u.IsInt()); EXPECT_FALSE(u.IsFloat()); EXPECT_TRUE(u.IsUint()); + EXPECT_FALSE(u.IsNull()); } TEST_F(UintLiteralTest, ToStr) { diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 1bfb0ad5e2..9c1094d8ed 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -36,6 +36,7 @@ #include "src/ast/location_decoration.h" #include "src/ast/loop_statement.h" #include "src/ast/member_accessor_expression.h" +#include "src/ast/null_literal.h" #include "src/ast/return_statement.h" #include "src/ast/scalar_constructor_expression.h" #include "src/ast/set_decoration.h" @@ -430,9 +431,15 @@ bool Builder::GenerateFunctionVariable(ast::Variable* var) { // TODO(dsinclair) We could detect if the constructor is fully const and emit // an initializer value for the variable instead of doing the OpLoad. + ast::NullLiteral nl(var->type()->UnwrapPtrIfNeeded()); + auto null_id = GenerateLiteralIfNeeded(&nl); + if (null_id == 0) { + return 0; + } + push_function_var({Operand::Int(type_id), result, + Operand::Int(ConvertStorageClass(sc)), + Operand::Int(null_id)}); - push_function_var( - {Operand::Int(type_id), result, Operand::Int(ConvertStorageClass(sc))}); if (var->has_constructor()) { init_id = GenerateLoadIfNeeded(var->constructor()->result_type(), init_id); GenerateStore(var_id, init_id); @@ -493,6 +500,19 @@ bool Builder::GenerateGlobalVariable(ast::Variable* var) { Operand::Int(ConvertStorageClass(sc))}; if (var->has_constructor()) { ops.push_back(Operand::Int(init_id)); + } else { + // If we don't have a constructor and we're an Output or Private variable + // then WGSL requires an initializer. + if (var->storage_class() == ast::StorageClass::kPrivate || + var->storage_class() == ast::StorageClass::kNone || + var->storage_class() == ast::StorageClass::kOutput) { + ast::NullLiteral nl(var->type()->UnwrapPtrIfNeeded()); + init_id = GenerateLiteralIfNeeded(&nl); + if (init_id == 0) { + return 0; + } + ops.push_back(Operand::Int(init_id)); + } } push_type(spv::Op::OpVariable, std::move(ops)); @@ -965,6 +985,8 @@ uint32_t Builder::GenerateLiteralIfNeeded(ast::Literal* lit) { } else if (lit->IsFloat()) { push_type(spv::Op::OpConstant, {Operand::Int(type_id), result, Operand::Float(lit->AsFloat()->value())}); + } else if (lit->IsNull()) { + push_type(spv::Op::OpConstantNull, {Operand::Int(type_id), result}); } else { error_ = "unknown literal type"; return 0; diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc index 182110fd23..d96554e75f 100644 --- a/src/writer/spirv/builder_accessor_expression_test.cc +++ b/src/writer/spirv/builder_accessor_expression_test.cc @@ -68,20 +68,21 @@ TEST_F(BuilderTest, ArrayAccessor) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%5 = OpTypeInt 32 1 -%6 = OpConstant %5 1 -%7 = OpTypePointer Function %4 +%5 = OpConstantNull %3 +%6 = OpTypeInt 32 1 +%7 = OpConstant %6 1 +%8 = OpTypePointer Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpAccessChain %7 %1 %6 + R"(%9 = OpAccessChain %8 %1 %7 )"); } @@ -114,22 +115,24 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) { ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(&idx)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 12u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%7 = OpTypeInt 32 1 -%6 = OpTypePointer Function %7 -%9 = OpTypePointer Function %4 +%5 = OpConstantNull %3 +%8 = OpTypeInt 32 1 +%7 = OpTypePointer Function %8 +%9 = OpConstantNull %8 +%11 = OpTypePointer Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function -%5 = OpVariable %6 Function + R"(%1 = OpVariable %2 Function %5 +%6 = OpVariable %7 Function %9 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpLoad %7 %5 -%10 = OpAccessChain %9 %1 %8 + R"(%10 = OpLoad %8 %6 +%12 = OpAccessChain %11 %1 %10 )"); } @@ -163,22 +166,23 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 11u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%5 = OpTypeInt 32 1 -%6 = OpConstant %5 1 -%7 = OpConstant %5 2 -%9 = OpTypePointer Function %4 +%5 = OpConstantNull %3 +%6 = OpTypeInt 32 1 +%7 = OpConstant %6 1 +%8 = OpConstant %6 2 +%10 = OpTypePointer Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpIAdd %5 %6 %7 -%10 = OpAccessChain %9 %1 %8 + R"(%9 = OpIAdd %6 %7 %8 +%11 = OpAccessChain %10 %1 %9 )"); } @@ -211,7 +215,7 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 12u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 13u); EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 %4 = OpTypeVector %5 3 @@ -219,16 +223,17 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) { %7 = OpConstant %6 4 %3 = OpTypeArray %4 %7 %2 = OpTypePointer Function %3 -%8 = OpTypeInt 32 1 -%9 = OpConstant %8 3 -%10 = OpConstant %8 2 -%11 = OpTypePointer Function %5 +%8 = OpConstantNull %3 +%9 = OpTypeInt 32 1 +%10 = OpConstant %9 3 +%11 = OpConstant %9 2 +%12 = OpTypePointer Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %8 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%12 = OpAccessChain %11 %1 %9 %10 + R"(%13 = OpAccessChain %12 %1 %10 %11 )"); } @@ -259,7 +264,7 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) { Builder b(&mod); b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 14u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 15u); EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 %4 = OpTypeVector %5 3 @@ -267,18 +272,19 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) { %7 = OpConstant %6 4 %3 = OpTypeArray %4 %7 %2 = OpTypePointer Function %3 -%8 = OpTypeInt 32 1 -%9 = OpConstant %8 2 -%10 = OpTypePointer Function %4 -%12 = OpTypeVector %5 2 +%8 = OpConstantNull %3 +%9 = OpTypeInt 32 1 +%10 = OpConstant %9 2 +%11 = OpTypePointer Function %4 +%13 = OpTypeVector %5 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %8 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%11 = OpAccessChain %10 %1 %9 -%13 = OpLoad %4 %11 -%14 = OpVectorShuffle %12 %13 %13 0 1 + R"(%12 = OpAccessChain %11 %1 %10 +%14 = OpLoad %4 %12 +%15 = OpVectorShuffle %13 %14 %14 0 1 )"); } @@ -320,20 +326,21 @@ TEST_F(BuilderTest, MemberAccessor) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeStruct %4 %4 %2 = OpTypePointer Function %3 -%5 = OpTypeInt 32 0 -%6 = OpConstant %5 1 -%7 = OpTypePointer Function %4 +%5 = OpConstantNull %3 +%6 = OpTypeInt 32 0 +%7 = OpConstant %6 1 +%8 = OpTypePointer Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpAccessChain %7 %1 %6 + R"(%9 = OpAccessChain %8 %1 %7 )"); } @@ -385,21 +392,22 @@ TEST_F(BuilderTest, MemberAccessor_Nested) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 %4 = OpTypeStruct %5 %5 %3 = OpTypeStruct %4 %2 = OpTypePointer Function %3 -%6 = OpTypeInt 32 0 -%7 = OpConstant %6 0 -%8 = OpTypePointer Function %5 +%6 = OpConstantNull %3 +%7 = OpTypeInt 32 0 +%8 = OpConstant %7 0 +%9 = OpTypePointer Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %6 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%9 = OpAccessChain %8 %1 %7 %7 + R"(%10 = OpAccessChain %9 %1 %8 %8 )"); } @@ -454,21 +462,22 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 %4 = OpTypeStruct %5 %5 %3 = OpTypeStruct %4 %2 = OpTypePointer Function %3 -%6 = OpTypeInt 32 0 -%7 = OpConstant %6 0 -%8 = OpTypePointer Function %5 +%6 = OpConstantNull %3 +%7 = OpTypeInt 32 0 +%8 = OpConstant %7 0 +%9 = OpTypePointer Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %6 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%9 = OpAccessChain %8 %1 %7 %7 + R"(%10 = OpAccessChain %9 %1 %8 %8 )"); } @@ -532,17 +541,18 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) { %4 = OpTypeStruct %5 %5 %3 = OpTypeStruct %4 %2 = OpTypePointer Function %3 -%6 = OpTypeInt 32 0 -%7 = OpConstant %6 0 -%8 = OpTypePointer Function %5 -%10 = OpConstant %5 2 +%6 = OpConstantNull %3 +%7 = OpTypeInt 32 0 +%8 = OpConstant %7 0 +%9 = OpTypePointer Function %5 +%11 = OpConstant %5 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %6 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%9 = OpAccessChain %8 %1 %7 %7 -OpStore %9 %10 + R"(%10 = OpAccessChain %9 %1 %8 %8 +OpStore %10 %11 )"); } @@ -608,18 +618,20 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) { %4 = OpTypeStruct %5 %5 %3 = OpTypeStruct %4 %2 = OpTypePointer Function %3 -%7 = OpTypePointer Function %5 -%8 = OpTypeInt 32 0 -%9 = OpConstant %8 0 +%6 = OpConstantNull %3 +%8 = OpTypePointer Function %5 +%9 = OpConstantNull %5 +%10 = OpTypeInt 32 0 +%11 = OpConstant %10 0 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function -%6 = OpVariable %7 Function + R"(%1 = OpVariable %2 Function %6 +%7 = OpVariable %8 Function %9 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%10 = OpAccessChain %7 %1 %9 %9 -%11 = OpLoad %5 %10 -OpStore %6 %11 + R"(%12 = OpAccessChain %8 %1 %11 %11 +%13 = OpLoad %5 %12 +OpStore %7 %13 )"); } @@ -645,20 +657,21 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%5 = OpTypeInt 32 0 -%6 = OpConstant %5 1 -%7 = OpTypePointer Function %4 +%5 = OpConstantNull %3 +%6 = OpTypeInt 32 0 +%7 = OpConstant %6 1 +%8 = OpTypePointer Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpAccessChain %7 %1 %6 + R"(%9 = OpAccessChain %8 %1 %7 )"); } @@ -684,19 +697,20 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 7u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%5 = OpTypeVector %4 2 +%5 = OpConstantNull %3 +%6 = OpTypeVector %4 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%6 = OpLoad %3 %1 -%7 = OpVectorShuffle %5 %6 %6 1 0 + R"(%7 = OpLoad %3 %1 +%8 = OpVectorShuffle %6 %7 %7 1 0 )"); } @@ -724,20 +738,21 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%7 = OpTypeVector %4 2 +%5 = OpConstantNull %3 +%8 = OpTypeVector %4 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%5 = OpLoad %3 %1 -%6 = OpVectorShuffle %3 %5 %5 1 0 2 -%8 = OpVectorShuffle %7 %6 %6 0 2 + R"(%6 = OpLoad %3 %1 +%7 = OpVectorShuffle %3 %6 %6 1 0 2 +%9 = OpVectorShuffle %8 %7 %7 0 2 )"); } @@ -765,19 +780,20 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 7u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 +%5 = OpConstantNull %3 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%5 = OpLoad %3 %1 -%6 = OpVectorShuffle %3 %5 %5 1 0 2 -%7 = OpCompositeExtract %4 %6 0 + R"(%6 = OpLoad %3 %1 +%7 = OpVectorShuffle %3 %6 %6 1 0 2 +%8 = OpCompositeExtract %4 %7 0 )"); } @@ -807,21 +823,22 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Function %3 -%7 = OpTypeInt 32 1 -%8 = OpConstant %7 1 +%5 = OpConstantNull %3 +%8 = OpTypeInt 32 1 +%9 = OpConstant %8 1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%5 = OpLoad %3 %1 -%6 = OpVectorShuffle %3 %5 %5 1 0 2 -%9 = OpVectorExtractDynamic %4 %6 %8 + R"(%6 = OpLoad %3 %1 +%7 = OpVectorShuffle %3 %6 %6 1 0 2 +%10 = OpVectorExtractDynamic %4 %7 %9 )"); } @@ -897,7 +914,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateAccessorExpression(&expr), 21u); + EXPECT_EQ(b.GenerateAccessorExpression(&expr), 22u); EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeFloat 32 %8 = OpTypeVector %9 3 @@ -910,20 +927,21 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) { %12 = OpConstant %10 2 %3 = OpTypeArray %4 %12 %2 = OpTypePointer Function %3 -%13 = OpTypeInt 32 1 -%14 = OpConstant %13 0 -%15 = OpConstant %10 0 -%16 = OpConstant %13 2 -%17 = OpTypePointer Function %8 -%19 = OpTypeVector %9 2 +%13 = OpConstantNull %3 +%14 = OpTypeInt 32 1 +%15 = OpConstant %14 0 +%16 = OpConstant %10 0 +%17 = OpConstant %14 2 +%18 = OpTypePointer Function %8 +%20 = OpTypeVector %9 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %13 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%18 = OpAccessChain %17 %1 %14 %15 %16 %15 %15 -%20 = OpLoad %8 %18 -%21 = OpVectorShuffle %19 %20 %20 1 0 + R"(%19 = OpAccessChain %18 %1 %15 %16 %17 %16 %16 +%21 = OpLoad %8 %19 +%22 = OpVectorShuffle %20 %21 %21 1 0 )"); } diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc index 7847d065b6..3c5467780d 100644 --- a/src/writer/spirv/builder_assign_test.cc +++ b/src/writer/spirv/builder_assign_test.cc @@ -69,11 +69,12 @@ TEST_F(BuilderTest, Assign_Var) { EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output -%4 = OpConstant %3 1 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 +%5 = OpConstant %3 1 )"); - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %4 + EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %5 )"); } @@ -180,13 +181,14 @@ TEST_F(BuilderTest, Assign_Vector) { EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output -%5 = OpConstant %4 1 -%6 = OpConstant %4 3 -%7 = OpConstantComposite %3 %5 %5 %6 +%5 = OpConstantNull %3 +%1 = OpVariable %2 Output %5 +%6 = OpConstant %4 1 +%7 = OpConstant %4 3 +%8 = OpConstantComposite %3 %6 %6 %7 )"); - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %7 + EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %1 %8 )"); } @@ -224,16 +226,17 @@ TEST_F(BuilderTest, Assign_Vector_MemberByName) { EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output -%5 = OpTypeInt 32 0 -%6 = OpConstant %5 1 -%7 = OpTypePointer Output %4 -%9 = OpConstant %4 1 +%5 = OpConstantNull %3 +%1 = OpVariable %2 Output %5 +%6 = OpTypeInt 32 0 +%7 = OpConstant %6 1 +%8 = OpTypePointer Output %4 +%10 = OpConstant %4 1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpAccessChain %7 %1 %6 -OpStore %8 %9 + R"(%9 = OpAccessChain %8 %1 %7 +OpStore %9 %10 )"); } @@ -273,16 +276,17 @@ TEST_F(BuilderTest, Assign_Vector_MemberByIndex) { EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output -%5 = OpTypeInt 32 1 -%6 = OpConstant %5 1 -%7 = OpTypePointer Output %4 -%9 = OpConstant %4 1 +%5 = OpConstantNull %3 +%1 = OpVariable %2 Output %5 +%6 = OpTypeInt 32 1 +%7 = OpConstant %6 1 +%8 = OpTypePointer Output %4 +%10 = OpConstant %4 1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%8 = OpAccessChain %7 %1 %6 -OpStore %8 %9 + R"(%9 = OpAccessChain %8 %1 %7 +OpStore %9 %10 )"); } diff --git a/src/writer/spirv/builder_call_test.cc b/src/writer/spirv/builder_call_test.cc index ea4dd9533a..d9aaef2114 100644 --- a/src/writer/spirv/builder_call_test.cc +++ b/src/writer/spirv/builder_call_test.cc @@ -107,19 +107,20 @@ TEST_F(BuilderTest, Call_GLSLMethod_WithLoad) { ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error(); ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); - EXPECT_EQ(b.GenerateCallExpression(&expr), 9u) << b.error(); + EXPECT_EQ(b.GenerateCallExpression(&expr), 10u) << b.error(); EXPECT_EQ(DumpBuilder(b), R"(%1 = OpExtInstImport "GLSL.std.450" OpName %2 "ident" -OpName %7 "a_func" +OpName %8 "a_func" %4 = OpTypeFloat 32 %3 = OpTypePointer Private %4 -%2 = OpVariable %3 Private -%6 = OpTypeVoid -%5 = OpTypeFunction %6 -%7 = OpFunction %6 None %5 -%8 = OpLabel -%10 = OpLoad %4 %2 -%9 = OpExtInst %4 %1 Round %10 +%5 = OpConstantNull %4 +%2 = OpVariable %3 Private %5 +%7 = OpTypeVoid +%6 = OpTypeFunction %7 +%8 = OpFunction %7 None %6 +%9 = OpLabel +%11 = OpLoad %4 %2 +%10 = OpExtInst %4 %1 Round %11 OpFunctionEnd )"); } diff --git a/src/writer/spirv/builder_cast_expression_test.cc b/src/writer/spirv/builder_cast_expression_test.cc index 90ca156542..c6b6fcb88d 100644 --- a/src/writer/spirv/builder_cast_expression_test.cc +++ b/src/writer/spirv/builder_cast_expression_test.cc @@ -86,16 +86,17 @@ TEST_F(BuilderTest, Cast_WithLoad) { Builder b(&mod); b.push_function(Function{}); ASSERT_TRUE(b.GenerateGlobalVariable(var.get())) << b.error(); - EXPECT_EQ(b.GenerateCastExpression(&cast), 4u) << b.error(); + EXPECT_EQ(b.GenerateCastExpression(&cast), 5u) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%5 = OpTypeFloat 32 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%6 = OpTypeFloat 32 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%6 = OpLoad %3 %1 -%4 = OpConvertSToF %5 %6 + R"(%7 = OpLoad %3 %1 +%5 = OpConvertSToF %6 %7 )"); } diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc index b7af4c88f7..df0c21905e 100644 --- a/src/writer/spirv/builder_constructor_expression_test.cc +++ b/src/writer/spirv/builder_constructor_expression_test.cc @@ -106,21 +106,22 @@ TEST_F(BuilderTest, Constructor_Type_NonConstructorParam) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(var.get())) << b.error(); - EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 7u); + EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 8u); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Function %3 -%4 = OpTypeVector %3 2 -%5 = OpConstant %3 1 +%4 = OpConstantNull %3 +%5 = OpTypeVector %3 2 +%6 = OpConstant %3 1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%6 = OpLoad %3 %1 -%7 = OpCompositeConstruct %4 %5 %6 + R"(%7 = OpLoad %3 %1 +%8 = OpCompositeConstruct %5 %6 %7 )"); } @@ -151,24 +152,25 @@ TEST_F(BuilderTest, Constructor_Type_NonConstVector) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateFunctionVariable(var.get())) << b.error(); - EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 10u); + EXPECT_EQ(b.GenerateConstructorExpression(&t, false), 11u); ASSERT_FALSE(b.has_error()) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 %3 = OpTypeVector %4 2 %2 = OpTypePointer Function %3 -%5 = OpTypeVector %4 4 -%6 = OpConstant %4 1 +%5 = OpConstantNull %3 +%6 = OpTypeVector %4 4 +%7 = OpConstant %4 1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%1 = OpVariable %2 Function + R"(%1 = OpVariable %2 Function %5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%8 = OpCompositeExtract %4 %7 0 -%9 = OpCompositeExtract %4 %7 1 -%10 = OpCompositeConstruct %5 %6 %6 %8 %9 + R"(%8 = OpLoad %3 %1 +%9 = OpCompositeExtract %4 %8 0 +%10 = OpCompositeExtract %4 %8 1 +%11 = OpCompositeConstruct %6 %7 %7 %9 %10 )"); } diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc index 2c4a71bafc..ae55071b25 100644 --- a/src/writer/spirv/builder_entry_point_test.cc +++ b/src/writer/spirv/builder_entry_point_test.cc @@ -129,15 +129,16 @@ TEST_F(BuilderTest, EntryPoint_WithInterfaceIds) { ASSERT_TRUE(b.GenerateEntryPoint(&ep)); EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in" OpName %4 "my_out" -OpName %6 "my_wg" +OpName %7 "my_wg" )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Input %3 %1 = OpVariable %2 Input %5 = OpTypePointer Output %3 -%4 = OpVariable %5 Output -%7 = OpTypePointer Workgroup %3 -%6 = OpVariable %7 Workgroup +%6 = OpConstantNull %3 +%4 = OpVariable %5 Output %6 +%8 = OpTypePointer Workgroup %3 +%7 = OpVariable %8 Workgroup )"); EXPECT_EQ(DumpInstructions(b.preamble()), R"(OpEntryPoint Vertex %3 "main" %1 %4 diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc index 0917616671..e462ce1601 100644 --- a/src/writer/spirv/builder_function_variable_test.cc +++ b/src/writer/spirv/builder_function_variable_test.cc @@ -54,10 +54,12 @@ TEST_F(BuilderTest, FunctionVar_NoStorageClass) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Function %3 +%4 = OpConstantNull %3 )"); const auto& func = b.functions()[0]; - EXPECT_EQ(DumpInstructions(func.variables()), R"(%1 = OpVariable %2 Function + EXPECT_EQ(DumpInstructions(func.variables()), + R"(%1 = OpVariable %2 Function %4 )"); } @@ -99,9 +101,10 @@ TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) { %4 = OpConstant %2 3 %5 = OpConstantComposite %1 %3 %3 %4 %7 = OpTypePointer Function %2 +%8 = OpConstantNull %2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%6 = OpVariable %7 Function + R"(%6 = OpVariable %7 Function %8 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %6 %5 )"); @@ -147,9 +150,10 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) { %3 = OpConstant %2 1 %4 = OpConstant %2 3 %8 = OpTypePointer Function %1 +%9 = OpConstantNull %1 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), - R"(%7 = OpVariable %8 Function + R"(%7 = OpVariable %8 Function %9 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%5 = OpFAdd %2 %4 %4 diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc index dd40711b6a..306d2d6f49 100644 --- a/src/writer/spirv/builder_global_variable_test.cc +++ b/src/writer/spirv/builder_global_variable_test.cc @@ -52,7 +52,8 @@ TEST_F(BuilderTest, GlobalVar_NoStorageClass) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 )"); } @@ -67,7 +68,23 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 +)"); +} + +TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) { + ast::type::F32Type f32; + ast::Variable v("var", ast::StorageClass::kInput, &f32); + + ast::Module mod; + Builder b(&mod); + EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); + EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" +)"); + EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 +%2 = OpTypePointer Input %3 +%1 = OpVariable %2 Input )"); } @@ -167,7 +184,8 @@ TEST_F(BuilderTest, GlobalVar_WithLocation) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 )"); } @@ -192,7 +210,8 @@ OpDecorate %1 DescriptorSet 3 )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 )"); } @@ -216,7 +235,8 @@ TEST_F(BuilderTest, GlobalVar_WithBuiltin) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 )"); } diff --git a/src/writer/spirv/builder_ident_expression_test.cc b/src/writer/spirv/builder_ident_expression_test.cc index 5fb39b59d7..c48133092a 100644 --- a/src/writer/spirv/builder_ident_expression_test.cc +++ b/src/writer/spirv/builder_ident_expression_test.cc @@ -96,7 +96,8 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalVar) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Output %3 -%1 = OpVariable %2 Output +%4 = OpConstantNull %3 +%1 = OpVariable %2 Output %4 )"); ast::IdentifierExpression expr("var"); @@ -161,10 +162,12 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) { )"); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 %2 = OpTypePointer Function %3 +%4 = OpConstantNull %3 )"); const auto& func = b.functions()[0]; - EXPECT_EQ(DumpInstructions(func.variables()), R"(%1 = OpVariable %2 Function + EXPECT_EQ(DumpInstructions(func.variables()), + R"(%1 = OpVariable %2 Function %4 )"); ast::IdentifierExpression expr("var"); @@ -195,15 +198,16 @@ TEST_F(BuilderTest, IdentifierExpression_Load) { b.push_function(Function{}); ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error(); - EXPECT_EQ(b.GenerateBinaryExpression(&expr), 6u) << b.error(); + EXPECT_EQ(b.GenerateBinaryExpression(&expr), 7u) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%4 = OpLoad %3 %1 -%5 = OpLoad %3 %1 -%6 = OpIAdd %3 %4 %5 + R"(%5 = OpLoad %3 %1 +%6 = OpLoad %3 %1 +%7 = OpIAdd %3 %5 %6 )"); } diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc index dbe1dc4e4c..b41d1e05ed 100644 --- a/src/writer/spirv/builder_if_test.cc +++ b/src/writer/spirv/builder_if_test.cc @@ -107,18 +107,19 @@ TEST_F(BuilderTest, If_WithStatements) { EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%4 = OpTypeBool -%5 = OpConstantTrue %4 -%8 = OpConstant %3 2 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%5 = OpTypeBool +%6 = OpConstantTrue %5 +%9 = OpConstant %3 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpSelectionMerge %6 None -OpBranchConditional %5 %7 %6 + R"(OpSelectionMerge %7 None +OpBranchConditional %6 %8 %7 +%8 = OpLabel +OpStore %1 %9 +OpBranch %7 %7 = OpLabel -OpStore %1 %8 -OpBranch %6 -%6 = OpLabel )"); } @@ -170,22 +171,23 @@ TEST_F(BuilderTest, If_WithElse) { EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%4 = OpTypeBool -%5 = OpConstantTrue %4 -%9 = OpConstant %3 2 -%10 = OpConstant %3 3 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%5 = OpTypeBool +%6 = OpConstantTrue %5 +%10 = OpConstant %3 2 +%11 = OpConstant %3 3 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpSelectionMerge %6 None -OpBranchConditional %5 %7 %8 -%7 = OpLabel -OpStore %1 %9 -OpBranch %6 + R"(OpSelectionMerge %7 None +OpBranchConditional %6 %8 %9 %8 = OpLabel OpStore %1 %10 -OpBranch %6 -%6 = OpLabel +OpBranch %7 +%9 = OpLabel +OpStore %1 %11 +OpBranch %7 +%7 = OpLabel )"); } @@ -240,27 +242,28 @@ TEST_F(BuilderTest, If_WithElseIf) { EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%4 = OpTypeBool -%5 = OpConstantTrue %4 -%9 = OpConstant %3 2 -%12 = OpConstant %3 3 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%5 = OpTypeBool +%6 = OpConstantTrue %5 +%10 = OpConstant %3 2 +%13 = OpConstant %3 3 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpSelectionMerge %6 None -OpBranchConditional %5 %7 %8 -%7 = OpLabel -OpStore %1 %9 -OpBranch %6 + R"(OpSelectionMerge %7 None +OpBranchConditional %6 %8 %9 %8 = OpLabel -OpSelectionMerge %10 None -OpBranchConditional %5 %11 %10 +OpStore %1 %10 +OpBranch %7 +%9 = OpLabel +OpSelectionMerge %11 None +OpBranchConditional %6 %12 %11 +%12 = OpLabel +OpStore %1 %13 +OpBranch %11 %11 = OpLabel -OpStore %1 %12 -OpBranch %10 -%10 = OpLabel -OpBranch %6 -%6 = OpLabel +OpBranch %7 +%7 = OpLabel )"); } @@ -334,41 +337,42 @@ TEST_F(BuilderTest, If_WithMultiple) { EXPECT_TRUE(b.GenerateIfStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%4 = OpTypeBool -%5 = OpConstantTrue %4 -%9 = OpConstant %3 2 -%13 = OpConstant %3 3 -%14 = OpConstantFalse %4 -%18 = OpConstant %3 4 -%19 = OpConstant %3 5 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%5 = OpTypeBool +%6 = OpConstantTrue %5 +%10 = OpConstant %3 2 +%14 = OpConstant %3 3 +%15 = OpConstantFalse %5 +%19 = OpConstant %3 4 +%20 = OpConstant %3 5 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpSelectionMerge %6 None -OpBranchConditional %5 %7 %8 -%7 = OpLabel -OpStore %1 %9 -OpBranch %6 + R"(OpSelectionMerge %7 None +OpBranchConditional %6 %8 %9 %8 = OpLabel -OpSelectionMerge %10 None -OpBranchConditional %5 %11 %12 -%11 = OpLabel -OpStore %1 %13 -OpBranch %10 +OpStore %1 %10 +OpBranch %7 +%9 = OpLabel +OpSelectionMerge %11 None +OpBranchConditional %6 %12 %13 %12 = OpLabel -OpSelectionMerge %15 None -OpBranchConditional %14 %16 %17 -%16 = OpLabel -OpStore %1 %18 -OpBranch %15 +OpStore %1 %14 +OpBranch %11 +%13 = OpLabel +OpSelectionMerge %16 None +OpBranchConditional %15 %17 %18 %17 = OpLabel OpStore %1 %19 -OpBranch %15 -%15 = OpLabel -OpBranch %10 -%10 = OpLabel -OpBranch %6 -%6 = OpLabel +OpBranch %16 +%18 = OpLabel +OpStore %1 %20 +OpBranch %16 +%16 = OpLabel +OpBranch %11 +%11 = OpLabel +OpBranch %7 +%7 = OpLabel )"); } diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc index 6333fad522..0b59ac3da3 100644 --- a/src/writer/spirv/builder_loop_test.cc +++ b/src/writer/spirv/builder_loop_test.cc @@ -94,20 +94,21 @@ TEST_F(BuilderTest, Loop_WithoutContinuing) { EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%8 = OpConstant %3 2 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%9 = OpConstant %3 2 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpBranch %4 -%4 = OpLabel -OpLoopMerge %5 %6 None + R"(OpBranch %5 +%5 = OpLabel +OpLoopMerge %6 %7 None +OpBranch %8 +%8 = OpLabel +OpStore %1 %9 OpBranch %7 %7 = OpLabel -OpStore %1 %8 -OpBranch %6 +OpBranch %5 %6 = OpLabel -OpBranch %4 -%5 = OpLabel )"); } @@ -149,22 +150,23 @@ TEST_F(BuilderTest, Loop_WithContinuing) { EXPECT_TRUE(b.GenerateLoopStatement(&expr)) << b.error(); EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 %2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%8 = OpConstant %3 2 -%9 = OpConstant %3 3 +%4 = OpConstantNull %3 +%1 = OpVariable %2 Private %4 +%9 = OpConstant %3 2 +%10 = OpConstant %3 3 )"); EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(OpBranch %4 -%4 = OpLabel -OpLoopMerge %5 %6 None + R"(OpBranch %5 +%5 = OpLabel +OpLoopMerge %6 %7 None +OpBranch %8 +%8 = OpLabel +OpStore %1 %9 OpBranch %7 %7 = OpLabel -OpStore %1 %8 -OpBranch %6 +OpStore %1 %10 +OpBranch %5 %6 = OpLabel -OpStore %1 %9 -OpBranch %4 -%5 = OpLabel )"); }