mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-09 06:35:54 +00:00
tint/resolver: Evaluate constant index accessors
If the object and index are both constant expressions, resolve the index as a constant. Note: Expectations have been updated for indexing on 'let's. Once 'const' is introduced, 'let' will no longer be treated as a constant expression, and these expectations will be reverted. Bug: tint:1580 Change-Id: I42793d36c1a5f82890ccaa5dbbb71b4346493bef Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94329 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
parent
c9787e774a
commit
c1cb9dc1a5
@ -171,17 +171,25 @@ class Resolver {
|
|||||||
const ast::ExpressionList& params,
|
const ast::ExpressionList& params,
|
||||||
uint32_t* id);
|
uint32_t* id);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
/// Expression traverses the graph of expressions starting at `expr`, building a postordered
|
||||||
// AST and Type traversal methods
|
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
/// dispatching to the appropriate expression handlers below.
|
||||||
|
/// @returns the resolved semantic node for the expression `expr`, or nullptr on failure.
|
||||||
|
sem::Expression* Expression(const ast::Expression* expr);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Expression resolving methods
|
// Expression resolving methods
|
||||||
|
//
|
||||||
// Returns the semantic node pointer on success, nullptr on failure.
|
// Returns the semantic node pointer on success, nullptr on failure.
|
||||||
|
//
|
||||||
|
// These methods are invoked by Expression(), in postorder (child-first). These methods should
|
||||||
|
// not attempt to resolve their children. This design avoids recursion, which is a common cause
|
||||||
|
// of stack-overflows.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*);
|
sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*);
|
||||||
sem::Expression* Binary(const ast::BinaryExpression*);
|
sem::Expression* Binary(const ast::BinaryExpression*);
|
||||||
sem::Expression* Bitcast(const ast::BitcastExpression*);
|
sem::Expression* Bitcast(const ast::BitcastExpression*);
|
||||||
sem::Call* Call(const ast::CallExpression*);
|
sem::Call* Call(const ast::CallExpression*);
|
||||||
sem::Expression* Expression(const ast::Expression*);
|
|
||||||
sem::Function* Function(const ast::Function*);
|
sem::Function* Function(const ast::Function*);
|
||||||
sem::Call* FunctionCall(const ast::CallExpression*,
|
sem::Call* FunctionCall(const ast::CallExpression*,
|
||||||
sem::Function* target,
|
sem::Function* target,
|
||||||
@ -195,6 +203,29 @@ class Resolver {
|
|||||||
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
|
sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*);
|
||||||
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
|
sem::Expression* UnaryOp(const ast::UnaryOpExpression*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Constant value evaluation methods
|
||||||
|
///
|
||||||
|
/// These methods are called from the expression resolving methods, and so child-expression
|
||||||
|
/// nodes are guaranteed to have been already resolved and any constant values calculated.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
sem::Constant EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type);
|
||||||
|
sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal,
|
||||||
|
const sem::Type* type);
|
||||||
|
sem::Constant EvaluateConstantValue(const ast::CallExpression* call, const sem::Type* type);
|
||||||
|
sem::Constant EvaluateConstantValue(const ast::IndexAccessorExpression* call,
|
||||||
|
const sem::Type* type);
|
||||||
|
|
||||||
|
/// The result type of a ConstantEvaluation method. Holds the constant value and a boolean,
|
||||||
|
/// which is true on success, false on an error.
|
||||||
|
using ConstantResult = utils::Result<sem::Constant>;
|
||||||
|
|
||||||
|
/// Convert the `value` to `target_type`
|
||||||
|
/// @return the converted value
|
||||||
|
ConstantResult ConvertValue(const sem::Constant& value,
|
||||||
|
const sem::Type* target_type,
|
||||||
|
const Source& source);
|
||||||
|
|
||||||
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
/// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`.
|
||||||
/// If `expr` is of an abstract-numeric type:
|
/// If `expr` is of an abstract-numeric type:
|
||||||
/// * Materialize will create and return a sem::Materialize node wrapping `expr`.
|
/// * Materialize will create and return a sem::Materialize node wrapping `expr`.
|
||||||
@ -379,23 +410,6 @@ class Resolver {
|
|||||||
/// Adds the given note message to the diagnostics
|
/// Adds the given note message to the diagnostics
|
||||||
void AddNote(const std::string& msg, const Source& source) const;
|
void AddNote(const std::string& msg, const Source& source) const;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Constant value evaluation methods
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// The result type of a ConstantEvaluation method. Holds the constant value and a boolean,
|
|
||||||
/// which is true on success, false on an error.
|
|
||||||
using ConstantResult = utils::Result<sem::Constant>;
|
|
||||||
|
|
||||||
/// Convert the `value` to `target_type`
|
|
||||||
/// @return the converted value
|
|
||||||
ConstantResult ConvertValue(const sem::Constant& value,
|
|
||||||
const sem::Type* target_type,
|
|
||||||
const Source& source);
|
|
||||||
sem::Constant EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type);
|
|
||||||
sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal,
|
|
||||||
const sem::Type* type);
|
|
||||||
sem::Constant EvaluateConstantValue(const ast::CallExpression* call, const sem::Type* type);
|
|
||||||
|
|
||||||
/// @returns true if the symbol is the name of a builtin function.
|
/// @returns true if the symbol is the name of a builtin function.
|
||||||
bool IsBuiltin(Symbol) const;
|
bool IsBuiltin(Symbol) const;
|
||||||
|
|
||||||
|
@ -155,7 +155,8 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr, const
|
|||||||
return Switch(
|
return Switch(
|
||||||
expr, //
|
expr, //
|
||||||
[&](const ast::LiteralExpression* e) { return EvaluateConstantValue(e, type); },
|
[&](const ast::LiteralExpression* e) { return EvaluateConstantValue(e, type); },
|
||||||
[&](const ast::CallExpression* e) { return EvaluateConstantValue(e, type); });
|
[&](const ast::CallExpression* e) { return EvaluateConstantValue(e, type); },
|
||||||
|
[&](const ast::IndexAccessorExpression* e) { return EvaluateConstantValue(e, type); });
|
||||||
}
|
}
|
||||||
|
|
||||||
sem::Constant Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal,
|
sem::Constant Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal,
|
||||||
@ -255,6 +256,54 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::CallExpression* call,
|
|||||||
elements.value());
|
elements.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sem::Constant Resolver::EvaluateConstantValue(const ast::IndexAccessorExpression* accessor,
|
||||||
|
const sem::Type* el_ty) {
|
||||||
|
auto* obj_sem = builder_->Sem().Get(accessor->object);
|
||||||
|
if (!obj_sem) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto obj_val = obj_sem->ConstantValue();
|
||||||
|
if (!obj_val) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* idx_sem = builder_->Sem().Get(accessor->index);
|
||||||
|
if (!idx_sem) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto idx_val = idx_sem->ConstantValue();
|
||||||
|
if (!idx_val || idx_val.ElementCount() != 1) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
AInt idx = idx_val.Element<AInt>(0);
|
||||||
|
|
||||||
|
// The immediate child element count.
|
||||||
|
uint32_t el_count = 0;
|
||||||
|
sem::Type::ElementOf(obj_val.Type(), &el_count);
|
||||||
|
|
||||||
|
// The total number of most-nested elements per child element type.
|
||||||
|
uint32_t step = 0;
|
||||||
|
sem::Type::DeepestElementOf(el_ty, &step);
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= el_count) {
|
||||||
|
auto clamped = std::min<AInt::type>(std::max<AInt::type>(idx, 0), el_count - 1);
|
||||||
|
AddWarning("index " + std::to_string(idx) + " out of bounds [0.." +
|
||||||
|
std::to_string(el_count - 1) + "]. Clamping index to " +
|
||||||
|
std::to_string(clamped),
|
||||||
|
accessor->index->source);
|
||||||
|
idx = clamped;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sem::Constant{el_ty, obj_val.WithElements([&](auto&& v) {
|
||||||
|
using VEC = std::decay_t<decltype(v)>;
|
||||||
|
return sem::Constant::Elements(
|
||||||
|
VEC(v.begin() + (idx * step), v.begin() + (idx + 1) * step));
|
||||||
|
})};
|
||||||
|
}
|
||||||
|
|
||||||
utils::Result<sem::Constant> Resolver::ConvertValue(const sem::Constant& value,
|
utils::Result<sem::Constant> Resolver::ConvertValue(const sem::Constant& value,
|
||||||
const sem::Type* ty,
|
const sem::Type* ty,
|
||||||
const Source& source) {
|
const Source& source) {
|
||||||
|
@ -608,5 +608,113 @@ 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, Vec3_Index) {
|
||||||
|
auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), 2_i);
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(0).value, 3_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Vec3_Index_OOB_High) {
|
||||||
|
auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, 3_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(0).value, 3_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Vec3_Index_OOB_Low) {
|
||||||
|
auto* expr = IndexAccessor(vec3<i32>(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, -3_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
ASSERT_TRUE(sem->Type()->Is<sem::I32>());
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::I32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<i32>(0).value, 1_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Mat3x2_Index) {
|
||||||
|
auto* expr = IndexAccessor(
|
||||||
|
mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)), 2_i);
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 5._a);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 6._a);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_High) {
|
||||||
|
auto* expr = IndexAccessor(
|
||||||
|
mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)),
|
||||||
|
Expr(Source{{12, 34}}, 3_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 5._a);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 6._a);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_Low) {
|
||||||
|
auto* expr = IndexAccessor(
|
||||||
|
mat3x2<f32>(vec2<f32>(1._a, 2._a), vec2<f32>(3._a, 4._a), vec2<f32>(5._a, 6._a)),
|
||||||
|
Expr(Source{{12, 34}}, -3_i));
|
||||||
|
WrapInFunction(expr);
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0");
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(expr);
|
||||||
|
EXPECT_NE(sem, nullptr);
|
||||||
|
auto* vec = sem->Type()->As<sem::Vector>();
|
||||||
|
ASSERT_NE(vec, nullptr);
|
||||||
|
EXPECT_EQ(vec->Width(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Type(), sem->Type());
|
||||||
|
EXPECT_TRUE(sem->ConstantValue().ElementType()->Is<sem::F32>());
|
||||||
|
ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(0).value, 1._a);
|
||||||
|
EXPECT_EQ(sem->ConstantValue().Element<f32>(1).value, 2._a);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint::resolver
|
} // namespace tint::resolver
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#version 310 es
|
#version 310 es
|
||||||
|
|
||||||
void main_1() {
|
void main_1() {
|
||||||
float x_24 = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1u].y;
|
float x_24 = vec3(4.0f, 5.0f, 6.0f).y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
void main_1() {
|
void main_1() {
|
||||||
const float x_24 = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1u].y;
|
const float x_24 = float3(4.0f, 5.0f, 6.0f).y;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
using namespace metal;
|
using namespace metal;
|
||||||
void main_1() {
|
void main_1() {
|
||||||
float const x_24 = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1u][1];
|
float const x_24 = float3(4.0f, 5.0f, 6.0f)[1];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
void tint_symbol() {
|
void tint_symbol() {
|
||||||
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
||||||
vec3 v = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1];
|
vec3 v = vec3(4.0f, 5.0f, 6.0f);
|
||||||
float f = v[1];
|
float f = 5.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[numthreads(1, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
void main() {
|
void main() {
|
||||||
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
const float3 v = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
const float3 v = float3(4.0f, 5.0f, 6.0f);
|
||||||
const float f = v[1];
|
const float f = 5.0f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
using namespace metal;
|
using namespace metal;
|
||||||
kernel void tint_symbol() {
|
kernel void tint_symbol() {
|
||||||
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
float3 const v = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
float3 const v = float3(4.0f, 5.0f, 6.0f);
|
||||||
float const f = v[1];
|
float const f = 5.0f;
|
||||||
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: 25
|
; Bound: 21
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -26,11 +26,7 @@
|
|||||||
%float_9 = OpConstant %float 9
|
%float_9 = OpConstant %float 9
|
||||||
%19 = OpConstantComposite %v3float %float_7 %float_8 %float_9
|
%19 = OpConstantComposite %v3float %float_7 %float_8 %float_9
|
||||||
%20 = OpConstantComposite %mat3v3float %11 %15 %19
|
%20 = OpConstantComposite %mat3v3float %11 %15 %19
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%int_1 = OpConstant %int 1
|
|
||||||
%main = OpFunction %void None %1
|
%main = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
%23 = OpCompositeExtract %v3float %20 1
|
|
||||||
%24 = OpCompositeExtract %float %23 1
|
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -6,7 +6,7 @@ void unused_entry_point() {
|
|||||||
}
|
}
|
||||||
void f() {
|
void f() {
|
||||||
mat4 m = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
|
mat4 m = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f));
|
||||||
vec4 v1 = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f))[0];
|
vec4 v1 = vec4(1.0f);
|
||||||
float a = v1[0];
|
float a = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,6 @@ void unused_entry_point() {
|
|||||||
|
|
||||||
void f() {
|
void f() {
|
||||||
const float4x4 m = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
|
const float4x4 m = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx);
|
||||||
const float4 v1 = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx)[0];
|
const float4 v1 = (1.0f).xxxx;
|
||||||
const float a = v1[0];
|
const float a = 1.0f;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
using namespace metal;
|
using namespace metal;
|
||||||
void f() {
|
void f() {
|
||||||
float4x4 const m = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f));
|
float4x4 const m = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f));
|
||||||
float4 const v1 = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f))[0];
|
float4 const v1 = float4(1.0f);
|
||||||
float const a = v1[0];
|
float const a = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: 17
|
; Bound: 13
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -17,15 +17,11 @@
|
|||||||
%float_1 = OpConstant %float 1
|
%float_1 = OpConstant %float 1
|
||||||
%11 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
%11 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
|
||||||
%12 = OpConstantComposite %mat4v4float %11 %11 %11 %11
|
%12 = OpConstantComposite %mat4v4float %11 %11 %11 %11
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%14 = OpConstantNull %int
|
|
||||||
%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
|
||||||
%15 = OpCompositeExtract %v4float %12 0
|
|
||||||
%16 = OpCompositeExtract %float %15 0
|
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
|||||||
}
|
}
|
||||||
vec3 f() {
|
vec3 f() {
|
||||||
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
||||||
return mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1];
|
return vec3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
|||||||
|
|
||||||
float3 f() {
|
float3 f() {
|
||||||
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
return float3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@ using namespace metal;
|
|||||||
float3 f() {
|
float3 f() {
|
||||||
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
int const i = 1;
|
int const i = 1;
|
||||||
return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
return float3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: 26
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -36,6 +36,5 @@
|
|||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %v3float None %5
|
%f = OpFunction %v3float None %5
|
||||||
%9 = OpLabel
|
%9 = OpLabel
|
||||||
%26 = OpCompositeExtract %v3float %23 1
|
OpReturnValue %18
|
||||||
OpReturnValue %26
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
|||||||
}
|
}
|
||||||
float f() {
|
float f() {
|
||||||
vec3 v = vec3(1.0f, 2.0f, 3.0f);
|
vec3 v = vec3(1.0f, 2.0f, 3.0f);
|
||||||
return vec3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
|||||||
|
|
||||||
float f() {
|
float f() {
|
||||||
const float3 v = float3(1.0f, 2.0f, 3.0f);
|
const float3 v = float3(1.0f, 2.0f, 3.0f);
|
||||||
return float3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@ using namespace metal;
|
|||||||
float f() {
|
float f() {
|
||||||
float3 const v = float3(1.0f, 2.0f, 3.0f);
|
float3 const v = float3(1.0f, 2.0f, 3.0f);
|
||||||
int const i = 1;
|
int const i = 1;
|
||||||
return float3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: 17
|
; Bound: 16
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -26,6 +26,5 @@
|
|||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %float None %5
|
%f = OpFunction %float None %5
|
||||||
%8 = OpLabel
|
%8 = OpLabel
|
||||||
%16 = OpCompositeExtract %float %13 1
|
OpReturnValue %float_2
|
||||||
OpReturnValue %16
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
|||||||
}
|
}
|
||||||
vec3 f() {
|
vec3 f() {
|
||||||
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f));
|
||||||
return mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1];
|
return vec3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
|||||||
|
|
||||||
float3 f() {
|
float3 f() {
|
||||||
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
return float3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
using namespace metal;
|
using namespace metal;
|
||||||
float3 f() {
|
float3 f() {
|
||||||
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f));
|
||||||
return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1];
|
return float3(4.0f, 5.0f, 6.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: 24
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -28,14 +28,11 @@
|
|||||||
%float_9 = OpConstant %float 9
|
%float_9 = OpConstant %float 9
|
||||||
%22 = OpConstantComposite %v3float %float_7 %float_8 %float_9
|
%22 = OpConstantComposite %v3float %float_7 %float_8 %float_9
|
||||||
%23 = OpConstantComposite %mat3v3float %14 %18 %22
|
%23 = OpConstantComposite %mat3v3float %14 %18 %22
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%int_1 = OpConstant %int 1
|
|
||||||
%unused_entry_point = OpFunction %void None %1
|
%unused_entry_point = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %v3float None %5
|
%f = OpFunction %v3float None %5
|
||||||
%9 = OpLabel
|
%9 = OpLabel
|
||||||
%26 = OpCompositeExtract %v3float %23 1
|
OpReturnValue %18
|
||||||
OpReturnValue %26
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
@ -6,6 +6,6 @@ void unused_entry_point() {
|
|||||||
}
|
}
|
||||||
float f() {
|
float f() {
|
||||||
vec3 v = vec3(1.0f, 2.0f, 3.0f);
|
vec3 v = vec3(1.0f, 2.0f, 3.0f);
|
||||||
return vec3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,5 +5,5 @@ void unused_entry_point() {
|
|||||||
|
|
||||||
float f() {
|
float f() {
|
||||||
const float3 v = float3(1.0f, 2.0f, 3.0f);
|
const float3 v = float3(1.0f, 2.0f, 3.0f);
|
||||||
return float3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
using namespace metal;
|
using namespace metal;
|
||||||
float f() {
|
float f() {
|
||||||
float3 const v = float3(1.0f, 2.0f, 3.0f);
|
float3 const v = float3(1.0f, 2.0f, 3.0f);
|
||||||
return float3(1.0f, 2.0f, 3.0f)[1];
|
return 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: 17
|
; Bound: 14
|
||||||
; Schema: 0
|
; Schema: 0
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
@ -18,14 +18,11 @@
|
|||||||
%float_2 = OpConstant %float 2
|
%float_2 = OpConstant %float 2
|
||||||
%float_3 = OpConstant %float 3
|
%float_3 = OpConstant %float 3
|
||||||
%13 = OpConstantComposite %v3float %float_1 %float_2 %float_3
|
%13 = OpConstantComposite %v3float %float_1 %float_2 %float_3
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%int_1 = OpConstant %int 1
|
|
||||||
%unused_entry_point = OpFunction %void None %1
|
%unused_entry_point = OpFunction %void None %1
|
||||||
%4 = OpLabel
|
%4 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%f = OpFunction %float None %5
|
%f = OpFunction %float None %5
|
||||||
%8 = OpLabel
|
%8 = OpLabel
|
||||||
%16 = OpCompositeExtract %float %13 1
|
OpReturnValue %float_2
|
||||||
OpReturnValue %16
|
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
|
Loading…
x
Reference in New Issue
Block a user