tint: Implement constant expression structures

Bug: tint:1611
Change-Id: Id04c31ade297a68e7e2941efafbd812ba631fc41
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95946
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-07-14 20:46:39 +00:00 committed by Dawn LUCI CQ
parent fc85619d77
commit 6c098baedf
53 changed files with 3275 additions and 2625 deletions

View File

@ -1943,13 +1943,13 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* expr) {
auto* structure = sem_.TypeOf(expr->structure);
auto* storage_ty = structure->UnwrapRef();
auto* source_var = sem_.Get(expr->structure)->SourceVariable();
auto* object = sem_.Get(expr->structure);
auto* source_var = object->SourceVariable();
const sem::Type* ret = nullptr;
std::vector<uint32_t> swizzle;
// Object may be a side-effecting expression (e.g. function call).
auto* object = sem_.Get(expr->structure);
bool has_side_effects = object && object->HasSideEffects();
if (auto* str = storage_ty->As<sem::Struct>()) {
@ -1976,7 +1976,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
ret = builder_->create<sem::Reference>(ret, ref->StorageClass(), ref->Access());
}
sem::Constant* val = nullptr; // TODO(crbug.com/tint/1611): Add structure support.
auto* val = EvaluateMemberAccessValue(object, member);
return builder_->create<sem::StructMemberAccess>(expr, ret, current_statement_, val, object,
member, has_side_effects, source_var);
}

View File

@ -66,6 +66,7 @@ class ForLoopStatement;
class IfStatement;
class LoopStatement;
class Statement;
class StructMember;
class SwitchStatement;
class TypeConstructor;
class WhileStatement;
@ -218,6 +219,8 @@ class Resolver {
const sem::Type* ty); // Note: ty is not an array or structure
const sem::Constant* EvaluateIndexValue(const sem::Expression* obj, const sem::Expression* idx);
const sem::Constant* EvaluateLiteralValue(const ast::LiteralExpression*, const sem::Type*);
const sem::Constant* EvaluateMemberAccessValue(const sem::Expression* obj,
const sem::StructMember* member);
const sem::Constant* EvaluateSwizzleValue(const sem::Expression* vector,
const sem::Type* type,
const std::vector<uint32_t>& indices);

View File

