tint/sem: Support arrays for sem::Constant
https://github.com/gpuweb/gpuweb/issues/3056 proposes that creation-time constant expressions should support arrays. We have verbal agreement to update to spec to support const arrays. Bug: tint:1580 Change-Id: If460f729384d700a1c2149c5b7dbe8613a960184 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94330 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
c174692187
commit
3c054304a8
|
@ -178,14 +178,13 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::CallExpression* call,
|
||||||
const sem::Type* ty) {
|
const sem::Type* ty) {
|
||||||
uint32_t num_elems = 0;
|
uint32_t num_elems = 0;
|
||||||
auto* el_ty = sem::Type::DeepestElementOf(ty, &num_elems);
|
auto* el_ty = sem::Type::DeepestElementOf(ty, &num_elems);
|
||||||
if (!el_ty) {
|
if (!el_ty || num_elems == 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ElementOf() will also return the element type of array, which we do not support.
|
// Note: we are building constant values for array types. The working group as verbally agreed
|
||||||
if (ty->Is<sem::Array>()) {
|
// to support constant expression arrays, but this is not (yet) part of the spec.
|
||||||
return sem::Constant{};
|
// See: https://github.com/gpuweb/gpuweb/issues/3056
|
||||||
}
|
|
||||||
|
|
||||||
// For zero value init, return 0s
|
// For zero value init, return 0s
|
||||||
if (call->args.empty()) {
|
if (call->args.empty()) {
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace {
|
||||||
|
|
||||||
using ResolverConstantsTest = ResolverTest;
|
using ResolverConstantsTest = ResolverTest;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Construction
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TEST_F(ResolverConstantsTest, Scalar_i32) {
|
TEST_F(ResolverConstantsTest, Scalar_i32) {
|
||||||
auto* expr = Expr(99_i);
|
auto* expr = Expr(99_i);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -32,7 +36,7 @@ TEST_F(ResolverConstantsTest, Scalar_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_TRUE(sem->Type()->Is<sem::I32>());
|
EXPECT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
||||||
|
@ -47,7 +51,7 @@ TEST_F(ResolverConstantsTest, Scalar_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_TRUE(sem->Type()->Is<sem::U32>());
|
EXPECT_TRUE(sem->Type()->Is<sem::U32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
||||||
|
@ -62,7 +66,7 @@ TEST_F(ResolverConstantsTest, Scalar_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_TRUE(sem->Type()->Is<sem::F32>());
|
EXPECT_TRUE(sem->Type()->Is<sem::F32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
||||||
|
@ -77,7 +81,7 @@ TEST_F(ResolverConstantsTest, Scalar_bool) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
EXPECT_TRUE(sem->Type()->Is<sem::Bool>());
|
EXPECT_TRUE(sem->Type()->Is<sem::Bool>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().ElementType(), sem->Type());
|
||||||
|
@ -92,7 +96,7 @@ TEST_F(ResolverConstantsTest, Vec3_ZeroInit_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -112,7 +116,7 @@ TEST_F(ResolverConstantsTest, Vec3_ZeroInit_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
||||||
|
@ -132,7 +136,7 @@ TEST_F(ResolverConstantsTest, Vec3_ZeroInit_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
@ -152,7 +156,7 @@ TEST_F(ResolverConstantsTest, Vec3_ZeroInit_bool) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
||||||
|
@ -172,7 +176,7 @@ TEST_F(ResolverConstantsTest, Vec3_Splat_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -192,7 +196,7 @@ TEST_F(ResolverConstantsTest, Vec3_Splat_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
||||||
|
@ -212,7 +216,7 @@ TEST_F(ResolverConstantsTest, Vec3_Splat_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
@ -232,7 +236,7 @@ TEST_F(ResolverConstantsTest, Vec3_Splat_bool) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
||||||
|
@ -252,7 +256,7 @@ TEST_F(ResolverConstantsTest, Vec3_FullConstruct_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -272,7 +276,7 @@ TEST_F(ResolverConstantsTest, Vec3_FullConstruct_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
||||||
|
@ -292,7 +296,7 @@ TEST_F(ResolverConstantsTest, Vec3_FullConstruct_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
@ -312,7 +316,7 @@ TEST_F(ResolverConstantsTest, Vec3_FullConstruct_bool) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
||||||
|
@ -332,7 +336,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -352,7 +356,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
||||||
|
@ -372,7 +376,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
@ -392,7 +396,7 @@ TEST_F(ResolverConstantsTest, Vec3_MixConstruct_bool) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
EXPECT_TRUE(vec->type()->Is<sem::Bool>());
|
||||||
|
@ -412,7 +416,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_f32_to_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -432,7 +436,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_u32_to_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
@ -452,7 +456,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_Large_f32_to_i32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
EXPECT_TRUE(vec->type()->Is<sem::I32>());
|
||||||
|
@ -472,7 +476,7 @@ TEST_F(ResolverConstantsTest, Vec3_Convert_Large_f32_to_u32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
EXPECT_TRUE(vec->type()->Is<sem::U32>());
|
||||||
|
@ -497,7 +501,7 @@ TEST_F(ResolverConstantsTest, DISABLED_Vec3_Convert_Large_f32_to_f16) {
|
||||||
constexpr auto kInf = std::numeric_limits<double>::infinity();
|
constexpr auto kInf = std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F16>());
|
EXPECT_TRUE(vec->type()->Is<sem::F16>());
|
||||||
|
@ -520,7 +524,7 @@ TEST_F(ResolverConstantsTest, DISABLED_Vec3_Convert_Small_f32_to_f16) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_TRUE(vec->type()->Is<sem::F16>());
|
EXPECT_TRUE(vec->type()->Is<sem::F16>());
|
||||||
|
@ -540,7 +544,7 @@ TEST_F(ResolverConstantsTest, Mat2x3_ZeroInit_f32) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* mat = sem->Type()->As<sem::Matrix>();
|
auto* mat = sem->Type()->As<sem::Matrix>();
|
||||||
ASSERT_NE(mat, nullptr);
|
ASSERT_NE(mat, nullptr);
|
||||||
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
||||||
|
@ -564,7 +568,7 @@ TEST_F(ResolverConstantsTest, Mat3x2_Construct_Scalars_af) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* mat = sem->Type()->As<sem::Matrix>();
|
auto* mat = sem->Type()->As<sem::Matrix>();
|
||||||
ASSERT_NE(mat, nullptr);
|
ASSERT_NE(mat, nullptr);
|
||||||
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
||||||
|
@ -591,7 +595,7 @@ TEST_F(ResolverConstantsTest, Mat3x2_Construct_Columns_af) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* mat = sem->Type()->As<sem::Matrix>();
|
auto* mat = sem->Type()->As<sem::Matrix>();
|
||||||
ASSERT_NE(mat, nullptr);
|
ASSERT_NE(mat, nullptr);
|
||||||
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
EXPECT_TRUE(mat->type()->Is<sem::F32>());
|
||||||
|
@ -608,6 +612,141 @@ TEST_F(ResolverConstantsTest, Mat3x2_Construct_Columns_af) {
|
||||||
EXPECT_EQ(sem->ConstantValue().Element<AFloat>(5).value, 6._a);
|
EXPECT_EQ(sem->ConstantValue().Element<AFloat>(5).value, 6._a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_i32_Zero) {
|
||||||
|
auto* expr = Construct(ty.array<i32, 4>());
|
||||||
|
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::I32>());
|
||||||
|
EXPECT_EQ(arr->Count(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(0).value, 0_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(1).value, 0_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(2).value, 0_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(3).value, 0_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_f32_Zero) {
|
||||||
|
auto* expr = Construct(ty.array<f32, 4>());
|
||||||
|
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::F32>());
|
||||||
|
EXPECT_EQ(arr->Count(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(3).value, 0_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_vec3_f32_Zero) {
|
||||||
|
auto* expr = Construct(ty.array(ty.vec3<f32>(), 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::Vector>());
|
||||||
|
EXPECT_EQ(arr->Count(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 6u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(3).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(4).value, 0_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(5).value, 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);
|
||||||
|
|
||||||
|
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::I32>());
|
||||||
|
EXPECT_EQ(arr->Count(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(0).value, 10_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(1).value, 20_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(2).value, 30_i);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(3).value, 40_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_f32_Elements) {
|
||||||
|
auto* expr = Construct(ty.array<f32, 4>(), 10_f, 20_f, 30_f, 40_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::F32>());
|
||||||
|
EXPECT_EQ(arr->Count(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 4u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 10_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 20_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 30_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(3).value, 40_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_vec3_f32_Elements) {
|
||||||
|
auto* expr = Construct(ty.array(ty.vec3<f32>(), 2_u), //
|
||||||
|
vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_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::Vector>());
|
||||||
|
EXPECT_EQ(arr->Count(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 6u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 1_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 2_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 3_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(3).value, 4_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(4).value, 5_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(5).value, 6_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Indexing
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TEST_F(ResolverConstantsTest, Vec3_Index) {
|
TEST_F(ResolverConstantsTest, Vec3_Index) {
|
||||||
auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), 2_i);
|
auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), 2_i);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -615,7 +754,7 @@ TEST_F(ResolverConstantsTest, Vec3_Index) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
@ -631,7 +770,7 @@ TEST_F(ResolverConstantsTest, Vec3_Index_OOB_High) {
|
||||||
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
@ -647,7 +786,7 @@ TEST_F(ResolverConstantsTest, Vec3_Index_OOB_Low) {
|
||||||
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
@ -663,7 +802,7 @@ TEST_F(ResolverConstantsTest, Mat3x2_Index) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_EQ(vec->Width(), 2u);
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
@ -684,7 +823,7 @@ TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_High) {
|
||||||
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_EQ(vec->Width(), 2u);
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
@ -705,7 +844,7 @@ TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_Low) {
|
||||||
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
||||||
|
|
||||||
auto* sem = Sem().Get(expr);
|
auto* sem = Sem().Get(expr);
|
||||||
EXPECT_NE(sem, nullptr);
|
ASSERT_NE(sem, nullptr);
|
||||||
auto* vec = sem->Type()->As<sem::Vector>();
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
ASSERT_NE(vec, nullptr);
|
ASSERT_NE(vec, nullptr);
|
||||||
EXPECT_EQ(vec->Width(), 2u);
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
@ -716,5 +855,190 @@ TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_Low) {
|
||||||
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 2._a);
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 2._a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_vec3_f32_Index) {
|
||||||
|
auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
|
||||||
|
vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
|
||||||
|
1_i);
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
ASSERT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(vec->Width(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 4_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 5_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 6_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_vec3_f32_Index_OOB_High) {
|
||||||
|
auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
|
||||||
|
vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
|
||||||
|
Expr(Source{{12, 34}}, 2_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index 2 out of bounds [0..1]. Clamping index to 1");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
ASSERT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(vec->Width(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 4_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 5_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 6_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Array_vec3_f32_Index_OOB_Low) {
|
||||||
|
auto* expr = IndexAccessor(Construct(ty.array(ty.vec3<f32>(), 2_u), //
|
||||||
|
vec3<f32>(1_f, 2_f, 3_f), vec3<f32>(4_f, 5_f, 6_f)),
|
||||||
|
Expr(Source{{12, 34}}, -2_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index -2 out of bounds [0..1]. Clamping index to 0");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
ASSERT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_TRUE(vec->type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(vec->Width(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 3u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 1_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 2_f);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(2).value, 3_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, ChainedIndex) {
|
||||||
|
auto* arr_expr = Construct(ty.array(ty.mat2x3<f32>(), 2_u), // array<mat2x3<f32>, 2u>
|
||||||
|
mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f), //
|
||||||
|
vec3<f32>(4_f, 5_f, 6_f)), //
|
||||||
|
mat2x3<f32>(vec3<f32>(7_f, 8_f, 9_f), //
|
||||||
|
vec3<f32>(10_f, 11_f, 12_f)));
|
||||||
|
|
||||||
|
auto* mat_expr = IndexAccessor(arr_expr, 1_i); // arr[1]
|
||||||
|
auto* vec_expr = IndexAccessor(mat_expr, 0_i); // arr[1][0]
|
||||||
|
auto* f32_expr = IndexAccessor(vec_expr, 2_i); // arr[1][0][2]
|
||||||
|
WrapInFunction(f32_expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
{
|
||||||
|
auto* mat = Sem().Get(mat_expr);
|
||||||
|
EXPECT_NE(mat, nullptr);
|
||||||
|
auto* ty = mat->Type()->As<sem::Matrix>();
|
||||||
|
ASSERT_NE(mat->Type(), nullptr);
|
||||||
|
EXPECT_TRUE(ty->ColumnType()->Is<sem::Vector>());
|
||||||
|
EXPECT_EQ(ty->columns(), 2u);
|
||||||
|
EXPECT_EQ(ty->rows(), 3u);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Type(), mat->Type());
|
||||||
|
EXPECT_TRUE(mat->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(mat->ConstantValue().ElementCount(), 6u);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(0).value, 7_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(1).value, 8_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(2).value, 9_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(3).value, 10_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(4).value, 11_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(5).value, 12_f);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto* vec = Sem().Get(vec_expr);
|
||||||
|
EXPECT_NE(vec, nullptr);
|
||||||
|
auto* ty = vec->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec->Type(), nullptr);
|
||||||
|
EXPECT_TRUE(ty->type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(ty->Width(), 3u);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Type(), vec->Type());
|
||||||
|
EXPECT_TRUE(vec->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(vec->ConstantValue().ElementCount(), 3u);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(0).value, 7_f);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(1).value, 8_f);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(2).value, 9_f);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto* f = Sem().Get(f32_expr);
|
||||||
|
EXPECT_NE(f, nullptr);
|
||||||
|
EXPECT_TRUE(f->Type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(f->ConstantValue().Type(), f->Type());
|
||||||
|
EXPECT_TRUE(f->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(f->ConstantValue().ElementCount(), 1u);
|
||||||
|
EXPECT_EQ(f->ConstantValue().Element<f32>(0).value, 9_f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, ChainedIndex_OOB) {
|
||||||
|
auto* arr_expr = Construct(ty.array(ty.mat2x3<f32>(), 2_u), // array<mat2x3<f32>, 2u>
|
||||||
|
mat2x3<f32>(vec3<f32>(1_f, 2_f, 3_f), //
|
||||||
|
vec3<f32>(4_f, 5_f, 6_f)), //
|
||||||
|
mat2x3<f32>(vec3<f32>(7_f, 8_f, 9_f), //
|
||||||
|
vec3<f32>(10_f, 11_f, 12_f)));
|
||||||
|
|
||||||
|
auto* mat_expr = IndexAccessor(arr_expr, Expr(Source{{1, 2}}, -3_i)); // arr[3]
|
||||||
|
auto* vec_expr = IndexAccessor(mat_expr, Expr(Source{{3, 4}}, -2_i)); // arr[3][-2]
|
||||||
|
auto* f32_expr = IndexAccessor(vec_expr, Expr(Source{{5, 6}}, 4_i)); // arr[3][-2][4]
|
||||||
|
WrapInFunction(f32_expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), R"(1:2 warning: index -3 out of bounds [0..1]. Clamping index to 0
|
||||||
|
3:4 warning: index -2 out of bounds [0..1]. Clamping index to 0
|
||||||
|
5:6 warning: index 4 out of bounds [0..2]. Clamping index to 2)");
|
||||||
|
|
||||||
|
{
|
||||||
|
auto* mat = Sem().Get(mat_expr);
|
||||||
|
EXPECT_NE(mat, nullptr);
|
||||||
|
auto* ty = mat->Type()->As<sem::Matrix>();
|
||||||
|
ASSERT_NE(mat->Type(), nullptr);
|
||||||
|
EXPECT_TRUE(ty->ColumnType()->Is<sem::Vector>());
|
||||||
|
EXPECT_EQ(ty->columns(), 2u);
|
||||||
|
EXPECT_EQ(ty->rows(), 3u);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Type(), mat->Type());
|
||||||
|
EXPECT_TRUE(mat->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(mat->ConstantValue().ElementCount(), 6u);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(0).value, 1_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(1).value, 2_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(2).value, 3_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(3).value, 4_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(4).value, 5_f);
|
||||||
|
EXPECT_EQ(mat->ConstantValue().Element<f32>(5).value, 6_f);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto* vec = Sem().Get(vec_expr);
|
||||||
|
EXPECT_NE(vec, nullptr);
|
||||||
|
auto* ty = vec->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec->Type(), nullptr);
|
||||||
|
EXPECT_TRUE(ty->type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(ty->Width(), 3u);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Type(), vec->Type());
|
||||||
|
EXPECT_TRUE(vec->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(vec->ConstantValue().ElementCount(), 3u);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(0).value, 1_f);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(1).value, 2_f);
|
||||||
|
EXPECT_EQ(vec->ConstantValue().Element<f32>(2).value, 3_f);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto* f = Sem().Get(f32_expr);
|
||||||
|
EXPECT_NE(f, nullptr);
|
||||||
|
EXPECT_TRUE(f->Type()->Is<sem::F32>());
|
||||||
|
EXPECT_EQ(f->ConstantValue().Type(), f->Type());
|
||||||
|
EXPECT_TRUE(f->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(f->ConstantValue().ElementCount(), 1u);
|
||||||
|
EXPECT_EQ(f->ConstantValue().Element<f32>(0).value, 3_f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint::resolver
|
} // namespace tint::resolver
|
||||||
|
|
|
@ -97,18 +97,19 @@ bool Constant::AllEqual(size_t start, size_t end) const {
|
||||||
|
|
||||||
const Type* Constant::CheckElemType(const sem::Type* ty, size_t num_elements) {
|
const Type* Constant::CheckElemType(const sem::Type* ty, size_t num_elements) {
|
||||||
diag::List diag;
|
diag::List diag;
|
||||||
if (ty->is_abstract_or_scalar() || ty->IsAnyOf<Vector, Matrix>()) {
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
auto* el_ty = Type::DeepestElementOf(ty, &count);
|
auto* el_ty = Type::DeepestElementOf(ty, &count);
|
||||||
|
if (!el_ty) {
|
||||||
|
TINT_ICE(Semantic, diag) << "Unsupported sem::Constant type: " << ty->TypeInfo().name;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (num_elements != count) {
|
if (num_elements != count) {
|
||||||
TINT_ICE(Semantic, diag) << "sem::Constant() type <-> element mismatch. type: '"
|
TINT_ICE(Semantic, diag) << "sem::Constant() type <-> element mismatch. type: '"
|
||||||
<< ty->TypeInfo().name << "' element: " << num_elements;
|
<< ty->TypeInfo().name << "' provided: " << num_elements
|
||||||
|
<< " require: " << count;
|
||||||
}
|
}
|
||||||
TINT_ASSERT(Semantic, el_ty->is_abstract_or_scalar());
|
TINT_ASSERT(Semantic, el_ty->is_abstract_or_scalar());
|
||||||
return el_ty;
|
return el_ty;
|
||||||
}
|
|
||||||
TINT_UNREACHABLE(Semantic, diag) << "Unsupported sem::Constant type: " << ty->TypeInfo().name;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
|
@ -25,7 +25,16 @@ using namespace tint::number_suffixes; // NOLINT
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using ConstantTest = TestHelper;
|
struct ConstantTest : public TestHelper {
|
||||||
|
const sem::Array* Array(uint32_t n, const sem::Type* el_ty) {
|
||||||
|
return create<sem::Array>(el_ty,
|
||||||
|
/* count */ n,
|
||||||
|
/* align */ 16u,
|
||||||
|
/* size */ 4u * n,
|
||||||
|
/* stride */ 16u * n,
|
||||||
|
/* implicit_stride */ 16u * n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
TEST_F(ConstantTest, ConstructorInitializerList) {
|
TEST_F(ConstantTest, ConstructorInitializerList) {
|
||||||
{
|
{
|
||||||
|
@ -259,6 +268,133 @@ TEST_F(ConstantTest, Element_mat2x3_f16) {
|
||||||
EXPECT_TYPE(c.ElementType(), el_ty);
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_ai) {
|
||||||
|
auto* el_ty = create<AbstractInt>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1_a, 2_a, 3_a, 4_a, 5_a, 6_a});
|
||||||
|
EXPECT_EQ(c.Element<AInt>(0), 1_a);
|
||||||
|
EXPECT_EQ(c.Element<AInt>(1), 2_a);
|
||||||
|
EXPECT_EQ(c.Element<AInt>(2), 3_a);
|
||||||
|
EXPECT_EQ(c.Element<AInt>(3), 4_a);
|
||||||
|
EXPECT_EQ(c.Element<AInt>(4), 5_a);
|
||||||
|
EXPECT_EQ(c.Element<AInt>(5), 6_a);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_i32) {
|
||||||
|
auto* el_ty = create<I32>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1_a, 2_a, 3_a, 4_a, 5_a, 6_a});
|
||||||
|
EXPECT_EQ(c.Element<i32>(0), 1_i);
|
||||||
|
EXPECT_EQ(c.Element<i32>(1), 2_i);
|
||||||
|
EXPECT_EQ(c.Element<i32>(2), 3_i);
|
||||||
|
EXPECT_EQ(c.Element<i32>(3), 4_i);
|
||||||
|
EXPECT_EQ(c.Element<i32>(4), 5_i);
|
||||||
|
EXPECT_EQ(c.Element<i32>(5), 6_i);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_u32) {
|
||||||
|
auto* el_ty = create<U32>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1_a, 2_a, 3_a, 4_a, 5_a, 6_a});
|
||||||
|
EXPECT_EQ(c.Element<u32>(0), 1_u);
|
||||||
|
EXPECT_EQ(c.Element<u32>(1), 2_u);
|
||||||
|
EXPECT_EQ(c.Element<u32>(2), 3_u);
|
||||||
|
EXPECT_EQ(c.Element<u32>(3), 4_u);
|
||||||
|
EXPECT_EQ(c.Element<u32>(4), 5_u);
|
||||||
|
EXPECT_EQ(c.Element<u32>(5), 6_u);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_bool) {
|
||||||
|
auto* el_ty = create<Bool>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 2u));
|
||||||
|
Constant c(ty, {true, false, false, true});
|
||||||
|
EXPECT_EQ(c.Element<bool>(0), true);
|
||||||
|
EXPECT_EQ(c.Element<bool>(1), false);
|
||||||
|
EXPECT_EQ(c.Element<bool>(2), false);
|
||||||
|
EXPECT_EQ(c.Element<bool>(3), true);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 4u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_af) {
|
||||||
|
auto* el_ty = create<AbstractFloat>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(0), 1.0_a);
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(1), 2.0_a);
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(2), 3.0_a);
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(3), 4.0_a);
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(4), 5.0_a);
|
||||||
|
EXPECT_EQ(c.Element<AFloat>(5), 6.0_a);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_f32) {
|
||||||
|
auto* el_ty = create<F32>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
|
||||||
|
EXPECT_EQ(c.Element<f32>(0), 1.0_f);
|
||||||
|
EXPECT_EQ(c.Element<f32>(1), 2.0_f);
|
||||||
|
EXPECT_EQ(c.Element<f32>(2), 3.0_f);
|
||||||
|
EXPECT_EQ(c.Element<f32>(3), 4.0_f);
|
||||||
|
EXPECT_EQ(c.Element<f32>(4), 5.0_f);
|
||||||
|
EXPECT_EQ(c.Element<f32>(5), 6.0_f);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_vec3_f16) {
|
||||||
|
auto* el_ty = create<F16>();
|
||||||
|
auto* ty = Array(2, create<Vector>(el_ty, 3u));
|
||||||
|
Constant c(ty, {1.0_a, 2.0_a, 3.0_a, 4.0_a, 5.0_a, 6.0_a});
|
||||||
|
EXPECT_EQ(c.Element<f16>(0), 1.0_h);
|
||||||
|
EXPECT_EQ(c.Element<f16>(1), 2.0_h);
|
||||||
|
EXPECT_EQ(c.Element<f16>(2), 3.0_h);
|
||||||
|
EXPECT_EQ(c.Element<f16>(3), 4.0_h);
|
||||||
|
EXPECT_EQ(c.Element<f16>(4), 5.0_h);
|
||||||
|
EXPECT_EQ(c.Element<f16>(5), 6.0_h);
|
||||||
|
EXPECT_EQ(c.ElementCount(), 6u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ConstantTest, Element_arr_arr_mat2x3_f32) {
|
||||||
|
auto* el_ty = create<F32>();
|
||||||
|
auto* ty = Array(2, Array(2, create<Matrix>(create<Vector>(el_ty, 3u), 2u)));
|
||||||
|
Constant c(ty, {
|
||||||
|
1.0_a, 2.0_a, 3.0_a, //
|
||||||
|
4.0_a, 5.0_a, 6.0_a, //
|
||||||
|
|
||||||
|
7.0_a, 8.0_a, 9.0_a, //
|
||||||
|
10.0_a, 11.0_a, 12.0_a, //
|
||||||
|
|
||||||
|
13.0_a, 14.0_a, 15.0_a, //
|
||||||
|
16.0_a, 17.0_a, 18.0_a, //
|
||||||
|
|
||||||
|
19.0_a, 20.0_a, 21.0_a, //
|
||||||
|
22.0_a, 23.0_a, 24.0_a, //
|
||||||
|
});
|
||||||
|
for (size_t i = 0; i < 24; i++) {
|
||||||
|
EXPECT_EQ(c.Element<f32>(i), f32(i + 1));
|
||||||
|
}
|
||||||
|
EXPECT_EQ(c.ElementCount(), 24u);
|
||||||
|
EXPECT_TYPE(c.Type(), ty);
|
||||||
|
EXPECT_TYPE(c.ElementType(), el_ty);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ConstantTest, AnyZero) {
|
TEST_F(ConstantTest, AnyZero) {
|
||||||
auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
|
auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u);
|
||||||
EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AnyZero(), false);
|
EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AnyZero(), false);
|
||||||
|
|
|
@ -1767,9 +1767,14 @@ bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
||||||
if (auto* sem = builder_.Sem().Get(expr)) {
|
if (auto* sem = builder_.Sem().Get(expr)) {
|
||||||
if (auto constant = sem->ConstantValue()) {
|
if (auto constant = sem->ConstantValue()) {
|
||||||
|
// We do not want to inline array constants, as this will undo the work of
|
||||||
|
// PromoteInitializersToConstVar, which ensures that arrays are declarated in 'let's
|
||||||
|
// before their usage.
|
||||||
|
if (!constant.Type()->Is<sem::Array>()) {
|
||||||
return EmitConstant(out, constant);
|
return EmitConstant(out, constant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Switch(
|
return Switch(
|
||||||
expr,
|
expr,
|
||||||
[&](const ast::IndexAccessorExpression* a) { //
|
[&](const ast::IndexAccessorExpression* a) { //
|
||||||
|
@ -2258,8 +2263,7 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const sem::Matrix* m) {
|
[&](const sem::Matrix* m) {
|
||||||
if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined,
|
if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
|
||||||
"")) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,12 +156,11 @@ void main() {
|
||||||
|
|
||||||
TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
|
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
|
||||||
auto* array_index = IndexAccessor(array_init, 3_i);
|
|
||||||
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
|
||||||
|
|
||||||
Func("main", {}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(Var("idx", nullptr, Expr(3_i))),
|
||||||
|
Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
@ -176,8 +175,9 @@ TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
void tint_symbol() {
|
void tint_symbol() {
|
||||||
|
int idx = 3;
|
||||||
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
|
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
|
||||||
int pos = tint_symbol_1[3];
|
int pos = tint_symbol_1[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
|
@ -2651,9 +2651,14 @@ bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
||||||
if (auto* sem = builder_.Sem().Get(expr)) {
|
if (auto* sem = builder_.Sem().Get(expr)) {
|
||||||
if (auto constant = sem->ConstantValue()) {
|
if (auto constant = sem->ConstantValue()) {
|
||||||
|
// We do not want to inline array constants, as this will undo the work of
|
||||||
|
// PromoteInitializersToConstVar, which ensures that arrays are declarated in 'let's
|
||||||
|
// before their usage.
|
||||||
|
if (!constant.Type()->Is<sem::Array>()) {
|
||||||
return EmitConstant(out, constant);
|
return EmitConstant(out, constant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Switch(
|
return Switch(
|
||||||
expr,
|
expr,
|
||||||
[&](const ast::IndexAccessorExpression* a) { //
|
[&](const ast::IndexAccessorExpression* a) { //
|
||||||
|
|
|
@ -188,12 +188,11 @@ void a_func() {
|
||||||
|
|
||||||
TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
|
auto* array_init = array<i32, 4>(1_i, 2_i, 3_i, 4_i);
|
||||||
auto* array_index = IndexAccessor(array_init, 3_i);
|
|
||||||
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
|
||||||
|
|
||||||
Func("main", {}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(Var("idx", nullptr, Expr(3_i))),
|
||||||
|
Decl(Var("pos", ty.i32(), IndexAccessor(array_init, "idx"))),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
@ -205,8 +204,9 @@ TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
|
|
||||||
auto got = gen.result();
|
auto got = gen.result();
|
||||||
auto* expect = R"(void main() {
|
auto* expect = R"(void main() {
|
||||||
|
int idx = 3;
|
||||||
const int tint_symbol[4] = {1, 2, 3, 4};
|
const int tint_symbol[4] = {1, 2, 3, 4};
|
||||||
int pos = tint_symbol[3];
|
int pos = tint_symbol[idx];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
|
@ -1691,9 +1691,14 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression*
|
||||||
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) {
|
||||||
if (auto* sem = builder_.Sem().Get(expr)) {
|
if (auto* sem = builder_.Sem().Get(expr)) {
|
||||||
if (auto constant = sem->ConstantValue()) {
|
if (auto constant = sem->ConstantValue()) {
|
||||||
|
// We do not want to inline array constants, as this will undo the work of
|
||||||
|
// PromoteInitializersToConstVar, which ensures that arrays are declarated in 'let's
|
||||||
|
// before their usage.
|
||||||
|
if (!constant.Type()->Is<sem::Array>()) {
|
||||||
return EmitConstant(out, constant);
|
return EmitConstant(out, constant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Switch(
|
return Switch(
|
||||||
expr,
|
expr,
|
||||||
[&](const ast::IndexAccessorExpression* a) { //
|
[&](const ast::IndexAccessorExpression* a) { //
|
||||||
|
|
|
@ -274,18 +274,13 @@ TEST_F(BuilderTest, Const_IndexAccessor_Array_MultiLevel) {
|
||||||
%16 = OpConstant %7 6
|
%16 = OpConstant %7 6
|
||||||
%17 = OpConstantComposite %6 %14 %15 %16
|
%17 = OpConstantComposite %6 %14 %15 %16
|
||||||
%18 = OpConstantComposite %5 %13 %17
|
%18 = OpConstantComposite %5 %13 %17
|
||||||
%19 = OpTypeInt 32 1
|
%20 = OpTypePointer Function %7
|
||||||
%20 = OpConstant %19 1
|
%21 = OpConstantNull %7
|
||||||
%22 = OpConstant %19 2
|
|
||||||
%25 = OpTypePointer Function %7
|
|
||||||
%26 = OpConstantNull %7
|
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
|
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%19 = OpVariable %20 Function %21
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||||
R"(%21 = OpCompositeExtract %6 %18 1
|
R"(OpStore %19 %16
|
||||||
%23 = OpCompositeExtract %7 %21 2
|
|
||||||
OpStore %24 %23
|
|
||||||
OpReturn
|
OpReturn
|
||||||
)");
|
)");
|
||||||
|
|
||||||
|
@ -546,16 +541,12 @@ TEST_F(BuilderTest, Const_IndexAccessor_Nested_Array_f32) {
|
||||||
%14 = OpConstantComposite %6 %13 %13
|
%14 = OpConstantComposite %6 %13 %13
|
||||||
%15 = OpConstantComposite %6 %11 %13
|
%15 = OpConstantComposite %6 %11 %13
|
||||||
%16 = OpConstantComposite %5 %12 %14 %15
|
%16 = OpConstantComposite %5 %12 %14 %15
|
||||||
%17 = OpConstant %8 1
|
%18 = OpTypePointer Function %7
|
||||||
%19 = OpConstantNull %8
|
|
||||||
%22 = OpTypePointer Function %7
|
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%21 = OpVariable %22 Function %10
|
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%17 = OpVariable %18 Function %10
|
||||||
)");
|
)");
|
||||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||||
R"(%18 = OpCompositeExtract %6 %16 1
|
R"(OpStore %17 %13
|
||||||
%20 = OpCompositeExtract %7 %18 0
|
|
||||||
OpStore %21 %20
|
|
||||||
OpReturn
|
OpReturn
|
||||||
)");
|
)");
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ void tint_symbol() {
|
||||||
int x = 42;
|
int x = 42;
|
||||||
int empty[4] = int[4](0, 0, 0, 0);
|
int empty[4] = int[4](0, 0, 0, 0);
|
||||||
int nonempty[4] = int[4](1, 2, 3, 4);
|
int nonempty[4] = int[4](1, 2, 3, 4);
|
||||||
int nonempty_with_expr[4] = int[4](1, 42, (42 + 1), nonempty[3]);
|
int nonempty_with_expr[4] = int[4](1, 42, (42 + 1), 4);
|
||||||
int nested_empty[2][3][4] = int[2][3][4](int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)), int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)));
|
int nested_empty[2][3][4] = int[2][3][4](int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)), int[3][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0), int[4](0, 0, 0, 0)));
|
||||||
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
|
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
|
||||||
int tint_symbol_2[4] = int[4](5, 6, 7, 8);
|
int tint_symbol_2[4] = int[4](5, 6, 7, 8);
|
||||||
|
@ -16,14 +16,14 @@ void tint_symbol() {
|
||||||
int tint_symbol_8[3][4] = int[3][4](tint_symbol_5, tint_symbol_6, tint_symbol_7);
|
int tint_symbol_8[3][4] = int[3][4](tint_symbol_5, tint_symbol_6, tint_symbol_7);
|
||||||
int nested_nonempty[2][3][4] = int[2][3][4](tint_symbol_4, tint_symbol_8);
|
int nested_nonempty[2][3][4] = int[2][3][4](tint_symbol_4, tint_symbol_8);
|
||||||
int tint_symbol_9[4] = int[4](1, 2, 42, (42 + 1));
|
int tint_symbol_9[4] = int[4](1, 2, 42, (42 + 1));
|
||||||
int tint_symbol_10[4] = int[4](5, 6, nonempty[2], (nonempty[3] + 1));
|
int tint_symbol_10[4] = int[4](5, 6, 3, (4 + 1));
|
||||||
int tint_symbol_11[3][4] = int[3][4](tint_symbol_9, tint_symbol_10, nonempty);
|
int tint_symbol_11[3][4] = int[3][4](tint_symbol_9, tint_symbol_10, nonempty);
|
||||||
int nested_nonempty_with_expr[2][3][4] = int[2][3][4](tint_symbol_11, nested_nonempty[1]);
|
int nested_nonempty_with_expr[2][3][4] = int[2][3][4](tint_symbol_11, nested_nonempty[1]);
|
||||||
int tint_symbol_12[4] = int[4](0, 0, 0, 0);
|
int tint_symbol_12[4] = int[4](0, 0, 0, 0);
|
||||||
int subexpr_empty = tint_symbol_12[1];
|
int subexpr_empty = 0;
|
||||||
int tint_symbol_13[4] = int[4](1, 2, 3, 4);
|
int tint_symbol_13[4] = int[4](1, 2, 3, 4);
|
||||||
int subexpr_nonempty = tint_symbol_13[2];
|
int subexpr_nonempty = 3;
|
||||||
int tint_symbol_14[4] = int[4](1, 42, (42 + 1), nonempty[3]);
|
int tint_symbol_14[4] = int[4](1, 42, (42 + 1), 4);
|
||||||
int subexpr_nonempty_with_expr = tint_symbol_14[2];
|
int subexpr_nonempty_with_expr = tint_symbol_14[2];
|
||||||
int tint_symbol_15[2][4] = int[2][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0));
|
int tint_symbol_15[2][4] = int[2][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0));
|
||||||
int subexpr_nested_empty[4] = tint_symbol_15[1];
|
int subexpr_nested_empty[4] = tint_symbol_15[1];
|
||||||
|
@ -31,7 +31,7 @@ void tint_symbol() {
|
||||||
int tint_symbol_17[4] = int[4](5, 6, 7, 8);
|
int tint_symbol_17[4] = int[4](5, 6, 7, 8);
|
||||||
int tint_symbol_18[2][4] = int[2][4](tint_symbol_16, tint_symbol_17);
|
int tint_symbol_18[2][4] = int[2][4](tint_symbol_16, tint_symbol_17);
|
||||||
int subexpr_nested_nonempty[4] = tint_symbol_18[1];
|
int subexpr_nested_nonempty[4] = tint_symbol_18[1];
|
||||||
int tint_symbol_19[4] = int[4](1, 42, (42 + 1), nonempty[3]);
|
int tint_symbol_19[4] = int[4](1, 42, (42 + 1), 4);
|
||||||
int tint_symbol_20[2][4] = int[2][4](tint_symbol_19, nested_nonempty[1][2]);
|
int tint_symbol_20[2][4] = int[2][4](tint_symbol_19, nested_nonempty[1][2]);
|
||||||
int subexpr_nested_nonempty_with_expr[4] = tint_symbol_20[1];
|
int subexpr_nested_nonempty_with_expr[4] = tint_symbol_20[1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ void main() {
|
||||||
const int x = 42;
|
const int x = 42;
|
||||||
const int empty[4] = (int[4])0;
|
const int empty[4] = (int[4])0;
|
||||||
const int nonempty[4] = {1, 2, 3, 4};
|
const int nonempty[4] = {1, 2, 3, 4};
|
||||||
const int nonempty_with_expr[4] = {1, 42, (42 + 1), nonempty[3]};
|
const int nonempty_with_expr[4] = {1, 42, (42 + 1), 4};
|
||||||
const int nested_empty[2][3][4] = (int[2][3][4])0;
|
const int nested_empty[2][3][4] = (int[2][3][4])0;
|
||||||
const int tint_symbol[4] = {1, 2, 3, 4};
|
const int tint_symbol[4] = {1, 2, 3, 4};
|
||||||
const int tint_symbol_1[4] = {5, 6, 7, 8};
|
const int tint_symbol_1[4] = {5, 6, 7, 8};
|
||||||
|
@ -15,14 +15,14 @@ void main() {
|
||||||
const int tint_symbol_7[3][4] = {tint_symbol_4, tint_symbol_5, tint_symbol_6};
|
const int tint_symbol_7[3][4] = {tint_symbol_4, tint_symbol_5, tint_symbol_6};
|
||||||
const int nested_nonempty[2][3][4] = {tint_symbol_3, tint_symbol_7};
|
const int nested_nonempty[2][3][4] = {tint_symbol_3, tint_symbol_7};
|
||||||
const int tint_symbol_8[4] = {1, 2, 42, (42 + 1)};
|
const int tint_symbol_8[4] = {1, 2, 42, (42 + 1)};
|
||||||
const int tint_symbol_9[4] = {5, 6, nonempty[2], (nonempty[3] + 1)};
|
const int tint_symbol_9[4] = {5, 6, 3, (4 + 1)};
|
||||||
const int tint_symbol_10[3][4] = {tint_symbol_8, tint_symbol_9, nonempty};
|
const int tint_symbol_10[3][4] = {tint_symbol_8, tint_symbol_9, nonempty};
|
||||||
const int nested_nonempty_with_expr[2][3][4] = {tint_symbol_10, nested_nonempty[1]};
|
const int nested_nonempty_with_expr[2][3][4] = {tint_symbol_10, nested_nonempty[1]};
|
||||||
const int tint_symbol_11[4] = (int[4])0;
|
const int tint_symbol_11[4] = (int[4])0;
|
||||||
const int subexpr_empty = tint_symbol_11[1];
|
const int subexpr_empty = 0;
|
||||||
const int tint_symbol_12[4] = {1, 2, 3, 4};
|
const int tint_symbol_12[4] = {1, 2, 3, 4};
|
||||||
const int subexpr_nonempty = tint_symbol_12[2];
|
const int subexpr_nonempty = 3;
|
||||||
const int tint_symbol_13[4] = {1, 42, (42 + 1), nonempty[3]};
|
const int tint_symbol_13[4] = {1, 42, (42 + 1), 4};
|
||||||
const int subexpr_nonempty_with_expr = tint_symbol_13[2];
|
const int subexpr_nonempty_with_expr = tint_symbol_13[2];
|
||||||
const int tint_symbol_14[2][4] = (int[2][4])0;
|
const int tint_symbol_14[2][4] = (int[2][4])0;
|
||||||
const int subexpr_nested_empty[4] = tint_symbol_14[1];
|
const int subexpr_nested_empty[4] = tint_symbol_14[1];
|
||||||
|
@ -30,7 +30,7 @@ void main() {
|
||||||
const int tint_symbol_16[4] = {5, 6, 7, 8};
|
const int tint_symbol_16[4] = {5, 6, 7, 8};
|
||||||
const int tint_symbol_17[2][4] = {tint_symbol_15, tint_symbol_16};
|
const int tint_symbol_17[2][4] = {tint_symbol_15, tint_symbol_16};
|
||||||
const int subexpr_nested_nonempty[4] = tint_symbol_17[1];
|
const int subexpr_nested_nonempty[4] = tint_symbol_17[1];
|
||||||
const int tint_symbol_18[4] = {1, 42, (42 + 1), nonempty[3]};
|
const int tint_symbol_18[4] = {1, 42, (42 + 1), 4};
|
||||||
const int tint_symbol_19[2][4] = {tint_symbol_18, nested_nonempty[1][2]};
|
const int tint_symbol_19[2][4] = {tint_symbol_18, nested_nonempty[1][2]};
|
||||||
const int subexpr_nested_nonempty_with_expr[4] = tint_symbol_19[1];
|
const int subexpr_nested_nonempty_with_expr[4] = tint_symbol_19[1];
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 79
|
; Bound: 66
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -29,66 +29,53 @@
|
||||||
%_arr__arr_int_uint_4_uint_3 = OpTypeArray %_arr_int_uint_4 %uint_3
|
%_arr__arr_int_uint_4_uint_3 = OpTypeArray %_arr_int_uint_4 %uint_3
|
||||||
%uint_2 = OpConstant %uint 2
|
%uint_2 = OpConstant %uint 2
|
||||||
%_arr__arr__arr_int_uint_4_uint_3_uint_2 = OpTypeArray %_arr__arr_int_uint_4_uint_3 %uint_2
|
%_arr__arr__arr_int_uint_4_uint_3_uint_2 = OpTypeArray %_arr__arr_int_uint_4_uint_3 %uint_2
|
||||||
%23 = OpConstantNull %_arr__arr__arr_int_uint_4_uint_3_uint_2
|
%22 = OpConstantNull %_arr__arr__arr_int_uint_4_uint_3_uint_2
|
||||||
%int_5 = OpConstant %int 5
|
%int_5 = OpConstant %int 5
|
||||||
%int_6 = OpConstant %int 6
|
%int_6 = OpConstant %int 6
|
||||||
%int_7 = OpConstant %int 7
|
%int_7 = OpConstant %int 7
|
||||||
%int_8 = OpConstant %int 8
|
%int_8 = OpConstant %int 8
|
||||||
%28 = OpConstantComposite %_arr_int_uint_4 %int_5 %int_6 %int_7 %int_8
|
%27 = OpConstantComposite %_arr_int_uint_4 %int_5 %int_6 %int_7 %int_8
|
||||||
%int_9 = OpConstant %int 9
|
%int_9 = OpConstant %int 9
|
||||||
%int_10 = OpConstant %int 10
|
%int_10 = OpConstant %int 10
|
||||||
%int_11 = OpConstant %int 11
|
%int_11 = OpConstant %int 11
|
||||||
%int_12 = OpConstant %int 12
|
%int_12 = OpConstant %int 12
|
||||||
%33 = OpConstantComposite %_arr_int_uint_4 %int_9 %int_10 %int_11 %int_12
|
%32 = OpConstantComposite %_arr_int_uint_4 %int_9 %int_10 %int_11 %int_12
|
||||||
%34 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %15 %28 %33
|
%33 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %15 %27 %32
|
||||||
%int_13 = OpConstant %int 13
|
%int_13 = OpConstant %int 13
|
||||||
%int_14 = OpConstant %int 14
|
%int_14 = OpConstant %int 14
|
||||||
%int_15 = OpConstant %int 15
|
%int_15 = OpConstant %int 15
|
||||||
%int_16 = OpConstant %int 16
|
%int_16 = OpConstant %int 16
|
||||||
%39 = OpConstantComposite %_arr_int_uint_4 %int_13 %int_14 %int_15 %int_16
|
%38 = OpConstantComposite %_arr_int_uint_4 %int_13 %int_14 %int_15 %int_16
|
||||||
%int_17 = OpConstant %int 17
|
%int_17 = OpConstant %int 17
|
||||||
%int_18 = OpConstant %int 18
|
%int_18 = OpConstant %int 18
|
||||||
%int_19 = OpConstant %int 19
|
%int_19 = OpConstant %int 19
|
||||||
%int_20 = OpConstant %int 20
|
%int_20 = OpConstant %int 20
|
||||||
%44 = OpConstantComposite %_arr_int_uint_4 %int_17 %int_18 %int_19 %int_20
|
%43 = OpConstantComposite %_arr_int_uint_4 %int_17 %int_18 %int_19 %int_20
|
||||||
%int_21 = OpConstant %int 21
|
%int_21 = OpConstant %int 21
|
||||||
%int_22 = OpConstant %int 22
|
%int_22 = OpConstant %int 22
|
||||||
%int_23 = OpConstant %int 23
|
%int_23 = OpConstant %int 23
|
||||||
%int_24 = OpConstant %int 24
|
%int_24 = OpConstant %int 24
|
||||||
%49 = OpConstantComposite %_arr_int_uint_4 %int_21 %int_22 %int_23 %int_24
|
%48 = OpConstantComposite %_arr_int_uint_4 %int_21 %int_22 %int_23 %int_24
|
||||||
%50 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %39 %44 %49
|
%49 = OpConstantComposite %_arr__arr_int_uint_4_uint_3 %38 %43 %48
|
||||||
%51 = OpConstantComposite %_arr__arr__arr_int_uint_4_uint_3_uint_2 %34 %50
|
%50 = OpConstantComposite %_arr__arr__arr_int_uint_4_uint_3_uint_2 %33 %49
|
||||||
|
%57 = OpConstantNull %int
|
||||||
%_arr__arr_int_uint_4_uint_2 = OpTypeArray %_arr_int_uint_4 %uint_2
|
%_arr__arr_int_uint_4_uint_2 = OpTypeArray %_arr_int_uint_4 %uint_2
|
||||||
%68 = OpConstantNull %_arr__arr_int_uint_4_uint_2
|
|
||||||
%70 = OpConstantComposite %_arr__arr_int_uint_4_uint_2 %15 %28
|
|
||||||
%main = OpFunction %void None %1
|
%main = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
%16 = OpIAdd %int %int_42 %int_1
|
%16 = OpIAdd %int %int_42 %int_1
|
||||||
%17 = OpCompositeExtract %int %15 3
|
%17 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %16 %int_4
|
||||||
%18 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %16 %17
|
%51 = OpIAdd %int %int_42 %int_1
|
||||||
%52 = OpIAdd %int %int_42 %int_1
|
%52 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_2 %int_42 %51
|
||||||
%53 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_2 %int_42 %52
|
%53 = OpIAdd %int %int_4 %int_1
|
||||||
%54 = OpCompositeExtract %int %15 2
|
%54 = OpCompositeConstruct %_arr_int_uint_4 %int_5 %int_6 %int_3 %53
|
||||||
%55 = OpCompositeExtract %int %15 3
|
%55 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_3 %52 %54 %15
|
||||||
%56 = OpIAdd %int %55 %int_1
|
%56 = OpCompositeConstruct %_arr__arr__arr_int_uint_4_uint_3_uint_2 %55 %49
|
||||||
%57 = OpCompositeConstruct %_arr_int_uint_4 %int_5 %int_6 %54 %56
|
%58 = OpIAdd %int %int_42 %int_1
|
||||||
%58 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_3 %53 %57 %15
|
%59 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %58 %int_4
|
||||||
%59 = OpCompositeExtract %_arr__arr_int_uint_4_uint_3 %51 1
|
%60 = OpCompositeExtract %int %59 2
|
||||||
%60 = OpCompositeConstruct %_arr__arr__arr_int_uint_4_uint_3_uint_2 %58 %59
|
%62 = OpIAdd %int %int_42 %int_1
|
||||||
%61 = OpCompositeExtract %int %10 1
|
%63 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %62 %int_4
|
||||||
%62 = OpCompositeExtract %int %15 2
|
%64 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_2 %63 %48
|
||||||
%63 = OpIAdd %int %int_42 %int_1
|
%65 = OpCompositeExtract %_arr_int_uint_4 %64 1
|
||||||
%64 = OpCompositeExtract %int %15 3
|
|
||||||
%65 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %63 %64
|
|
||||||
%66 = OpCompositeExtract %int %65 2
|
|
||||||
%69 = OpCompositeExtract %_arr_int_uint_4 %68 1
|
|
||||||
%71 = OpCompositeExtract %_arr_int_uint_4 %70 1
|
|
||||||
%72 = OpIAdd %int %int_42 %int_1
|
|
||||||
%73 = OpCompositeExtract %int %15 3
|
|
||||||
%74 = OpCompositeConstruct %_arr_int_uint_4 %int_1 %int_42 %72 %73
|
|
||||||
%75 = OpCompositeExtract %_arr__arr_int_uint_4_uint_3 %51 1
|
|
||||||
%76 = OpCompositeExtract %_arr_int_uint_4 %75 2
|
|
||||||
%77 = OpCompositeConstruct %_arr__arr_int_uint_4_uint_2 %74 %76
|
|
||||||
%78 = OpCompositeExtract %_arr_int_uint_4 %77 1
|
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
||||||
}
|
}
|
||||||
int f() {
|
int f() {
|
||||||
int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
|
int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
|
||||||
return a[1];
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
||||||
|
|
||||||
int f() {
|
int f() {
|
||||||
const int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
const int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||||
return a[1];
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 22
|
; Bound: 21
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -32,6 +32,5 @@
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %int None %5
|
%f = OpFunction %int None %5
|
||||||
%8 = OpLabel
|
%8 = OpLabel
|
||||||
%21 = OpCompositeExtract %int %20 1
|
OpReturnValue %int_2
|
||||||
OpReturnValue %21
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
||||||
}
|
}
|
||||||
int f() {
|
int f() {
|
||||||
int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
|
int a[8] = int[8](1, 2, 3, 4, 5, 6, 7, 8);
|
||||||
return a[1];
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
||||||
|
|
||||||
int f() {
|
int f() {
|
||||||
const int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
const int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||||
return a[1];
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 22
|
; Bound: 21
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -32,6 +32,5 @@
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %int None %5
|
%f = OpFunction %int None %5
|
||||||
%8 = OpLabel
|
%8 = OpLabel
|
||||||
%21 = OpCompositeExtract %int %20 1
|
OpReturnValue %int_2
|
||||||
OpReturnValue %21
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
|
@ -8,7 +8,7 @@ void f() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
int tint_symbol[1] = int[1](1);
|
int tint_symbol[1] = int[1](1);
|
||||||
if (!((i < tint_symbol[0]))) {
|
if (!((i < 1))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ void f() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
[loop] while (true) {
|
[loop] while (true) {
|
||||||
const int tint_symbol[1] = {1};
|
const int tint_symbol[1] = {1};
|
||||||
if (!((i < tint_symbol[0]))) {
|
if (!((i < 1))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 27
|
; Bound: 22
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -10,17 +10,12 @@
|
||||||
OpName %unused_entry_point "unused_entry_point"
|
OpName %unused_entry_point "unused_entry_point"
|
||||||
OpName %f "f"
|
OpName %f "f"
|
||||||
OpName %i "i"
|
OpName %i "i"
|
||||||
OpDecorate %_arr_int_uint_1 ArrayStride 4
|
|
||||||
%void = OpTypeVoid
|
%void = OpTypeVoid
|
||||||
%1 = OpTypeFunction %void
|
%1 = OpTypeFunction %void
|
||||||
%int = OpTypeInt 32 1
|
%int = OpTypeInt 32 1
|
||||||
%_ptr_Function_int = OpTypePointer Function %int
|
%_ptr_Function_int = OpTypePointer Function %int
|
||||||
%10 = OpConstantNull %int
|
%10 = OpConstantNull %int
|
||||||
%uint = OpTypeInt 32 0
|
|
||||||
%uint_1 = OpConstant %uint 1
|
|
||||||
%_arr_int_uint_1 = OpTypeArray %int %uint_1
|
|
||||||
%int_1 = OpConstant %int 1
|
%int_1 = OpConstant %int 1
|
||||||
%21 = OpConstantComposite %_arr_int_uint_1 %int_1
|
|
||||||
%bool = OpTypeBool
|
%bool = OpTypeBool
|
||||||
%unused_entry_point = OpFunction %void None %1
|
%unused_entry_point = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
|
@ -35,14 +30,13 @@
|
||||||
OpBranch %14
|
OpBranch %14
|
||||||
%14 = OpLabel
|
%14 = OpLabel
|
||||||
%16 = OpLoad %int %i
|
%16 = OpLoad %int %i
|
||||||
%22 = OpCompositeExtract %int %21 0
|
%18 = OpSLessThan %bool %16 %int_1
|
||||||
%23 = OpSLessThan %bool %16 %22
|
%15 = OpLogicalNot %bool %18
|
||||||
%15 = OpLogicalNot %bool %23
|
OpSelectionMerge %20 None
|
||||||
OpSelectionMerge %25 None
|
OpBranchConditional %15 %21 %20
|
||||||
OpBranchConditional %15 %26 %25
|
%21 = OpLabel
|
||||||
%26 = OpLabel
|
|
||||||
OpBranch %12
|
OpBranch %12
|
||||||
%25 = OpLabel
|
%20 = OpLabel
|
||||||
OpBranch %13
|
OpBranch %13
|
||||||
%13 = OpLabel
|
%13 = OpLabel
|
||||||
OpBranch %11
|
OpBranch %11
|
||||||
|
|
|
@ -14,7 +14,7 @@ void f() {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int tint_symbol[1] = int[1](1);
|
int tint_symbol[1] = int[1](1);
|
||||||
i = (i + tint_symbol[0]);
|
i = (i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ void f() {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const int tint_symbol[1] = {1};
|
const int tint_symbol[1] = {1};
|
||||||
i = (i + tint_symbol[0]);
|
i = (i + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 28
|
; Bound: 23
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -10,7 +10,6 @@
|
||||||
OpName %unused_entry_point "unused_entry_point"
|
OpName %unused_entry_point "unused_entry_point"
|
||||||
OpName %f "f"
|
OpName %f "f"
|
||||||
OpName %i "i"
|
OpName %i "i"
|
||||||
OpDecorate %_arr_int_uint_1 ArrayStride 4
|
|
||||||
%void = OpTypeVoid
|
%void = OpTypeVoid
|
||||||
%1 = OpTypeFunction %void
|
%1 = OpTypeFunction %void
|
||||||
%int = OpTypeInt 32 1
|
%int = OpTypeInt 32 1
|
||||||
|
@ -18,11 +17,7 @@
|
||||||
%10 = OpConstantNull %int
|
%10 = OpConstantNull %int
|
||||||
%bool = OpTypeBool
|
%bool = OpTypeBool
|
||||||
%17 = OpConstantNull %bool
|
%17 = OpConstantNull %bool
|
||||||
%uint = OpTypeInt 32 0
|
|
||||||
%uint_1 = OpConstant %uint 1
|
|
||||||
%_arr_int_uint_1 = OpTypeArray %int %uint_1
|
|
||||||
%int_1 = OpConstant %int 1
|
%int_1 = OpConstant %int 1
|
||||||
%25 = OpConstantComposite %_arr_int_uint_1 %int_1
|
|
||||||
%unused_entry_point = OpFunction %void None %1
|
%unused_entry_point = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
|
@ -44,9 +39,8 @@
|
||||||
OpBranch %13
|
OpBranch %13
|
||||||
%13 = OpLabel
|
%13 = OpLabel
|
||||||
%20 = OpLoad %int %i
|
%20 = OpLoad %int %i
|
||||||
%26 = OpCompositeExtract %int %25 0
|
%22 = OpIAdd %int %20 %int_1
|
||||||
%27 = OpIAdd %int %20 %26
|
OpStore %i %22
|
||||||
OpStore %i %27
|
|
||||||
OpBranch %11
|
OpBranch %11
|
||||||
%12 = OpLabel
|
%12 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
|
|
|
@ -7,7 +7,7 @@ void unused_entry_point() {
|
||||||
void f() {
|
void f() {
|
||||||
int tint_symbol[1] = int[1](1);
|
int tint_symbol[1] = int[1](1);
|
||||||
{
|
{
|
||||||
for(int i = tint_symbol[0]; false; ) {
|
for(int i = 1; false; ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ void unused_entry_point() {
|
||||||
void f() {
|
void f() {
|
||||||
const int tint_symbol[1] = {1};
|
const int tint_symbol[1] = {1};
|
||||||
{
|
{
|
||||||
[loop] for(int i = tint_symbol[0]; false; ) {
|
[loop] for(int i = 1; false; ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
; Generator: Google Tint Compiler; 0
|
; Generator: Google Tint Compiler; 0
|
||||||
; Bound: 26
|
; Bound: 21
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
|
@ -10,42 +10,36 @@
|
||||||
OpName %unused_entry_point "unused_entry_point"
|
OpName %unused_entry_point "unused_entry_point"
|
||||||
OpName %f "f"
|
OpName %f "f"
|
||||||
OpName %i "i"
|
OpName %i "i"
|
||||||
OpDecorate %_arr_int_uint_1 ArrayStride 4
|
|
||||||
%void = OpTypeVoid
|
%void = OpTypeVoid
|
||||||
%1 = OpTypeFunction %void
|
%1 = OpTypeFunction %void
|
||||||
%int = OpTypeInt 32 1
|
%int = OpTypeInt 32 1
|
||||||
%uint = OpTypeInt 32 0
|
|
||||||
%uint_1 = OpConstant %uint 1
|
|
||||||
%_arr_int_uint_1 = OpTypeArray %int %uint_1
|
|
||||||
%int_1 = OpConstant %int 1
|
%int_1 = OpConstant %int 1
|
||||||
%12 = OpConstantComposite %_arr_int_uint_1 %int_1
|
|
||||||
%13 = OpConstantNull %int
|
|
||||||
%_ptr_Function_int = OpTypePointer Function %int
|
%_ptr_Function_int = OpTypePointer Function %int
|
||||||
|
%11 = OpConstantNull %int
|
||||||
%bool = OpTypeBool
|
%bool = OpTypeBool
|
||||||
%23 = OpConstantNull %bool
|
%18 = OpConstantNull %bool
|
||||||
%unused_entry_point = OpFunction %void None %1
|
%unused_entry_point = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %void None %1
|
%f = OpFunction %void None %1
|
||||||
%6 = OpLabel
|
%6 = OpLabel
|
||||||
%i = OpVariable %_ptr_Function_int Function %13
|
%i = OpVariable %_ptr_Function_int Function %11
|
||||||
%14 = OpCompositeExtract %int %12 0
|
OpStore %i %int_1
|
||||||
OpStore %i %14
|
OpBranch %12
|
||||||
OpBranch %17
|
%12 = OpLabel
|
||||||
%17 = OpLabel
|
OpLoopMerge %13 %14 None
|
||||||
OpLoopMerge %18 %19 None
|
OpBranch %15
|
||||||
OpBranch %20
|
%15 = OpLabel
|
||||||
|
%16 = OpLogicalNot %bool %18
|
||||||
|
OpSelectionMerge %19 None
|
||||||
|
OpBranchConditional %16 %20 %19
|
||||||
%20 = OpLabel
|
%20 = OpLabel
|
||||||
%21 = OpLogicalNot %bool %23
|
OpBranch %13
|
||||||
OpSelectionMerge %24 None
|
|
||||||
OpBranchConditional %21 %25 %24
|
|
||||||
%25 = OpLabel
|
|
||||||
OpBranch %18
|
|
||||||
%24 = OpLabel
|
|
||||||
OpBranch %19
|
|
||||||
%19 = OpLabel
|
%19 = OpLabel
|
||||||
OpBranch %17
|
OpBranch %14
|
||||||
%18 = OpLabel
|
%14 = OpLabel
|
||||||
|
OpBranch %12
|
||||||
|
%13 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
|
Loading…
Reference in New Issue