[tint][ir][val] Reject IR with abstract values
Abstract values should be removed at the resolve stage before IR is
generated, so should not be present when validating IR.
Fixes: 388286932
Change-Id: I0fec91d1a11ca0ec848234a15d77faf08b15bb57
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/221474
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 45b19fe..fee5529 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -78,7 +78,6 @@
#include "src/tint/lang/core/ir/unused.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/var.h"
-#include "src/tint/lang/core/type/abstract_int.h"
#include "src/tint/lang/core/type/array.h"
#include "src/tint/lang/core/type/bool.h"
#include "src/tint/lang/core/type/f16.h"
@@ -1762,6 +1761,11 @@
}
auto visit = [&](const core::type::Type* type) {
+ if (type->IsAbstract()) {
+ diag() << "abstracts are not permitted";
+ return false;
+ }
+
return tint::Switch(
type,
[&](const core::type::Reference* ref) {
@@ -2697,11 +2701,6 @@
if (result_type->Is<core::type::F16>()) {
return;
}
- } else if (val_type->Is<core::type::AbstractInt>()) {
- // AbstractInt -> u32
- if (result_type->Is<core::type::U32>()) {
- return;
- }
} else if (val_type->Is<core::type::Vector>()) {
auto val_elements = val_type->Elements();
if (!val_elements.type) {
@@ -2758,12 +2757,6 @@
return;
}
}
- } else if (val_elements.type->Is<core::type::AbstractInt>()) {
- // vecN<AbstractInt> -> vecN<u32>
- if (result_elements.has_value() && val_elements.count == result_elements->count &&
- result_elements->type->Is<core::type::U32>()) {
- return;
- }
}
}
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index f69f987..5490d83 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -40,6 +40,8 @@
#include "src/tint/lang/core/ir/validator.h"
#include "src/tint/lang/core/number.h"
#include "src/tint/lang/core/texel_format.h"
+#include "src/tint/lang/core/type/abstract_float.h"
+#include "src/tint/lang/core/type/abstract_int.h"
#include "src/tint/lang/core/type/manager.h"
#include "src/tint/lang/core/type/matrix.h"
#include "src/tint/lang/core/type/memory_view.h"
@@ -251,6 +253,179 @@
)");
}
+TEST_F(IR_ValidatorTest, Abstract_Scalar) {
+ auto* f = b.Function("my_func", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Var("af", function, ty.AFloat());
+ b.Var("af", function, ty.AInt());
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:3:5 error: var: abstracts are not permitted
+ %af:ptr<function, abstract-float, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+:4:5 error: var: abstracts are not permitted
+ %af_1:ptr<function, abstract-int, read_write> = var # %af_1: 'af'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%my_func = func():void {
+ $B1: {
+ %af:ptr<function, abstract-float, read_write> = var
+ %af_1:ptr<function, abstract-int, read_write> = var # %af_1: 'af'
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, Abstract_Vector) {
+ auto* f = b.Function("my_func", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Var("af", function, ty.vec2<AFloat>());
+ b.Var("ai", function, ty.vec3<AInt>());
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:3:5 error: var: abstracts are not permitted
+ %af:ptr<function, vec2<abstract-float>, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+:4:5 error: var: abstracts are not permitted
+ %ai:ptr<function, vec3<abstract-int>, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%my_func = func():void {
+ $B1: {
+ %af:ptr<function, vec2<abstract-float>, read_write> = var
+ %ai:ptr<function, vec3<abstract-int>, read_write> = var
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, Abstract_Matrix) {
+ auto* f = b.Function("my_func", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Var("af", function, ty.mat2x2<AFloat>());
+ b.Var("ai", function, ty.mat3x4<AInt>());
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:3:5 error: var: abstracts are not permitted
+ %af:ptr<function, mat2x2<abstract-float>, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+:4:5 error: var: abstracts are not permitted
+ %ai:ptr<function, mat3x4<abstract-int>, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:2:3 note: in block
+ $B1: {
+ ^^^
+
+note: # Disassembly
+%my_func = func():void {
+ $B1: {
+ %af:ptr<function, mat2x2<abstract-float>, read_write> = var
+ %ai:ptr<function, mat3x4<abstract-int>, read_write> = var
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, Abstract_Struct) {
+ auto* str_ty =
+ ty.Struct(mod.symbols.New("MyStruct"), {
+ {mod.symbols.New("af"), ty.AFloat(), {}},
+ {mod.symbols.New("ai"), ty.AInt(), {}},
+ });
+ auto* v = b.Var(ty.ptr(private_, str_ty));
+ mod.root_block->Append(v);
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:7:3 error: var: abstracts are not permitted
+ %1:ptr<private, MyStruct, read_write> = var
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:6:1 note: in block
+$B1: { # root
+^^^
+
+note: # Disassembly
+MyStruct = struct @align(1) {
+ af:abstract-float @offset(0)
+ ai:abstract-int @offset(0)
+}
+
+$B1: { # root
+ %1:ptr<private, MyStruct, read_write> = var
+}
+
+)");
+}
+
+TEST_F(IR_ValidatorTest, Abstract_FunctionParam) {
+ auto* f = b.Function("my_func", ty.void_());
+
+ f->SetParams({b.FunctionParam(ty.AFloat()), b.FunctionParam(ty.AInt())});
+ f->Block()->Append(b.Return(f));
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.Str(),
+ R"(:1:17 error: abstracts are not permitted
+%my_func = func(%2:abstract-float, %3:abstract-int):void {
+ ^^^^^^^^^^^^^^^^^
+
+:1:36 error: abstracts are not permitted
+%my_func = func(%2:abstract-float, %3:abstract-int):void {
+ ^^^^^^^^^^^^^^^
+
+note: # Disassembly
+%my_func = func(%2:abstract-float, %3:abstract-int):void {
+ $B1: {
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Function) {
auto* f = b.Function("my_func", ty.void_());
@@ -11170,9 +11345,6 @@
std::make_tuple(false, TypeBuilder<f16>, TypeBuilder<i32>),
std::make_tuple(false, TypeBuilder<f16>, TypeBuilder<f32>),
std::make_tuple(false, TypeBuilder<f16>, TypeBuilder<vec2<f16>>)
-
- // Intentionally omitting AbstractInt cases, since concretetization
- // when creating IR should remove them
));
} // namespace