@ -22,6 +22,7 @@
#include "src/tint/sem/member_accessor_expression.h"
#include "src/tint/sem/type_constructor.h"
#include "src/tint/utils/compiler_macros.h"
#include "src/tint/utils/map.h"
#include "src/tint/utils/transform.h"
using namespace tint::number_suffixes; // NOLINT
@ -277,6 +278,24 @@ const Constant* ZeroValue(ProgramBuilder& builder, const sem::Type* type) {
}
return nullptr;
},
[&](const sem::Struct* s) -> const Constant* {
std::unordered_map<sem::Type*, const Constant*> zero_by_type;
std::vector<const Constant*> zeros;
zeros.reserve(s->Members().size());
for (auto* member : s->Members()) {
auto* zero = utils::GetOrCreate(zero_by_type, member->Type(),
[&] { return ZeroValue(builder, member->Type()); });
if (!zero) {
return nullptr;
}
zeros.emplace_back(zero);
}
if (zero_by_type.size() == 1) {
// All members were of the same type, so the zero value is the same for all members.
return builder.create<Splat>(type, zeros[0], s->Members().size());
}
return CreateComposite(builder, s, std::move(zeros));
},
[&](Default) -> const Constant* {
return TypeDispatch(type, [&](auto zero) -> const Constant* {
return CreateElement(builder, type, zero);
@ -335,6 +354,9 @@ const Constant* CreateComposite(ProgramBuilder& builder,
bool all_equal = true;
auto* first = elements.front();
for (auto* el : elements) {
if (!el) {
return nullptr;
}
if (!any_zero && el->AnyZero()) {
any_zero = true;
}
@ -395,13 +417,7 @@ const sem::Constant* Resolver::EvaluateCtorOrConvValue(
return ZeroValue(*builder_, ty);
}
uint32_t el_count = 0;
auto* el_ty = sem::Type::ElementOf(ty, &el_count);
if (!el_ty) {
return nullptr; // Target type does not support constant values
}
if (args.size() == 1) {
if (auto* el_ty = sem::Type::ElementOf(ty); el_ty && args.size() == 1) {
// Type constructor or conversion that takes a single argument.
auto& src = args[0]->Declaration()->source;
auto* arg = static_cast<const Constant*>(args[0]->ConstantValue());
@ -431,33 +447,25 @@ const sem::Constant* Resolver::EvaluateCtorOrConvValue(
return nullptr;
}
// Multiple arguments. Must be a type constructor.
std::vector<const Constant*> els; // The constant elements for the composite constant.
els.reserve(std::min<uint32_t>(el_count, 256u)); // min() as el_count is unbounded input
// Helper for pushing all the argument constants to `els`.
auto push_all_args = [&] {
for (auto* expr : args) {
auto* arg = static_cast<const Constant*>(expr->ConstantValue());
if (!arg) {
return;
}
els.emplace_back(arg);
}
auto args_as_constants = [&] {
return utils::Transform(
args, [&](auto* expr) { return static_cast<const Constant*>(expr->ConstantValue()); });
};
// TODO(crbug.com/tint/1611): Add structure support.
// Multiple arguments. Must be a type constructor.
Switch(
return Switch(
ty, // What's the target type being constructed?
[&](const sem::Vector*) {
[&](const sem::Vector*) -> const Constant* {
// Vector can be constructed with a mix of scalars / abstract numerics and smaller
// vectors.
std::vector<const Constant*> els;
els.reserve(args.size());
for (auto* expr : args) {
auto* arg = static_cast<const Constant*>(expr->ConstantValue());
if (!arg) {
return;
return nullptr;
}
auto* arg_ty = arg->Type();
if (auto* arg_vec = arg_ty->As<sem::Vector>()) {
@ -465,7 +473,7 @@ const sem::Constant* Resolver::EvaluateCtorOrConvValue(
for (uint32_t i = 0; i < arg_vec->Width(); i++) {
auto* el = static_cast<const Constant*>(arg->Index(i));
if (!el) {
return;
return nullptr;
}
els.emplace_back(el);
}
@ -473,12 +481,15 @@ const sem::Constant* Resolver::EvaluateCtorOrConvValue(
els.emplace_back(arg);
}
}
return CreateComposite(*builder_, ty, std::move(els));
},
[&](const sem::Matrix* m) {
[&](const sem::Matrix* m) -> const Constant* {
// Matrix can be constructed with a set of scalars / abstract numerics, or column
// vectors.
if (args.size() == m->columns() * m->rows()) {
// Matrix built from scalars / abstract numerics
std::vector<const Constant*> els;
els.reserve(args.size());
for (uint32_t c = 0; c < m->columns(); c++) {
std::vector<const Constant*> column;
column.reserve(m->rows());
@ -486,28 +497,25 @@ const sem::Constant* Resolver::EvaluateCtorOrConvValue(
auto* arg =
static_cast<const Constant*>(args[r + c * m->rows()]->ConstantValue());
if (!arg) {
return;
return nullptr;
}
column.emplace_back(arg);
}
els.push_back(CreateComposite(*builder_, m->ColumnType(), std::move(column)));
}
} else if (args.size() == m->columns()) {
// Matrix built from column vectors
push_all_args();
return CreateComposite(*builder_, ty, std::move(els));
}
// Matrix built from column vectors
return CreateComposite(*builder_, ty, args_as_constants());
},
[&](const sem::Array*) {
// Arrays must be constructed using a list of elements
push_all_args();
return CreateComposite(*builder_, ty, args_as_constants());
},
[&](const sem::Struct*) {
// Structures must be constructed using a list of elements
return CreateComposite(*builder_, ty, args_as_constants());
});
if (els.size() != el_count) {
// If the number of constant elements doesn't match the type, then something went wrong.
return nullptr;
}
// Construct and return either a Composite or Splat.
return CreateComposite(*builder_, ty, std::move(els));
}
const sem::Constant* Resolver::EvaluateIndexValue(const sem::Expression* obj_expr,
@ -538,6 +546,15 @@ const sem::Constant* Resolver::EvaluateIndexValue(const sem::Expression* obj_exp
return obj_val->Index(static_cast<size_t>(idx));
}
const sem::Constant* Resolver::EvaluateMemberAccessValue(const sem::Expression* obj_expr,
const sem::StructMember* member) {
auto obj_val = obj_expr->ConstantValue();
if (!obj_val) {
return {};
}
return obj_val->Index(static_cast<size_t>(member->Index()));
}
const sem::Constant* Resolver::EvaluateSwizzleValue(const sem::Expression* vec_expr,
const sem::Type* type,
const std::vector<uint32_t>& indices) {
@ -546,7 +563,7 @@ const sem::Constant* Resolver::EvaluateSwizzleValue(const sem::Expression* vec_e
return nullptr;
}
if (indices.size() == 1) {
return static_cast<const Constant*>(vec_val->Index(indices[0]));
return static_cast<const Constant*>(vec_val->Index(static_cast<size_t>(indices[0])));
} else {
auto values = utils::Transform(
indices, [&](uint32_t i) { return static_cast<const Constant*>(vec_val->Index(i)); });

View File

@ -84,6 +84,7 @@ TEST_F(ResolverConstantsTest, Scalar_f32) {
TEST_F(ResolverConstantsTest, Scalar_f16) {
Enable(ast::Extension::kF16);
auto* expr = Expr(9.9_h);
WrapInFunction(expr);
@ -217,6 +218,7 @@ TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f32) {
TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f16) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>();
WrapInFunction(expr);
@ -383,6 +385,7 @@ TEST_F(ResolverConstantsTest, Vec3_Splat_f32) {
TEST_F(ResolverConstantsTest, Vec3_Splat_f16) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(9.9_h);
WrapInFunction(expr);
@ -550,6 +553,7 @@ TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f32) {
TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f16) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(1_h, 2_h, 3_h);
WrapInFunction(expr);
@ -848,6 +852,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32_mixed_sign_0) {
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(1_h, vec2<f16>(2_h, 3_h));
WrapInFunction(expr);
@ -882,6 +887,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16) {
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_10) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(10_h, vec2<f16>(10_h, 10_h));
WrapInFunction(expr);
@ -916,6 +922,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_10) {
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_positive_0) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(0_h, vec2<f16>(0_h, 0_h));
WrapInFunction(expr);
@ -950,6 +957,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_positive_0) {
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_negative_0) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(vec2<f16>(-0_h, -0_h), -0_h);
WrapInFunction(expr);
@ -984,6 +992,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_all_negative_0) {
TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f16_mixed_sign_0) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(0_h, vec2<f16>(-0_h, 0_h));
WrapInFunction(expr);
@ -1183,6 +1192,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_u32_to_f32) {
TEST_F(ResolverConstantsTest, Vec3_Convert_f16_to_i32) {
Enable(ast::Extension::kF16);
auto* expr = vec3<i32>(vec3<f16>(1.1_h, 2.2_h, 3.3_h));
WrapInFunction(expr);
@ -1217,6 +1227,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_f16_to_i32) {
TEST_F(ResolverConstantsTest, Vec3_Convert_u32_to_f16) {
Enable(ast::Extension::kF16);
auto* expr = vec3<f16>(vec3<u32>(10_u, 20_u, 30_u));
WrapInFunction(expr);
@ -1715,6 +1726,48 @@ TEST_F(ResolverConstantsTest, Array_vec3_f32_Zero) {
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 0_f);
}
TEST_F(ResolverConstantsTest, Array_Struct_f32_Zero) {
Structure("S", {
Member("m1", ty.f32()),
Member("m2", ty.f32()),
});
auto* expr = Construct(ty.array(ty.type_name("S"), 2_u));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
EXPECT_EQ(arr->Count(), 2u);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 0_f);
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 0_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 0_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 0_f);
}
TEST_F(ResolverConstantsTest, Array_i32_Elements) {
auto* expr = Construct(ty.array<i32, 4>(), 10_i, 20_i, 30_i, 40_i);
WrapInFunction(expr);
@ -1816,6 +1869,523 @@ TEST_F(ResolverConstantsTest, Array_vec3_f32_Elements) {
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 6_f);
}
TEST_F(ResolverConstantsTest, Array_Struct_f32_Elements) {
Structure("S", {
Member("m1", ty.f32()),
Member("m2", ty.f32()),
});
auto* expr = Construct(ty.array(ty.type_name("S"), 2_u), //
Construct(ty.type_name("S"), 1_f, 2_f), //
Construct(ty.type_name("S"), 3_f, 4_f));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
EXPECT_EQ(arr->Count(), 2u);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(0)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 1_f);
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Index(1)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->Index(1)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 2_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(0)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 3_f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Index(1)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->Index(1)->AllZero());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 4_f);
}
TEST_F(ResolverConstantsTest, Struct_I32s_ZeroInit) {
Structure("S", {Member("m1", ty.i32()), Member("m2", ty.i32()), Member("m3", ty.i32())});
auto* expr = Construct(ty.type_name("S"));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 3u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->As<i32>(), 0_i);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->As<i32>(), 0_i);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->As<i32>(), 0_i);
}
TEST_F(ResolverConstantsTest, Struct_MixedScalars_ZeroInit) {
Enable(ast::Extension::kF16);
Structure("S", {
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
Member("m4", ty.f16()),
Member("m5", ty.bool_()),
});
auto* expr = Construct(ty.type_name("S"));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->As<i32>(), 0_i);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::U32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->As<u32>(), 0_u);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 0._f);
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->Is<sem::F16>());
EXPECT_EQ(sem->ConstantValue()->Index(3)->As<f16>(), 0._h);
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->Is<sem::Bool>());
EXPECT_EQ(sem->ConstantValue()->Index(4)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Struct_VectorF32s_ZeroInit) {
Structure("S", {
Member("m1", ty.vec3<f32>()),
Member("m2", ty.vec3<f32>()),
Member("m3", ty.vec3<f32>()),
});
auto* expr = Construct(ty.type_name("S"));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 3u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 0._f);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 0._f);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(0)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(1)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(2)->As<f32>(), 0._f);
}
TEST_F(ResolverConstantsTest, Struct_MixedVectors_ZeroInit) {
Enable(ast::Extension::kF16);
Structure("S", {
Member("m1", ty.vec2<i32>()),
Member("m2", ty.vec3<u32>()),
Member("m3", ty.vec4<f32>()),
Member("m4", ty.vec3<f16>()),
Member("m5", ty.vec2<bool>()),
});
auto* expr = Construct(ty.type_name("S"));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<i32>(), 0_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<i32>(), 0_i);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<u32>(), 0_u);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(0)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(1)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(2)->As<f32>(), 0._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(3)->As<f32>(), 0._f);
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(0)->As<f16>(), 0._h);
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(1)->As<f16>(), 0._h);
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(2)->As<f16>(), 0._h);
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_EQ(sem->ConstantValue()->Index(4)->Index(0)->As<bool>(), false);
EXPECT_EQ(sem->ConstantValue()->Index(4)->Index(1)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Struct_Struct_ZeroInit) {
Structure("Inner", {
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
});
Structure("Outer", {
Member("m1", ty.type_name("Inner")),
Member("m2", ty.type_name("Inner")),
});
auto* expr = Construct(ty.type_name("Outer"));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->AllZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<i32>(), 0_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 0_f);
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<i32>(), 0_i);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 0_f);
}
TEST_F(ResolverConstantsTest, Struct_MixedScalars_Construct) {
Enable(ast::Extension::kF16);
Structure("S", {
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
Member("m4", ty.f16()),
Member("m5", ty.bool_()),
});
auto* expr = Construct(ty.type_name("S"), 1_i, 2_u, 3_f, 4_h, false);
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->As<i32>(), 1_i);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::U32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->As<u32>(), 2_u);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->As<f32>(), 3._f);
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(3)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(3)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->Is<sem::F16>());
EXPECT_EQ(sem->ConstantValue()->Index(3)->As<f16>(), 4._h);
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->Is<sem::Bool>());
EXPECT_EQ(sem->ConstantValue()->Index(4)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Struct_MixedVectors_Construct) {
Enable(ast::Extension::kF16);
Structure("S", {
Member("m1", ty.vec2<i32>()),
Member("m2", ty.vec3<u32>()),
Member("m3", ty.vec4<f32>()),
Member("m4", ty.vec3<f16>()),
Member("m5", ty.vec2<bool>()),
});
auto* expr = Construct(ty.type_name("S"), vec2<i32>(1_i), vec3<u32>(2_u), vec4<f32>(3_f),
vec3<f16>(4_h), vec2<bool>(false));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 5u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->As<sem::Vector>()->type()->Is<sem::I32>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<i32>(), 1_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<i32>(), 1_i);
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->As<sem::Vector>()->type()->Is<sem::U32>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<u32>(), 2_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<u32>(), 2_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<u32>(), 2_u);
EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(2)->Type()->As<sem::Vector>()->type()->Is<sem::F32>());
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(0)->As<f32>(), 3._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(1)->As<f32>(), 3._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(2)->As<f32>(), 3._f);
EXPECT_EQ(sem->ConstantValue()->Index(2)->Index(3)->As<f32>(), 3._f);
EXPECT_TRUE(sem->ConstantValue()->Index(3)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(3)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(3)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(3)->Type()->As<sem::Vector>()->type()->Is<sem::F16>());
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(0)->As<f16>(), 4._h);
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(1)->As<f16>(), 4._h);
EXPECT_EQ(sem->ConstantValue()->Index(3)->Index(2)->As<f16>(), 4._h);
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AnyZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->Is<sem::Vector>());
EXPECT_TRUE(sem->ConstantValue()->Index(4)->Type()->As<sem::Vector>()->type()->Is<sem::Bool>());
EXPECT_EQ(sem->ConstantValue()->Index(4)->Index(0)->As<bool>(), false);
EXPECT_EQ(sem->ConstantValue()->Index(4)->Index(1)->As<bool>(), false);
}
TEST_F(ResolverConstantsTest, Struct_Struct_Construct) {
Structure("Inner", {
Member("m1", ty.i32()),
Member("m2", ty.u32()),
Member("m3", ty.f32()),
});
Structure("Outer", {
Member("m1", ty.type_name("Inner")),
Member("m2", ty.type_name("Inner")),
});
auto* expr = Construct(ty.type_name("Outer"), //
Construct(ty.type_name("Inner"), 1_i, 2_u, 3_f),
Construct(ty.type_name("Inner"), 4_i, 0_u, 6_f));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<i32>(), 1_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<u32>(), 2_u);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(2)->As<f32>(), 3_f);
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Struct>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<i32>(), 4_i);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<u32>(), 0_u);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 6_f);
}
TEST_F(ResolverConstantsTest, Struct_Array_Construct) {
Structure("S", {
Member("m1", ty.array<i32, 2>()),
Member("m2", ty.array<f32, 3>()),
});
auto* expr = Construct(ty.type_name("S"), //
Construct(ty.array<i32, 2>(), 1_i, 2_i),
Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
WrapInFunction(expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* sem = Sem().Get(expr);
ASSERT_NE(sem, nullptr);
auto* str = sem->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 2u);
ASSERT_NE(sem->ConstantValue(), nullptr);
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->AllZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(0)->Type()->Is<sem::Array>());
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(0)->As<i32>(), 1_i);
EXPECT_EQ(sem->ConstantValue()->Index(0)->Index(1)->As<u32>(), 2_i);
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
EXPECT_TRUE(sem->ConstantValue()->Index(1)->Type()->Is<sem::Array>());
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(0)->As<i32>(), 1_f);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(1)->As<u32>(), 2_f);
EXPECT_EQ(sem->ConstantValue()->Index(1)->Index(2)->As<f32>(), 3_f);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Indexing
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -2302,5 +2872,59 @@ TEST_F(ResolverConstantsTest, ChainedIndex_OOB) {
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Member accessing
////////////////////////////////////////////////////////////////////////////////////////////////////
TEST_F(ResolverConstantsTest, MemberAccess) {
Structure("Inner", {
Member("i1", ty.i32()),
Member("i2", ty.u32()),
Member("i3", ty.f32()),
});
Structure("Outer", {
Member("o1", ty.type_name("Inner")),
Member("o2", ty.type_name("Inner")),
});
auto* outer_expr = Construct(ty.type_name("Outer"), //
Construct(ty.type_name("Inner"), 1_i, 2_u, 3_f),
Construct(ty.type_name("Inner")));
auto* o1_expr = MemberAccessor(outer_expr, "o1");
auto* i2_expr = MemberAccessor(o1_expr, "i2");
WrapInFunction(i2_expr);
EXPECT_TRUE(r()->Resolve()) << r()->error();
auto* outer = Sem().Get(outer_expr);
ASSERT_NE(outer, nullptr);
auto* str = outer->Type()->As<sem::Struct>();
ASSERT_NE(str, nullptr);
EXPECT_EQ(str->Members().size(), 2u);
ASSERT_NE(outer->ConstantValue(), nullptr);
EXPECT_TYPE(outer->ConstantValue()->Type(), outer->Type());
EXPECT_FALSE(outer->ConstantValue()->AllEqual());
EXPECT_TRUE(outer->ConstantValue()->AnyZero());
EXPECT_FALSE(outer->ConstantValue()->AllZero());
auto* o1 = Sem().Get(o1_expr);
ASSERT_NE(o1->ConstantValue(), nullptr);
EXPECT_FALSE(o1->ConstantValue()->AllEqual());
EXPECT_FALSE(o1->ConstantValue()->AnyZero());
EXPECT_FALSE(o1->ConstantValue()->AllZero());
EXPECT_TRUE(o1->ConstantValue()->Type()->Is<sem::Struct>());
EXPECT_EQ(o1->ConstantValue()->Index(0)->As<i32>(), 1_i);
EXPECT_EQ(o1->ConstantValue()->Index(1)->As<u32>(), 2_u);
EXPECT_EQ(o1->ConstantValue()->Index(2)->As<f32>(), 3_f);
auto* i2 = Sem().Get(i2_expr);
ASSERT_NE(i2->ConstantValue(), nullptr);
EXPECT_TRUE(i2->ConstantValue()->AllEqual());
EXPECT_FALSE(i2->ConstantValue()->AnyZero());
EXPECT_FALSE(i2->ConstantValue()->AllZero());
EXPECT_TRUE(i2->ConstantValue()->Type()->Is<sem::U32>());
EXPECT_EQ(i2->ConstantValue()->As<u32>(), 2_u);
}
} // namespace
} // namespace tint::resolver

