Converting to Atomic-Free Plain to Constructible

The language in the spec and details of the restriction have changed,
https://github.com/gpuweb/gpuweb/pull/1876.

BUG=tint:928

Change-Id: Ib9f4d5e785bb5e04d63e880fe8984a8683d759f0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/57260
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ryan Harrison
2021-07-07 20:41:00 +00:00
committed by Tint LUCI CQ
parent 26b6edc545
commit 2f258d1bf8
11 changed files with 202 additions and 190 deletions

View File

@@ -230,10 +230,8 @@ TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_RuntimeArray) {
{Stage(ast::PipelineStage::kFragment)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(13:43 error: entry point IO types cannot contain runtime sized arrays
12:34 note: while analysing entry point main)");
EXPECT_EQ(r()->error(),
R"(error: function return type must be a constructible type)");
}
TEST_F(ResolverEntryPointValidationTest, ReturnType_Struct_DuplicateBuiltins) {
@@ -446,8 +444,7 @@ TEST_F(ResolverEntryPointValidationTest, Parameter_Struct_RuntimeArray) {
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
R"(13:43 error: entry point IO types cannot contain runtime sized arrays
12:34 note: while analysing entry point main)");
R"(error: store type of function parameter must be a constructible type)");
}
TEST_F(ResolverEntryPointValidationTest, Parameter_DuplicateBuiltins) {

View File

@@ -479,49 +479,54 @@ TEST_F(ResolverFunctionValidationTest, WorkgroupSize_NonConst) {
"i32 module-scope constant");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsAtomicFreePlain_NonPlain) {
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
auto* ret_type =
ty.pointer(Source{{12, 34}}, ty.i32(), ast::StorageClass::kFunction);
Func("f", {}, ret_type, {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
"12:34 error: function return type must be an atomic-free plain type");
EXPECT_EQ(r()->error(),
"12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsAtomicFreePlain_AtomicInt) {
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_AtomicInt) {
auto* ret_type = ty.atomic(Source{{12, 34}}, ty.i32());
Func("f", {}, ret_type, {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
"12:34 error: function return type must be an atomic-free plain type");
EXPECT_EQ(r()->error(),
"12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsAtomicFreePlain_ArrayOfAtomic) {
auto* ret_type = ty.array(Source{{12, 34}}, ty.atomic(ty.i32()));
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_ArrayOfAtomic) {
auto* ret_type = ty.array(Source{{12, 34}}, ty.atomic(ty.i32()), 10);
Func("f", {}, ret_type, {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
"12:34 error: function return type must be an atomic-free plain type");
EXPECT_EQ(r()->error(),
"12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ReturnIsAtomicFreePlain_StructOfAtomic) {
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_StructOfAtomic) {
Structure("S", {Member("m", ty.atomic(ty.i32()))});
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
Func("f", {}, ret_type, {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
r()->error(),
"12:34 error: function return type must be an atomic-free plain type");
EXPECT_EQ(r()->error(),
"12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ParameterSotreType_NonAtomicFree) {
TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_RuntimeArray) {
auto* ret_type = ty.array(Source{{12, 34}}, ty.i32(), 0);
Func("f", {}, ret_type, {});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: function return type must be a constructible type");
}
TEST_F(ResolverFunctionValidationTest, ParameterStoreType_NonAtomicFree) {
Structure("S", {Member("m", ty.atomic(ty.i32()))});
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
@@ -529,8 +534,8 @@ TEST_F(ResolverFunctionValidationTest, ParameterSotreType_NonAtomicFree) {
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: store type of function parameter must be an "
"atomic-free type");
"12:34 error: store type of function parameter must be a "
"constructible type");
}
TEST_F(ResolverFunctionValidationTest, ParameterSotreType_AtomicFree) {

View File

@@ -193,8 +193,8 @@ bool Resolver::IsPlain(const sem::Type* type) const {
type->Is<sem::Array>() || type->Is<sem::Struct>();
}
// https://gpuweb.github.io/gpuweb/wgsl/#atomic-free
bool Resolver::IsAtomicFreePlain(const sem::Type* type) const {
// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
bool Resolver::IsConstructible(const sem::Type* type) const {
if (type->Is<sem::Atomic>()) {
return false;
}
@@ -204,12 +204,16 @@ bool Resolver::IsAtomicFreePlain(const sem::Type* type) const {
}
if (auto* arr = type->As<sem::Array>()) {
return IsAtomicFreePlain(arr->ElemType());
if (arr->IsRuntimeSized()) {
return false;
}
return IsConstructible(arr->ElemType());
}
if (auto* str = type->As<sem::Struct>()) {
for (auto* m : str->Members()) {
if (!IsAtomicFreePlain(m->Type())) {
if (!IsConstructible(m->Type())) {
return false;
}
}
@@ -944,7 +948,8 @@ bool Resolver::ValidateFunctionParameter(const ast::Function* func,
ast::DisabledValidation::kEntryPointParameter) &&
IsValidationEnabled(
info->declaration->decorations(),
ast::DisabledValidation::kIgnoreAtomicFunctionParameter))) {
ast::DisabledValidation::
kIgnoreConstructibleFunctionParameter))) {
AddError("decoration is not valid for function parameters",
deco->source());
return false;
@@ -965,11 +970,11 @@ bool Resolver::ValidateFunctionParameter(const ast::Function* func,
}
if (IsPlain(info->type)) {
if (!IsAtomicFreePlain(info->type) &&
if (!IsConstructible(info->type) &&
IsValidationEnabled(
info->declaration->decorations(),
ast::DisabledValidation::kIgnoreAtomicFunctionParameter)) {
AddError("store type of function parameter must be an atomic-free type",
ast::DisabledValidation::kIgnoreConstructibleFunctionParameter)) {
AddError("store type of function parameter must be a constructible type",
info->declaration->source());
return false;
}
@@ -1091,8 +1096,8 @@ bool Resolver::ValidateFunction(const ast::Function* func,
}
if (!info->return_type->Is<sem::Void>()) {
if (!IsAtomicFreePlain(info->return_type)) {
AddError("function return type must be an atomic-free plain type",
if (!IsConstructible(info->return_type)) {
AddError("function return type must be a constructible type",
func->return_type()->source());
return false;
}

View File

@@ -81,8 +81,8 @@ class Resolver {
bool IsPlain(const sem::Type* type) const;
/// @param type the given type
/// @returns true if the given type is a atomic-free plain type
bool IsAtomicFreePlain(const sem::Type* type) const;
/// @returns true if the given type is a constructible type
bool IsConstructible(const sem::Type* type) const;
/// @param type the given type
/// @returns true if the given type is storable