View File

@ -892,6 +892,8 @@ TEST_F(ResolverVariableTest, LocalConst_ShadowsParam) {
}
TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
Structure("S", {Member("m", ty.u32())});
auto* c_i32 = Const("a", ty.i32(), Expr(0_i));
auto* c_u32 = Const("b", ty.u32(), Expr(0_u));
auto* c_f32 = Const("c", ty.f32(), Expr(0_f));
@ -899,8 +901,9 @@ TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
auto* c_vu32 = Const("e", ty.vec3<u32>(), vec3<u32>());
auto* c_vf32 = Const("f", ty.vec3<f32>(), vec3<f32>());
auto* c_mf32 = Const("g", ty.mat3x3<f32>(), mat3x3<f32>());
auto* c_s = Const("h", ty.type_name("S"), Construct(ty.type_name("S")));
WrapInFunction(c_i32, c_u32, c_f32, c_vi32, c_vu32, c_vf32, c_mf32);
WrapInFunction(c_i32, c_u32, c_f32, c_vi32, c_vu32, c_vf32, c_mf32, c_s);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@ -911,6 +914,7 @@ TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
EXPECT_EQ(Sem().Get(c_vu32)->Declaration(), c_vu32);
EXPECT_EQ(Sem().Get(c_vf32)->Declaration(), c_vf32);
EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
EXPECT_EQ(Sem().Get(c_s)->Declaration(), c_s);
ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
@ -919,6 +923,7 @@ TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
ASSERT_TRUE(TypeOf(c_vu32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(c_vf32)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
ASSERT_TRUE(TypeOf(c_s)->Is<sem::Struct>());
EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
@ -927,9 +932,12 @@ TEST_F(ResolverVariableTest, LocalConst_ExplicitType_Decls) {
EXPECT_TRUE(Sem().Get(c_vu32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_vf32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_s)->ConstantValue()->AllZero());
}
TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
Structure("S", {Member("m", ty.u32())});
auto* c_i32 = Const("a", nullptr, Expr(0_i));
auto* c_u32 = Const("b", nullptr, Expr(0_u));
auto* c_f32 = Const("c", nullptr, Expr(0_f));
@ -946,9 +954,10 @@ TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
Construct(ty.vec(nullptr, 3), Expr(0._a)),
Construct(ty.vec(nullptr, 3), Expr(0._a)),
Construct(ty.vec(nullptr, 3), Expr(0._a))));
auto* c_s = Const("m", nullptr, Construct(ty.type_name("S")));
WrapInFunction(c_i32, c_u32, c_f32, c_ai, c_af, c_vi32, c_vu32, c_vf32, c_vai, c_vaf, c_mf32,
c_maf32);
c_maf32, c_s);
ASSERT_TRUE(r()->Resolve()) << r()->error();
@ -964,6 +973,7 @@ TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
EXPECT_EQ(Sem().Get(c_vaf)->Declaration(), c_vaf);
EXPECT_EQ(Sem().Get(c_mf32)->Declaration(), c_mf32);
EXPECT_EQ(Sem().Get(c_maf32)->Declaration(), c_maf32);
EXPECT_EQ(Sem().Get(c_s)->Declaration(), c_s);
ASSERT_TRUE(TypeOf(c_i32)->Is<sem::I32>());
ASSERT_TRUE(TypeOf(c_u32)->Is<sem::U32>());
@ -977,6 +987,7 @@ TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
ASSERT_TRUE(TypeOf(c_vaf)->Is<sem::Vector>());
ASSERT_TRUE(TypeOf(c_mf32)->Is<sem::Matrix>());
ASSERT_TRUE(TypeOf(c_maf32)->Is<sem::Matrix>());
ASSERT_TRUE(TypeOf(c_s)->Is<sem::Struct>());
EXPECT_TRUE(Sem().Get(c_i32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_u32)->ConstantValue()->AllZero());
@ -990,6 +1001,7 @@ TEST_F(ResolverVariableTest, LocalConst_ImplicitType_Decls) {
EXPECT_TRUE(Sem().Get(c_vaf)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_mf32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_maf32)->ConstantValue()->AllZero());
EXPECT_TRUE(Sem().Get(c_s)->ConstantValue()->AllZero());
}
TEST_F(ResolverVariableTest, LocalConst_PropagateConstValue) {

View File

@ -365,23 +365,6 @@ TEST_F(ResolverVariableValidationTest, MatrixVarNoType) {
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
}
TEST_F(ResolverVariableValidationTest, ConstStructure) {
auto* s = Structure("S", {Member("m", ty.i32())});
auto* c = Const("c", ty.Of(s), Construct(Source{{12, 34}}, ty.Of(s)));
WrapInFunction(c);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
}
TEST_F(ResolverVariableValidationTest, GlobalConstStructure) {
auto* s = Structure("S", {Member("m", ty.i32())});
GlobalConst("c", ty.Of(s), Construct(Source{{12, 34}}, ty.Of(s)));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(12:34 error: 'const' initializer must be constant expression)");
}
TEST_F(ResolverVariableValidationTest, ConstInitWithVar) {
auto* v = Var("v", nullptr, Expr(1_i));
auto* c = Const("c", nullptr, Expr(Source{{12, 34}}, v));

View File

@ -39,11 +39,15 @@ class Constant {
virtual const sem::Type* Type() const = 0;
/// @returns the value of this Constant, if this constant is of a scalar value or abstract
/// numeric, otherwsie std::monostate.
/// numeric, otherwise std::monostate.
virtual std::variant<std::monostate, AInt, AFloat> Value() const = 0;
/// @returns the child constant element with the given index, or nullptr if the constant has no
/// children, or the index is out of bounds.
/// For arrays, this returns the i'th element of the array.
/// For vectors, this returns the i'th element of the vector.
/// For matrices, this returns the i'th column vector of the matrix.
/// For structures, this returns the i'th member field of the structure.
virtual const Constant* Index(size_t) const = 0;
/// @returns true if child elements of this constant are positive-zero valued.

View File

@ -862,15 +862,10 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
return EmitZeroValue(out, type);
}
auto it = structure_builders_.find(As<sem::Struct>(type));
if (it != structure_builders_.end()) {
out << it->second << "(";
} else {
if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
return false;
}
out << "(";
if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
return false;
}
ScopedParen sp(out);
bool first = true;
for (auto* arg : call->Arguments()) {
@ -884,7 +879,6 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
}
}
out << ")";
return true;
}
@ -2300,6 +2294,24 @@ bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constan
return true;
},
[&](const sem::Struct* s) {
if (!EmitType(out, s, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
ScopedParen sp(out);
for (size_t i = 0; i < s->Members().size(); i++) {
if (i > 0) {
out << ", ";
}
if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,

View File

@ -520,7 +520,6 @@ class GeneratorImpl : public TextGenerator {
std::function<bool()> emit_continuing_;
std::unordered_map<DMAIntrinsic, std::string, DMAIntrinsic::Hasher> dma_intrinsics_;
std::unordered_map<const sem::Builtin*, std::string> builtins_;
std::unordered_map<const sem::Struct*, std::string> structure_builders_;
std::unordered_map<const sem::Vector*, std::string> dynamic_vector_write_;
std::unordered_map<const sem::Vector*, std::string> int_dot_funcs_;
std::unordered_map<const sem::Type*, std::string> float_modulo_funcs_;

View File

@ -1142,11 +1142,7 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& out,
call->Arguments().size() == 1 &&
ctor->Parameters()[0]->Type()->is_scalar();
auto it = structure_builders_.find(As<sem::Struct>(type));
if (it != structure_builders_.end()) {
out << it->second << "(";
brackets = false;
} else if (brackets) {
if (brackets) {
out << "{";
} else {
if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
@ -3219,6 +3215,30 @@ bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constan
return true;
},
[&](const sem::Struct* s) {
if (constant->AllZero()) {
out << "(";
if (!EmitType(out, s, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
out << ")0";
return true;
}
out << "{";
TINT_DEFER(out << "}");
for (size_t i = 0; i < s->Members().size(); i++) {
if (i > 0) {
out << ", ";
}
if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,

View File

@ -543,7 +543,6 @@ class GeneratorImpl : public TextGenerator {
std::function<bool()> emit_continuing_;
std::unordered_map<const sem::Matrix*, std::string> matrix_scalar_ctors_;
std::unordered_map<const sem::Builtin*, std::string> builtins_;
std::unordered_map<const sem::Struct*, std::string> structure_builders_;
std::unordered_map<const sem::Vector*, std::string> dynamic_vector_write_;
std::unordered_map<const sem::Matrix*, std::string> dynamic_matrix_vector_write_;
std::unordered_map<const sem::Matrix*, std::string> dynamic_matrix_scalar_write_;

View File

@ -1676,14 +1676,13 @@ bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constan
return false;
}
if (constant->AllZero()) {
out << "{}";
return true;
}
out << "{";
TINT_DEFER(out << "}");
if (constant->AllZero()) {
return true;
}
for (size_t i = 0; i < a->Count(); i++) {
if (i > 0) {
out << ", ";
@ -1695,6 +1694,27 @@ bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constan
return true;
},
[&](const sem::Struct* s) {
out << "{";
TINT_DEFER(out << "}");
if (constant->AllZero()) {
return true;
}
auto& members = s->Members();
for (size_t i = 0; i < members.size(); i++) {
if (i > 0) {
out << ", ";
}
out << "." << program_->Symbols().NameFor(members[i]->Name()) << "=";
if (!EmitConstant(out, constant->Index(i))) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,

View File

@ -1770,6 +1770,7 @@ uint32_t Builder::GenerateConstantIfNeeded(const sem::Constant* constant) {
[&](const sem::Vector* v) { return composite(v->Width()); },
[&](const sem::Matrix* m) { return composite(m->columns()); },
[&](const sem::Array* a) { return composite(a->Count()); },
[&](const sem::Struct* s) { return composite(s->Members().size()); },
[&](Default) {
error_ = "unhandled constant type: " + builder_.FriendlyName(ty);
return false;

View File

@ -47,7 +47,8 @@ TEST_F(BuilderTest, Let_IndexAccessor_Vector) {
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%11 = OpCompositeExtract %6 %10 1
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(%11 = OpCompositeExtract %6 %10 1
OpStore %12 %11
OpReturn
)");
@ -773,7 +774,8 @@ TEST_F(BuilderTest, Let_IndexAccessor_Matrix) {
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%18 = OpVariable %19 Function %20
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%17 = OpCompositeExtract %6 %14 1
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(%17 = OpCompositeExtract %6 %14 1
OpStore %18 %17
OpReturn
)");
@ -1009,11 +1011,10 @@ TEST_F(BuilderTest, MemberAccessor_NonPointer) {
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeStruct %6 %6
%7 = OpConstantNull %6
%8 = OpConstantComposite %5 %7 %7
%7 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%9 = OpCompositeExtract %6 %8 1
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%8 = OpCompositeExtract %6 %7 1
OpReturn
)");
@ -1052,14 +1053,12 @@ TEST_F(BuilderTest, MemberAccessor_Nested_NonPointer) {
%7 = OpTypeFloat 32
%6 = OpTypeStruct %7 %7
%5 = OpTypeStruct %6
%8 = OpConstantNull %7
%9 = OpConstantComposite %6 %8 %8
%10 = OpConstantComposite %5 %9
%8 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(%11 = OpCompositeExtract %6 %10 0
%12 = OpCompositeExtract %7 %11 1
R"(%9 = OpCompositeExtract %6 %8 0
%10 = OpCompositeExtract %7 %9 1
OpReturn
)");

View File

@ -23,7 +23,7 @@ ivec4[4] ret_arr() {
}
S ret_struct_arr() {
S tint_symbol_2 = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
S tint_symbol_2 = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
return tint_symbol_2;
}

View File

@ -25,7 +25,7 @@ ivec4[4] ret_arr() {
}
S ret_struct_arr() {
S tint_symbol_2 = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
S tint_symbol_2 = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
return tint_symbol_2;
}

View File

@ -33,7 +33,7 @@ ivec4[4] ret_arr() {
}
S ret_struct_arr() {
S tint_symbol_3 = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
S tint_symbol_3 = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
return tint_symbol_3;
}

View File

@ -25,7 +25,7 @@ ivec4[4] ret_arr() {
}
S ret_struct_arr() {
S tint_symbol_2 = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
S tint_symbol_2 = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
return tint_symbol_2;
}

View File

@ -131,7 +131,7 @@ main_out tint_symbol(float fClipDistance3_param, float fClipDistance4_param) {
fClipDistance4 = fClipDistance4_param;
main_1();
if (tint_discard) {
main_out tint_symbol_1 = main_out(vec4(0.0f, 0.0f, 0.0f, 0.0f));
main_out tint_symbol_1 = main_out(vec4(0.0f));
return tint_symbol_1;
}
main_out tint_symbol_2 = main_out(glFragColor);

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ atomic_compare_exchange_weak_ret_type tint_atomicCompareExchangeWeak(RWByteAddre
void atomicCompareExchangeWeak_1bd40a() {
x__atomic_compare_exchange_resulti32 res = {0, false};
x__atomic_compare_exchange_resulti32 res = (x__atomic_compare_exchange_resulti32)0;
const atomic_compare_exchange_weak_ret_type tint_symbol = tint_atomicCompareExchangeWeak(sb_rw, 0u, 1, 1);
const int old_value_1 = tint_symbol.old_value;
const int x_19 = old_value_1;

View File

@ -26,7 +26,7 @@ struct x__atomic_compare_exchange_resulti32 {
};
void atomicCompareExchangeWeak_1bd40a(device SB_RW_atomic* const tint_symbol_2) {
x__atomic_compare_exchange_resulti32 res = {.old_value=0, .exchanged=false};
x__atomic_compare_exchange_resulti32 res = {};
atomic_compare_exchange_resulti32 const tint_symbol = atomicCompareExchangeWeak_1(&((*(tint_symbol_2)).arg_0), 1, 1);
int const old_value_1 = tint_symbol.old_value;
int const x_19 = old_value_1;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 43
; Bound: 40
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -40,11 +40,8 @@
%5 = OpTypeFunction %void
%bool = OpTypeBool
%x__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%11 = OpConstantNull %int
%12 = OpConstantNull %bool
%13 = OpConstantComposite %x__atomic_compare_exchange_resulti32 %11 %12
%11 = OpConstantNull %x__atomic_compare_exchange_resulti32
%_ptr_Function_x__atomic_compare_exchange_resulti32 = OpTypePointer Function %x__atomic_compare_exchange_resulti32
%16 = OpConstantNull %x__atomic_compare_exchange_resulti32
%__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
@ -53,35 +50,35 @@
%int_1 = OpConstant %int 1
%atomicCompareExchangeWeak_1bd40a = OpFunction %void None %5
%8 = OpLabel
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %16
OpStore %res %13
%24 = OpAccessChain %_ptr_StorageBuffer_int %sb_rw %uint_0
%26 = OpAtomicCompareExchange %int %24 %uint_1 %uint_0 %uint_0 %int_1 %int_1
%27 = OpIEqual %bool %26 %int_1
%17 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %26 %27
%28 = OpCompositeExtract %int %17 0
%29 = OpIEqual %bool %28 %int_1
%30 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %28 %29
OpStore %res %30
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %11
OpStore %res %11
%21 = OpAccessChain %_ptr_StorageBuffer_int %sb_rw %uint_0
%23 = OpAtomicCompareExchange %int %21 %uint_1 %uint_0 %uint_0 %int_1 %int_1
%24 = OpIEqual %bool %23 %int_1
%14 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %23 %24
%25 = OpCompositeExtract %int %14 0
%26 = OpIEqual %bool %25 %int_1
%27 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %25 %26
OpStore %res %27
OpReturn
OpFunctionEnd
%fragment_main_1 = OpFunction %void None %5
%32 = OpLabel
%33 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
%29 = OpLabel
%30 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
OpReturn
OpFunctionEnd
%fragment_main = OpFunction %void None %5
%35 = OpLabel
%36 = OpFunctionCall %void %fragment_main_1
%32 = OpLabel
%33 = OpFunctionCall %void %fragment_main_1
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %5
%38 = OpLabel
%39 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
%35 = OpLabel
%36 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %5
%41 = OpLabel
%42 = OpFunctionCall %void %compute_main_1
%38 = OpLabel
%39 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd

View File

@ -19,7 +19,7 @@ atomic_compare_exchange_weak_ret_type tint_atomicCompareExchangeWeak(RWByteAddre
void atomicCompareExchangeWeak_63d8e6() {
x__atomic_compare_exchange_resultu32 res = {0u, false};
x__atomic_compare_exchange_resultu32 res = (x__atomic_compare_exchange_resultu32)0;
const atomic_compare_exchange_weak_ret_type tint_symbol = tint_atomicCompareExchangeWeak(sb_rw, 0u, 1u, 1u);
const uint old_value_1 = tint_symbol.old_value;
const uint x_17 = old_value_1;

View File

@ -26,7 +26,7 @@ struct x__atomic_compare_exchange_resultu32 {
};
void atomicCompareExchangeWeak_63d8e6(device SB_RW_atomic* const tint_symbol_2) {
x__atomic_compare_exchange_resultu32 res = {.old_value=0u, .exchanged=false};
x__atomic_compare_exchange_resultu32 res = {};
atomic_compare_exchange_resultu32 const tint_symbol = atomicCompareExchangeWeak_1(&((*(tint_symbol_2)).arg_0), 1u, 1u);
uint const old_value_1 = tint_symbol.old_value;
uint const x_17 = old_value_1;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 41
; Bound: 38
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -40,46 +40,43 @@
%5 = OpTypeFunction %void
%bool = OpTypeBool
%x__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%11 = OpConstantNull %uint
%12 = OpConstantNull %bool
%13 = OpConstantComposite %x__atomic_compare_exchange_resultu32 %11 %12
%11 = OpConstantNull %x__atomic_compare_exchange_resultu32
%_ptr_Function_x__atomic_compare_exchange_resultu32 = OpTypePointer Function %x__atomic_compare_exchange_resultu32
%16 = OpConstantNull %x__atomic_compare_exchange_resultu32
%__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%uint_1 = OpConstant %uint 1
%uint_0 = OpConstant %uint 0
%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
%atomicCompareExchangeWeak_63d8e6 = OpFunction %void None %5
%8 = OpLabel
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %16
OpStore %res %13
%23 = OpAccessChain %_ptr_StorageBuffer_uint %sb_rw %uint_0
%24 = OpAtomicCompareExchange %uint %23 %uint_1 %uint_0 %uint_0 %uint_1 %uint_1
%25 = OpIEqual %bool %24 %uint_1
%17 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %24 %25
%26 = OpCompositeExtract %uint %17 0
%27 = OpIEqual %bool %26 %uint_1
%28 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %26 %27
OpStore %res %28
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %11
OpStore %res %11
%20 = OpAccessChain %_ptr_StorageBuffer_uint %sb_rw %uint_0
%21 = OpAtomicCompareExchange %uint %20 %uint_1 %uint_0 %uint_0 %uint_1 %uint_1
%22 = OpIEqual %bool %21 %uint_1
%14 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %21 %22
%23 = OpCompositeExtract %uint %14 0
%24 = OpIEqual %bool %23 %uint_1
%25 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %23 %24
OpStore %res %25
OpReturn
OpFunctionEnd
%fragment_main_1 = OpFunction %void None %5
%30 = OpLabel
%31 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
%27 = OpLabel
%28 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
OpReturn
OpFunctionEnd
%fragment_main = OpFunction %void None %5
%33 = OpLabel
%34 = OpFunctionCall %void %fragment_main_1
%30 = OpLabel
%31 = OpFunctionCall %void %fragment_main_1
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %5
%36 = OpLabel
%37 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
%33 = OpLabel
%34 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %5
%39 = OpLabel
%40 = OpFunctionCall %void %compute_main_1
%36 = OpLabel
%37 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd

View File

@ -11,7 +11,7 @@ static uint local_invocation_index_1 = 0u;
groupshared int arg_0;
void atomicCompareExchangeWeak_e88938() {
x__atomic_compare_exchange_resulti32 res = {0, false};
x__atomic_compare_exchange_resulti32 res = (x__atomic_compare_exchange_resulti32)0;
atomic_compare_exchange_resulti32 atomic_result = (atomic_compare_exchange_resulti32)0;
int atomic_compare_value = 1;
InterlockedCompareExchange(arg_0, atomic_compare_value, 1, atomic_result.old_value);

View File

@ -18,7 +18,7 @@ struct x__atomic_compare_exchange_resulti32 {
};
void atomicCompareExchangeWeak_e88938(threadgroup atomic_int* const tint_symbol_2) {
x__atomic_compare_exchange_resulti32 res = {.old_value=0, .exchanged=false};
x__atomic_compare_exchange_resulti32 res = {};
atomic_compare_exchange_resulti32 const tint_symbol = atomicCompareExchangeWeak_1(tint_symbol_2, 1, 1);
int const old_value_1 = tint_symbol.old_value;
int const x_18 = old_value_1;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 57
; Bound: 55
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -42,56 +42,54 @@
%10 = OpTypeFunction %void
%bool = OpTypeBool
%x__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%16 = OpConstantNull %int
%17 = OpConstantNull %bool
%18 = OpConstantComposite %x__atomic_compare_exchange_resulti32 %16 %17
%16 = OpConstantNull %x__atomic_compare_exchange_resulti32
%_ptr_Function_x__atomic_compare_exchange_resulti32 = OpTypePointer Function %x__atomic_compare_exchange_resulti32
%21 = OpConstantNull %x__atomic_compare_exchange_resulti32
%__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%uint_2 = OpConstant %uint 2
%uint_0 = OpConstant %uint 0
%int_1 = OpConstant %int 1
%33 = OpTypeFunction %void %uint
%30 = OpTypeFunction %void %uint
%36 = OpConstantNull %int
%uint_264 = OpConstant %uint 264
%atomicCompareExchangeWeak_e88938 = OpFunction %void None %10
%13 = OpLabel
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %21
OpStore %res %18
%28 = OpAtomicCompareExchange %int %arg_0 %uint_2 %uint_0 %uint_0 %int_1 %int_1
%29 = OpIEqual %bool %28 %int_1
%22 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %28 %29
%30 = OpCompositeExtract %int %22 0
%31 = OpIEqual %bool %30 %int_1
%32 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %30 %31
OpStore %res %32
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %16
OpStore %res %16
%25 = OpAtomicCompareExchange %int %arg_0 %uint_2 %uint_0 %uint_0 %int_1 %int_1
%26 = OpIEqual %bool %25 %int_1
%19 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %25 %26
%27 = OpCompositeExtract %int %19 0
%28 = OpIEqual %bool %27 %int_1
%29 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %27 %28
OpStore %res %29
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %33
%compute_main_inner = OpFunction %void None %30
%local_invocation_index = OpFunctionParameter %uint
%36 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %16
%33 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %36
OpControlBarrier %uint_2 %uint_2 %uint_264
%41 = OpFunctionCall %void %atomicCompareExchangeWeak_e88938
%39 = OpFunctionCall %void %atomicCompareExchangeWeak_e88938
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %10
%43 = OpLabel
%44 = OpLoad %uint %local_invocation_index_1
%45 = OpFunctionCall %void %compute_main_inner %44
%41 = OpLabel
%42 = OpLoad %uint %local_invocation_index_1
%43 = OpFunctionCall %void %compute_main_inner %42
OpReturn
OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %33
%compute_main_inner_1 = OpFunction %void None %30
%local_invocation_index_1_param = OpFunctionParameter %uint
%48 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %16
%46 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %36
OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param
%52 = OpFunctionCall %void %compute_main_1
%50 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %10
%54 = OpLabel
%56 = OpLoad %uint %local_invocation_index_1_param_1
%55 = OpFunctionCall %void %compute_main_inner_1 %56
%52 = OpLabel
%54 = OpLoad %uint %local_invocation_index_1_param_1
%53 = OpFunctionCall %void %compute_main_inner_1 %54
OpReturn
OpFunctionEnd

View File

@ -11,7 +11,7 @@ static uint local_invocation_index_1 = 0u;
groupshared uint arg_0;
void atomicCompareExchangeWeak_83580d() {
x__atomic_compare_exchange_resultu32 res = {0u, false};
x__atomic_compare_exchange_resultu32 res = (x__atomic_compare_exchange_resultu32)0;
atomic_compare_exchange_resultu32 atomic_result = (atomic_compare_exchange_resultu32)0;
uint atomic_compare_value = 1u;
InterlockedCompareExchange(arg_0, atomic_compare_value, 1u, atomic_result.old_value);

View File

@ -18,7 +18,7 @@ struct x__atomic_compare_exchange_resultu32 {
};
void atomicCompareExchangeWeak_83580d(threadgroup atomic_uint* const tint_symbol_2) {
x__atomic_compare_exchange_resultu32 res = {.old_value=0u, .exchanged=false};
x__atomic_compare_exchange_resultu32 res = {};
atomic_compare_exchange_resultu32 const tint_symbol = atomicCompareExchangeWeak_1(tint_symbol_2, 1u, 1u);
uint const old_value_1 = tint_symbol.old_value;
uint const x_17 = old_value_1;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 55
; Bound: 53
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -41,55 +41,53 @@
%9 = OpTypeFunction %void
%bool = OpTypeBool
%x__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%15 = OpConstantNull %bool
%16 = OpConstantComposite %x__atomic_compare_exchange_resultu32 %6 %15
%15 = OpConstantNull %x__atomic_compare_exchange_resultu32
%_ptr_Function_x__atomic_compare_exchange_resultu32 = OpTypePointer Function %x__atomic_compare_exchange_resultu32
%19 = OpConstantNull %x__atomic_compare_exchange_resultu32
%__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%uint_2 = OpConstant %uint 2
%uint_0 = OpConstant %uint 0
%uint_1 = OpConstant %uint 1
%31 = OpTypeFunction %void %uint
%29 = OpTypeFunction %void %uint
%uint_264 = OpConstant %uint 264
%atomicCompareExchangeWeak_83580d = OpFunction %void None %9
%12 = OpLabel
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %19
OpStore %res %16
%26 = OpAtomicCompareExchange %uint %arg_0 %uint_2 %uint_0 %uint_0 %uint_1 %uint_1
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %15
OpStore %res %15
%24 = OpAtomicCompareExchange %uint %arg_0 %uint_2 %uint_0 %uint_0 %uint_1 %uint_1
%25 = OpIEqual %bool %24 %uint_1
%18 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %24 %25
%26 = OpCompositeExtract %uint %18 0
%27 = OpIEqual %bool %26 %uint_1
%20 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %26 %27
%28 = OpCompositeExtract %uint %20 0
%29 = OpIEqual %bool %28 %uint_1
%30 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %28 %29
OpStore %res %30
%28 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %26 %27
OpStore %res %28
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %31
%compute_main_inner = OpFunction %void None %29
%local_invocation_index = OpFunctionParameter %uint
%34 = OpLabel
%32 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %6
OpControlBarrier %uint_2 %uint_2 %uint_264
%39 = OpFunctionCall %void %atomicCompareExchangeWeak_83580d
%37 = OpFunctionCall %void %atomicCompareExchangeWeak_83580d
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %9
%41 = OpLabel
%42 = OpLoad %uint %local_invocation_index_1
%43 = OpFunctionCall %void %compute_main_inner %42
%39 = OpLabel
%40 = OpLoad %uint %local_invocation_index_1
%41 = OpFunctionCall %void %compute_main_inner %40
OpReturn
OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %31
%compute_main_inner_1 = OpFunction %void None %29
%local_invocation_index_1_param = OpFunctionParameter %uint
%46 = OpLabel
%44 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %6
OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param
%50 = OpFunctionCall %void %compute_main_1
%48 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %9
%52 = OpLabel
%54 = OpLoad %uint %local_invocation_index_1_param_1
%53 = OpFunctionCall %void %compute_main_inner_1 %54
%50 = OpLabel
%52 = OpLoad %uint %local_invocation_index_1_param_1
%51 = OpFunctionCall %void %compute_main_inner_1 %52
OpReturn
OpFunctionEnd

View File

@ -21,7 +21,7 @@ atomic_compare_exchange_weak_ret_type tint_atomicCompareExchangeWeak(RWByteAddre
void atomicCompareExchangeWeak_1bd40a() {
int arg_1 = 0;
int arg_2 = 0;
x__atomic_compare_exchange_resulti32 res = {0, false};
x__atomic_compare_exchange_resulti32 res = (x__atomic_compare_exchange_resulti32)0;
arg_1 = 1;
arg_2 = 1;
const int x_23 = arg_2;

View File

@ -28,7 +28,7 @@ struct x__atomic_compare_exchange_resulti32 {
void atomicCompareExchangeWeak_1bd40a(device SB_RW_atomic* const tint_symbol_2) {
int arg_1 = 0;
int arg_2 = 0;
x__atomic_compare_exchange_resulti32 res = {.old_value=0, .exchanged=false};
x__atomic_compare_exchange_resulti32 res = {};
arg_1 = 1;
arg_2 = 1;
int const x_23 = arg_2;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 48
; Bound: 46
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -44,10 +44,8 @@
%_ptr_Function_int = OpTypePointer Function %int
%bool = OpTypeBool
%x__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%15 = OpConstantNull %bool
%16 = OpConstantComposite %x__atomic_compare_exchange_resulti32 %9 %15
%15 = OpConstantNull %x__atomic_compare_exchange_resulti32
%_ptr_Function_x__atomic_compare_exchange_resulti32 = OpTypePointer Function %x__atomic_compare_exchange_resulti32
%19 = OpConstantNull %x__atomic_compare_exchange_resulti32
%int_1 = OpConstant %int 1
%__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%uint = OpTypeInt 32 0
@ -58,41 +56,41 @@
%8 = OpLabel
%arg_1 = OpVariable %_ptr_Function_int Function %9
%arg_2 = OpVariable %_ptr_Function_int Function %9
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %19
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %15
OpStore %arg_1 %9
OpStore %arg_2 %9
OpStore %res %16
OpStore %res %15
OpStore %arg_1 %int_1
OpStore %arg_2 %int_1
%21 = OpLoad %int %arg_2
%22 = OpLoad %int %arg_1
%30 = OpAccessChain %_ptr_StorageBuffer_int %sb_rw %uint_0
%31 = OpAtomicCompareExchange %int %30 %uint_1 %uint_0 %uint_0 %21 %22
%32 = OpIEqual %bool %31 %21
%23 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %31 %32
%33 = OpCompositeExtract %int %23 0
%34 = OpIEqual %bool %33 %21
%35 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %33 %34
OpStore %res %35
%19 = OpLoad %int %arg_2
%20 = OpLoad %int %arg_1
%28 = OpAccessChain %_ptr_StorageBuffer_int %sb_rw %uint_0
%29 = OpAtomicCompareExchange %int %28 %uint_1 %uint_0 %uint_0 %19 %20
%30 = OpIEqual %bool %29 %19
%21 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %29 %30
%31 = OpCompositeExtract %int %21 0
%32 = OpIEqual %bool %31 %19
%33 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %31 %32
OpStore %res %33
OpReturn
OpFunctionEnd
%fragment_main_1 = OpFunction %void None %5
%37 = OpLabel
%38 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
%35 = OpLabel
%36 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
OpReturn
OpFunctionEnd
%fragment_main = OpFunction %void None %5
%40 = OpLabel
%41 = OpFunctionCall %void %fragment_main_1
%38 = OpLabel
%39 = OpFunctionCall %void %fragment_main_1
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %5
%43 = OpLabel
%44 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
%41 = OpLabel
%42 = OpFunctionCall %void %atomicCompareExchangeWeak_1bd40a
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %5
%46 = OpLabel
%47 = OpFunctionCall %void %compute_main_1
%44 = OpLabel
%45 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd

View File

@ -21,7 +21,7 @@ atomic_compare_exchange_weak_ret_type tint_atomicCompareExchangeWeak(RWByteAddre
void atomicCompareExchangeWeak_63d8e6() {
uint arg_1 = 0u;
uint arg_2 = 0u;
x__atomic_compare_exchange_resultu32 res = {0u, false};
x__atomic_compare_exchange_resultu32 res = (x__atomic_compare_exchange_resultu32)0;
arg_1 = 1u;
arg_2 = 1u;
const uint x_21 = arg_2;

View File

@ -28,7 +28,7 @@ struct x__atomic_compare_exchange_resultu32 {
void atomicCompareExchangeWeak_63d8e6(device SB_RW_atomic* const tint_symbol_2) {
uint arg_1 = 0u;
uint arg_2 = 0u;
x__atomic_compare_exchange_resultu32 res = {.old_value=0u, .exchanged=false};
x__atomic_compare_exchange_resultu32 res = {};
arg_1 = 1u;
arg_2 = 1u;
uint const x_21 = arg_2;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 46
; Bound: 44
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -44,10 +44,8 @@
%_ptr_Function_uint = OpTypePointer Function %uint
%bool = OpTypeBool
%x__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%15 = OpConstantNull %bool
%16 = OpConstantComposite %x__atomic_compare_exchange_resultu32 %9 %15
%15 = OpConstantNull %x__atomic_compare_exchange_resultu32
%_ptr_Function_x__atomic_compare_exchange_resultu32 = OpTypePointer Function %x__atomic_compare_exchange_resultu32
%19 = OpConstantNull %x__atomic_compare_exchange_resultu32
%uint_1 = OpConstant %uint 1
%__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%uint_0 = OpConstant %uint 0
@ -56,41 +54,41 @@
%8 = OpLabel
%arg_1 = OpVariable %_ptr_Function_uint Function %9
%arg_2 = OpVariable %_ptr_Function_uint Function %9
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %19
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %15
OpStore %arg_1 %9
OpStore %arg_2 %9
OpStore %res %16
OpStore %res %15
OpStore %arg_1 %uint_1
OpStore %arg_2 %uint_1
%21 = OpLoad %uint %arg_2
%22 = OpLoad %uint %arg_1
%28 = OpAccessChain %_ptr_StorageBuffer_uint %sb_rw %uint_0
%29 = OpAtomicCompareExchange %uint %28 %uint_1 %uint_0 %uint_0 %21 %22
%30 = OpIEqual %bool %29 %21
%23 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %29 %30
%31 = OpCompositeExtract %uint %23 0
%32 = OpIEqual %bool %31 %21
%33 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %31 %32
OpStore %res %33
%19 = OpLoad %uint %arg_2
%20 = OpLoad %uint %arg_1
%26 = OpAccessChain %_ptr_StorageBuffer_uint %sb_rw %uint_0
%27 = OpAtomicCompareExchange %uint %26 %uint_1 %uint_0 %uint_0 %19 %20
%28 = OpIEqual %bool %27 %19
%21 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %27 %28
%29 = OpCompositeExtract %uint %21 0
%30 = OpIEqual %bool %29 %19
%31 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %29 %30
OpStore %res %31
OpReturn
OpFunctionEnd
%fragment_main_1 = OpFunction %void None %5
%35 = OpLabel
%36 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
%33 = OpLabel
%34 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
OpReturn
OpFunctionEnd
%fragment_main = OpFunction %void None %5
%38 = OpLabel
%39 = OpFunctionCall %void %fragment_main_1
%36 = OpLabel
%37 = OpFunctionCall %void %fragment_main_1
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %5
%41 = OpLabel
%42 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
%39 = OpLabel
%40 = OpFunctionCall %void %atomicCompareExchangeWeak_63d8e6
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %5
%44 = OpLabel
%45 = OpFunctionCall %void %compute_main_1
%42 = OpLabel
%43 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd

View File

@ -13,7 +13,7 @@ groupshared int arg_0;
void atomicCompareExchangeWeak_e88938() {
int arg_1 = 0;
int arg_2 = 0;
x__atomic_compare_exchange_resulti32 res = {0, false};
x__atomic_compare_exchange_resulti32 res = (x__atomic_compare_exchange_resulti32)0;
arg_1 = 1;
arg_2 = 1;
const int x_22 = arg_2;

View File

@ -20,7 +20,7 @@ struct x__atomic_compare_exchange_resulti32 {
void atomicCompareExchangeWeak_e88938(threadgroup atomic_int* const tint_symbol_2) {
int arg_1 = 0;
int arg_2 = 0;
x__atomic_compare_exchange_resulti32 res = {.old_value=0, .exchanged=false};
x__atomic_compare_exchange_resulti32 res = {};
arg_1 = 1;
arg_2 = 1;
int const x_22 = arg_2;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 62
; Bound: 60
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -46,63 +46,61 @@
%_ptr_Function_int = OpTypePointer Function %int
%bool = OpTypeBool
%x__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%20 = OpConstantNull %bool
%21 = OpConstantComposite %x__atomic_compare_exchange_resulti32 %14 %20
%20 = OpConstantNull %x__atomic_compare_exchange_resulti32
%_ptr_Function_x__atomic_compare_exchange_resulti32 = OpTypePointer Function %x__atomic_compare_exchange_resulti32
%24 = OpConstantNull %x__atomic_compare_exchange_resulti32
%int_1 = OpConstant %int 1
%__atomic_compare_exchange_resulti32 = OpTypeStruct %int %bool
%uint_2 = OpConstant %uint 2
%uint_0 = OpConstant %uint 0
%38 = OpTypeFunction %void %uint
%36 = OpTypeFunction %void %uint
%uint_264 = OpConstant %uint 264
%atomicCompareExchangeWeak_e88938 = OpFunction %void None %10
%13 = OpLabel
%arg_1 = OpVariable %_ptr_Function_int Function %14
%arg_2 = OpVariable %_ptr_Function_int Function %14
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %24
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resulti32 Function %20
OpStore %arg_1 %14
OpStore %arg_2 %14
OpStore %res %21
OpStore %res %20
OpStore %arg_1 %int_1
OpStore %arg_2 %int_1
%26 = OpLoad %int %arg_2
%27 = OpLoad %int %arg_1
%33 = OpAtomicCompareExchange %int %arg_0 %uint_2 %uint_0 %uint_0 %26 %27
%34 = OpIEqual %bool %33 %26
%28 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %33 %34
%35 = OpCompositeExtract %int %28 0
%36 = OpIEqual %bool %35 %26
%37 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %35 %36
OpStore %res %37
%24 = OpLoad %int %arg_2
%25 = OpLoad %int %arg_1
%31 = OpAtomicCompareExchange %int %arg_0 %uint_2 %uint_0 %uint_0 %24 %25
%32 = OpIEqual %bool %31 %24
%26 = OpCompositeConstruct %__atomic_compare_exchange_resulti32 %31 %32
%33 = OpCompositeExtract %int %26 0
%34 = OpIEqual %bool %33 %24
%35 = OpCompositeConstruct %x__atomic_compare_exchange_resulti32 %33 %34
OpStore %res %35
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %38
%compute_main_inner = OpFunction %void None %36
%local_invocation_index = OpFunctionParameter %uint
%41 = OpLabel
%39 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %14
OpControlBarrier %uint_2 %uint_2 %uint_264
%46 = OpFunctionCall %void %atomicCompareExchangeWeak_e88938
%44 = OpFunctionCall %void %atomicCompareExchangeWeak_e88938
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %10
%48 = OpLabel
%49 = OpLoad %uint %local_invocation_index_1
%50 = OpFunctionCall %void %compute_main_inner %49
%46 = OpLabel
%47 = OpLoad %uint %local_invocation_index_1
%48 = OpFunctionCall %void %compute_main_inner %47
OpReturn
OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %38
%compute_main_inner_1 = OpFunction %void None %36
%local_invocation_index_1_param = OpFunctionParameter %uint
%53 = OpLabel
%51 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %14
OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param
%57 = OpFunctionCall %void %compute_main_1
%55 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %10
%59 = OpLabel
%61 = OpLoad %uint %local_invocation_index_1_param_1
%60 = OpFunctionCall %void %compute_main_inner_1 %61
%57 = OpLabel
%59 = OpLoad %uint %local_invocation_index_1_param_1
%58 = OpFunctionCall %void %compute_main_inner_1 %59
OpReturn
OpFunctionEnd

View File

@ -13,7 +13,7 @@ groupshared uint arg_0;
void atomicCompareExchangeWeak_83580d() {
uint arg_1 = 0u;
uint arg_2 = 0u;
x__atomic_compare_exchange_resultu32 res = {0u, false};
x__atomic_compare_exchange_resultu32 res = (x__atomic_compare_exchange_resultu32)0;
arg_1 = 1u;
arg_2 = 1u;
const uint x_21 = arg_2;

View File

@ -20,7 +20,7 @@ struct x__atomic_compare_exchange_resultu32 {
void atomicCompareExchangeWeak_83580d(threadgroup atomic_uint* const tint_symbol_2) {
uint arg_1 = 0u;
uint arg_2 = 0u;
x__atomic_compare_exchange_resultu32 res = {.old_value=0u, .exchanged=false};
x__atomic_compare_exchange_resultu32 res = {};
arg_1 = 1u;
arg_2 = 1u;
uint const x_21 = arg_2;

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 60
; Bound: 58
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -44,63 +44,61 @@
%_ptr_Function_uint = OpTypePointer Function %uint
%bool = OpTypeBool
%x__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%18 = OpConstantNull %bool
%19 = OpConstantComposite %x__atomic_compare_exchange_resultu32 %6 %18
%18 = OpConstantNull %x__atomic_compare_exchange_resultu32
%_ptr_Function_x__atomic_compare_exchange_resultu32 = OpTypePointer Function %x__atomic_compare_exchange_resultu32
%22 = OpConstantNull %x__atomic_compare_exchange_resultu32
%uint_1 = OpConstant %uint 1
%__atomic_compare_exchange_resultu32 = OpTypeStruct %uint %bool
%uint_2 = OpConstant %uint 2
%uint_0 = OpConstant %uint 0
%36 = OpTypeFunction %void %uint
%34 = OpTypeFunction %void %uint
%uint_264 = OpConstant %uint 264
%atomicCompareExchangeWeak_83580d = OpFunction %void None %9
%12 = OpLabel
%arg_1 = OpVariable %_ptr_Function_uint Function %6
%arg_2 = OpVariable %_ptr_Function_uint Function %6
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %22
%res = OpVariable %_ptr_Function_x__atomic_compare_exchange_resultu32 Function %18
OpStore %arg_1 %6
OpStore %arg_2 %6
OpStore %res %19
OpStore %res %18
OpStore %arg_1 %uint_1
OpStore %arg_2 %uint_1
%24 = OpLoad %uint %arg_2
%25 = OpLoad %uint %arg_1
%31 = OpAtomicCompareExchange %uint %arg_0 %uint_2 %uint_0 %uint_0 %24 %25
%32 = OpIEqual %bool %31 %24
%26 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %31 %32
%33 = OpCompositeExtract %uint %26 0
%34 = OpIEqual %bool %33 %24
%35 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %33 %34
OpStore %res %35
%22 = OpLoad %uint %arg_2
%23 = OpLoad %uint %arg_1
%29 = OpAtomicCompareExchange %uint %arg_0 %uint_2 %uint_0 %uint_0 %22 %23
%30 = OpIEqual %bool %29 %22
%24 = OpCompositeConstruct %__atomic_compare_exchange_resultu32 %29 %30
%31 = OpCompositeExtract %uint %24 0
%32 = OpIEqual %bool %31 %22
%33 = OpCompositeConstruct %x__atomic_compare_exchange_resultu32 %31 %32
OpStore %res %33
OpReturn
OpFunctionEnd
%compute_main_inner = OpFunction %void None %36
%compute_main_inner = OpFunction %void None %34
%local_invocation_index = OpFunctionParameter %uint
%39 = OpLabel
%37 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %6
OpControlBarrier %uint_2 %uint_2 %uint_264
%44 = OpFunctionCall %void %atomicCompareExchangeWeak_83580d
%42 = OpFunctionCall %void %atomicCompareExchangeWeak_83580d
OpReturn
OpFunctionEnd
%compute_main_1 = OpFunction %void None %9
%46 = OpLabel
%47 = OpLoad %uint %local_invocation_index_1
%48 = OpFunctionCall %void %compute_main_inner %47
%44 = OpLabel
%45 = OpLoad %uint %local_invocation_index_1
%46 = OpFunctionCall %void %compute_main_inner %45
OpReturn
OpFunctionEnd
%compute_main_inner_1 = OpFunction %void None %36
%compute_main_inner_1 = OpFunction %void None %34
%local_invocation_index_1_param = OpFunctionParameter %uint
%51 = OpLabel
%49 = OpLabel
OpAtomicStore %arg_0 %uint_2 %uint_0 %6
OpControlBarrier %uint_2 %uint_2 %uint_264
OpStore %local_invocation_index_1 %local_invocation_index_1_param
%55 = OpFunctionCall %void %compute_main_1
%53 = OpFunctionCall %void %compute_main_1
OpReturn
OpFunctionEnd
%compute_main = OpFunction %void None %9
%57 = OpLabel
%59 = OpLoad %uint %local_invocation_index_1_param_1
%58 = OpFunctionCall %void %compute_main_inner_1 %59
%55 = OpLabel
%57 = OpLoad %uint %local_invocation_index_1_param_1
%56 = OpFunctionCall %void %compute_main_inner_1 %57
OpReturn
OpFunctionEnd

View File

@ -13,7 +13,7 @@ struct Interface {
};
Interface vert_main() {
Interface tint_symbol = Interface(0, 0u, ivec4(0, 0, 0, 0), uvec4(0u, 0u, 0u, 0u), vec4(0.0f, 0.0f, 0.0f, 0.0f));
Interface tint_symbol = Interface(0, 0u, ivec4(0), uvec4(0u), vec4(0.0f));
return tint_symbol;
}

View File

@ -21,7 +21,7 @@ struct Out {
};
Out tint_symbol_1() {
Out tint_symbol_3 = Out(vec4(0.0f, 0.0f, 0.0f, 0.0f), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
Out tint_symbol_3 = Out(vec4(0.0f), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
return tint_symbol_3;
}

View File

@ -5,7 +5,7 @@ struct Out {
};
Out tint_symbol() {
Out tint_symbol_1 = Out(vec4(0.0f, 0.0f, 0.0f, 0.0f));
Out tint_symbol_1 = Out(vec4(0.0f));
return tint_symbol_1;
}

View File

@ -20,7 +20,7 @@ int bar() {
}
void tint_symbol() {
S x = S(ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0)));
S x = S(ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0)));
int tint_symbol_3 = foo();
int tint_symbol_1_save = tint_symbol_3;
int tint_symbol_2 = bar();

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 25
; Bound: 22
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -10,17 +10,12 @@
OpName %unused_entry_point "unused_entry_point"
OpName %f "f"
OpName %i "i"
OpName %S "S"
OpMemberName %S 0 "i"
OpMemberDecorate %S 0 Offset 0
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Function_int = OpTypePointer Function %int
%10 = OpConstantNull %int
%S = OpTypeStruct %int
%int_1 = OpConstant %int 1
%19 = OpConstantComposite %S %int_1
%bool = OpTypeBool
%unused_entry_point = OpFunction %void None %1
%4 = OpLabel
@ -35,14 +30,13 @@
OpBranch %14
%14 = OpLabel
%16 = OpLoad %int %i
%20 = OpCompositeExtract %int %19 0
%21 = OpSLessThan %bool %16 %20
%15 = OpLogicalNot %bool %21
OpSelectionMerge %23 None
OpBranchConditional %15 %24 %23
%24 = OpLabel
%18 = OpSLessThan %bool %16 %int_1
%15 = OpLogicalNot %bool %18
OpSelectionMerge %20 None
OpBranchConditional %15 %21 %20
%21 = OpLabel
OpBranch %12
%23 = OpLabel
%20 = OpLabel
OpBranch %13
%13 = OpLabel
OpBranch %11

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 26
; Bound: 23
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -10,9 +10,6 @@
OpName %unused_entry_point "unused_entry_point"
OpName %f "f"
OpName %i "i"
OpName %S "S"
OpMemberName %S 0 "i"
OpMemberDecorate %S 0 Offset 0
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1
@ -20,9 +17,7 @@
%_ptr_Function_int = OpTypePointer Function %int
%bool = OpTypeBool
%17 = OpConstantNull %bool
%S = OpTypeStruct %int
%int_1 = OpConstant %int 1
%23 = OpConstantComposite %S %int_1
%unused_entry_point = OpFunction %void None %1
%4 = OpLabel
OpReturn
@ -45,9 +40,8 @@
OpBranch %13
%13 = OpLabel
%20 = OpLoad %int %i
%24 = OpCompositeExtract %int %23 0
%25 = OpIAdd %int %20 %24
OpStore %i %25
%22 = OpIAdd %int %20 %int_1
OpStore %i %22
OpBranch %11
%12 = OpLabel
OpReturn

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 24
; Bound: 21
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -9,43 +9,37 @@
OpExecutionMode %unused_entry_point LocalSize 1 1 1
OpName %unused_entry_point "unused_entry_point"
OpName %f "f"
OpName %S "S"
OpMemberName %S 0 "i"
OpName %i "i"
OpMemberDecorate %S 0 Offset 0
%void = OpTypeVoid
%1 = OpTypeFunction %void
%int = OpTypeInt 32 1
%S = OpTypeStruct %int
%int_1 = OpConstant %int 1
%10 = OpConstantComposite %S %int_1
%_ptr_Function_int = OpTypePointer Function %int
%14 = OpConstantNull %int
%11 = OpConstantNull %int
%bool = OpTypeBool
%21 = OpConstantNull %bool
%18 = OpConstantNull %bool
%unused_entry_point = OpFunction %void None %1
%4 = OpLabel
OpReturn
OpFunctionEnd
%f = OpFunction %void None %1
%6 = OpLabel
%i = OpVariable %_ptr_Function_int Function %14
%11 = OpCompositeExtract %int %10 0
OpStore %i %11
%i = OpVariable %_ptr_Function_int Function %11
OpStore %i %int_1
OpBranch %12
%12 = OpLabel
OpLoopMerge %13 %14 None
OpBranch %15
%15 = OpLabel
OpLoopMerge %16 %17 None
OpBranch %18
%18 = OpLabel
%19 = OpLogicalNot %bool %21
OpSelectionMerge %22 None
OpBranchConditional %19 %23 %22
%23 = OpLabel
OpBranch %16
%22 = OpLabel
OpBranch %17
%17 = OpLabel
OpBranch %15
%16 = OpLabel
%16 = OpLogicalNot %bool %18
OpSelectionMerge %19 None
OpBranchConditional %16 %20 %19
%20 = OpLabel
OpBranch %13
%19 = OpLabel
OpBranch %14
%14 = OpLabel
OpBranch %12
%13 = OpLabel
OpReturn
OpFunctionEnd

View File

@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
; Bound: 74
; Bound: 68
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@ -58,20 +58,18 @@
%27 = OpConstantComposite %S1 %int_7 %int_8 %int_9 %int_10
%28 = OpConstantComposite %S2 %int_6 %27
%29 = OpConstantComposite %S3 %int_1 %21 %28
%43 = OpConstantNull %S2
%45 = OpConstantComposite %S2 %int_1 %21
%37 = OpConstantNull %int
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%_arr_int_uint_2 = OpTypeArray %int %uint_2
%T = OpTypeStruct %_arr_int_uint_2
%_arr_T_uint_2 = OpTypeArray %T %uint_2
%59 = OpConstantNull %_arr_T_uint_2
%60 = OpConstantComposite %_arr_int_uint_2 %int_1 %int_2
%61 = OpConstantComposite %T %60
%62 = OpConstantComposite %_arr_int_uint_2 %int_3 %int_4
%63 = OpConstantComposite %T %62
%64 = OpConstantComposite %_arr_T_uint_2 %61 %63
%65 = OpConstantNull %int
%54 = OpConstantNull %_arr_T_uint_2
%55 = OpConstantComposite %_arr_int_uint_2 %int_1 %int_2
%56 = OpConstantComposite %T %55
%57 = OpConstantComposite %_arr_int_uint_2 %int_3 %int_4
%58 = OpConstantComposite %T %57
%59 = OpConstantComposite %_arr_T_uint_2 %56 %58
%main = OpFunction %void None %1
%4 = OpLabel
%14 = OpIAdd %int %int_42 %int_1
@ -84,28 +82,24 @@
%34 = OpCompositeConstruct %S1 %int_2 %int_42 %30 %33
%35 = OpCompositeConstruct %S2 %int_6 %13
%36 = OpCompositeConstruct %S3 %int_1 %34 %35
%37 = OpCompositeExtract %int %8 0
%38 = OpCompositeExtract %int %13 1
%39 = OpIAdd %int %int_42 %int_1
%40 = OpCompositeExtract %int %13 3
%41 = OpCompositeConstruct %S1 %int_1 %int_42 %39 %40
%42 = OpCompositeExtract %int %41 2
%38 = OpIAdd %int %int_42 %int_1
%39 = OpCompositeExtract %int %13 3
%40 = OpCompositeConstruct %S1 %int_1 %int_42 %38 %39
%41 = OpCompositeExtract %int %40 2
%42 = OpIAdd %int %int_42 %int_1
%43 = OpCompositeExtract %S2 %29 2
%44 = OpCompositeExtract %S1 %43 1
%46 = OpCompositeExtract %S1 %45 1
%47 = OpIAdd %int %int_42 %int_1
%48 = OpCompositeExtract %S2 %29 2
%49 = OpCompositeExtract %S1 %48 1
%50 = OpCompositeExtract %int %49 3
%51 = OpCompositeConstruct %S1 %int_2 %int_42 %47 %50
%52 = OpCompositeConstruct %S2 %int_1 %51
%53 = OpCompositeExtract %S1 %52 1
%66 = OpCompositeExtract %T %64 0
%67 = OpCompositeExtract %_arr_int_uint_2 %66 0
%68 = OpCompositeExtract %int %67 0
%69 = OpIAdd %int %68 %int_1
%70 = OpCompositeConstruct %_arr_int_uint_2 %int_1 %69
%71 = OpCompositeConstruct %T %70
%72 = OpCompositeExtract %T %64 1
%73 = OpCompositeConstruct %_arr_T_uint_2 %71 %72
%45 = OpCompositeExtract %int %44 3
%46 = OpCompositeConstruct %S1 %int_2 %int_42 %42 %45
%47 = OpCompositeConstruct %S2 %int_1 %46
%48 = OpCompositeExtract %S1 %47 1
%60 = OpCompositeExtract %T %59 0
%61 = OpCompositeExtract %_arr_int_uint_2 %60 0
%62 = OpCompositeExtract %int %61 0
%63 = OpIAdd %int %62 %int_1
%64 = OpCompositeConstruct %_arr_int_uint_2 %int_1 %63
%65 = OpCompositeConstruct %T %64
%66 = OpCompositeExtract %T %59 1
%67 = OpCompositeConstruct %_arr_T_uint_2 %65 %66
OpReturn
OpFunctionEnd

View File

@ -18,7 +18,7 @@ struct S {
};
void tint_symbol() {
S s = S(false, 0, 0u, 0.0f, ivec2(0, 0), uvec3(0u, 0u, 0u), vec4(0.0f, 0.0f, 0.0f, 0.0f), mat2x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f), float[4](0.0f, 0.0f, 0.0f, 0.0f), S_inner(0.0f));
S s = S(false, 0, 0u, 0.0f, ivec2(0), uvec3(0u), vec4(0.0f), mat2x3(vec3(0.0f), vec3(0.0f)), float[4](0.0f, 0.0f, 0.0f, 0.0f), S_inner(0.0f));
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;