Add support for converting bool to other types
The only non-trivial case is SPIR-V, which generates OpSelect to
choose between 1 or 0.
Fixed: tint:997
Change-Id: Ifda7b3ec1e0a713843a2da7ed59c3449d4eec8bd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58521
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index ca5ea27..6a4d7b3 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2752,11 +2752,7 @@
// A mismatch of vector type parameter T is only an error if multiple
// arguments are present. A single argument constructor constitutes a
// type conversion expression.
- // NOTE: A conversion expression from a vec<bool> to any other vecN<T>
- // is disallowed (see
- // https://gpuweb.github.io/gpuweb/wgsl.html#conversion-expr).
- if (elem_type != value_elem_type &&
- (values.size() > 1u || value_vec->is_bool_vector())) {
+ if (elem_type != value_elem_type && values.size() > 1u) {
AddError(
"type in vector constructor does not match vector type: "
"expected '" +
@@ -2878,11 +2874,10 @@
using U32 = sem::U32;
using F32 = sem::F32;
- const bool is_valid =
- (type->Is<Bool>() && value_type->IsAnyOf<Bool, I32, U32, F32>()) ||
- (type->Is<I32>() && value_type->IsAnyOf<I32, U32, F32>()) ||
- (type->Is<U32>() && value_type->IsAnyOf<I32, U32, F32>()) ||
- (type->Is<F32>() && value_type->IsAnyOf<I32, U32, F32>());
+ const bool is_valid = (type->Is<Bool>() && value_type->is_scalar()) ||
+ (type->Is<I32>() && value_type->is_scalar()) ||
+ (type->Is<U32>() && value_type->is_scalar()) ||
+ (type->Is<F32>() && value_type->is_scalar());
if (!is_valid) {
AddError("cannot construct '" + type_name + "' with a value of type '" +
TypeNameOf(value) + "'",
diff --git a/src/resolver/type_constructor_validation_test.cc b/src/resolver/type_constructor_validation_test.cc
index d363f8c..2f67ce0 100644
--- a/src/resolver/type_constructor_validation_test.cc
+++ b/src/resolver/type_constructor_validation_test.cc
@@ -255,27 +255,33 @@
ParamsFor<bool, i32>(), //
ParamsFor<bool, f32>(), //
- ParamsFor<i32, u32>(), //
- ParamsFor<i32, f32>(), //
+ ParamsFor<i32, bool>(), //
+ ParamsFor<i32, u32>(), //
+ ParamsFor<i32, f32>(), //
- ParamsFor<u32, i32>(), //
- ParamsFor<u32, f32>(), //
+ ParamsFor<u32, bool>(), //
+ ParamsFor<u32, i32>(), //
+ ParamsFor<u32, f32>(), //
- ParamsFor<f32, u32>(), //
- ParamsFor<f32, i32>(), //
+ ParamsFor<f32, bool>(), //
+ ParamsFor<f32, u32>(), //
+ ParamsFor<f32, i32>(), //
ParamsFor<vec3<bool>, vec3<u32>>(), //
ParamsFor<vec3<bool>, vec3<i32>>(), //
ParamsFor<vec3<bool>, vec3<f32>>(), //
- ParamsFor<vec3<i32>, vec3<u32>>(), //
- ParamsFor<vec3<i32>, vec3<f32>>(), //
+ ParamsFor<vec3<i32>, vec3<bool>>(), //
+ ParamsFor<vec3<i32>, vec3<u32>>(), //
+ ParamsFor<vec3<i32>, vec3<f32>>(), //
- ParamsFor<vec3<u32>, vec3<i32>>(), //
- ParamsFor<vec3<u32>, vec3<f32>>(), //
+ ParamsFor<vec3<u32>, vec3<bool>>(), //
+ ParamsFor<vec3<u32>, vec3<i32>>(), //
+ ParamsFor<vec3<u32>, vec3<f32>>(), //
- ParamsFor<vec3<f32>, vec3<u32>>(), //
- ParamsFor<vec3<f32>, vec3<i32>>(), //
+ ParamsFor<vec3<f32>, vec3<bool>>(), //
+ ParamsFor<vec3<f32>, vec3<u32>>(), //
+ ParamsFor<vec3<f32>, vec3<i32>>(), //
};
using ConversionConstructorValidTest = ResolverTestWithParam<Params>;
@@ -388,13 +394,15 @@
TEST_F(ResolverTypeConstructorValidationTest,
ConversionConstructorInvalid_InvalidInitializer) {
- auto* a = Var("a", ty.f32(), ast::StorageClass::kNone,
- Construct(Source{{12, 34}}, ty.f32(), Expr(true)));
+ auto* a =
+ Var("a", ty.f32(), ast::StorageClass::kNone,
+ Construct(Source{{12, 34}}, ty.f32(), Construct(ty.array<f32, 4>())));
WrapInFunction(a);
ASSERT_FALSE(r()->Resolve());
ASSERT_EQ(r()->error(),
- "12:34 error: cannot construct 'f32' with a value of type 'bool'");
+ "12:34 error: cannot construct 'f32' with a value of type "
+ "'array<f32, 4>'");
}
} // namespace ConversionConstructorTest
@@ -717,20 +725,6 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
- Expr_Constructor_Vec2_Error_InvalidConversionFromVec2Bool) {
- SetSource(Source::Location({12, 34}));
-
- auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
- Source{{12, 34}}, ty.vec2<bool>(), ExprList()));
- WrapInFunction(tc);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'bool'");
-}
-
-TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec2_Error_InvalidArgumentType) {
auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
@@ -987,18 +981,6 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
- Expr_Constructor_Vec3_Error_InvalidConversionFromVec3Bool) {
- auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
- Source{{12, 34}}, ty.vec3<bool>(), ExprList()));
- WrapInFunction(tc);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'bool'");
-}
-
-TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec3_Error_InvalidArgumentType) {
auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
@@ -1349,18 +1331,6 @@
}
TEST_F(ResolverTypeConstructorValidationTest,
- Expr_Constructor_Vec4_Error_InvalidConversionFromVec4Bool) {
- auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
- Source{{12, 34}}, ty.vec4<bool>(), ExprList()));
- WrapInFunction(tc);
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: type in vector constructor does not match vector "
- "type: expected 'f32', found 'bool'");
-}
-
-TEST_F(ResolverTypeConstructorValidationTest,
Expr_Constructor_Vec4_Error_InvalidArgumentType) {
auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 8038ddd..039269f 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -1568,7 +1568,51 @@
}
return result_id;
+ } else if (from_type->is_bool_scalar_or_vector() &&
+ to_type->is_numeric_scalar_or_vector()) {
+ // Convert bool scalar/vector to numeric scalar/vector.
+ // Use the bool to select between 1 (if true) and 0 (if false).
+ const auto* to_elem_type = elem_type_of(to_type);
+ uint32_t one_id;
+ uint32_t zero_id;
+ if (to_elem_type->Is<sem::F32>()) {
+ ast::FloatLiteral one(ProgramID(), Source{}, 1.0f);
+ ast::FloatLiteral zero(ProgramID(), Source{}, 0.0f);
+ one_id = GenerateLiteralIfNeeded(nullptr, &one);
+ zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
+ } else if (to_elem_type->Is<sem::U32>()) {
+ ast::UintLiteral one(ProgramID(), Source{}, 1);
+ ast::UintLiteral zero(ProgramID(), Source{}, 0);
+ one_id = GenerateLiteralIfNeeded(nullptr, &one);
+ zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
+ } else if (to_elem_type->Is<sem::I32>()) {
+ ast::SintLiteral one(ProgramID(), Source{}, 1);
+ ast::SintLiteral zero(ProgramID(), Source{}, 0);
+ one_id = GenerateLiteralIfNeeded(nullptr, &one);
+ zero_id = GenerateLiteralIfNeeded(nullptr, &zero);
+ } else {
+ error_ = "invalid destination type for bool conversion";
+ return false;
+ }
+ if (auto* to_vec = to_type->As<sem::Vector>()) {
+ // Splat the scalars into vectors.
+ one_id = GenerateConstantVectorSplatIfNeeded(to_vec, one_id);
+ zero_id = GenerateConstantVectorSplatIfNeeded(to_vec, zero_id);
+ }
+ if (!one_id || !zero_id) {
+ return false;
+ }
+
+ op = spv::Op::OpSelect;
+ if (!push_function_inst(
+ op, {Operand::Int(result_type_id), Operand::Int(result_id),
+ Operand::Int(val_id), Operand::Int(one_id),
+ Operand::Int(zero_id)})) {
+ return 0;
+ }
+
+ return result_id;
} else {
TINT_ICE(Writer, builder_.Diagnostics()) << "Invalid from_type";
}
@@ -1720,6 +1764,31 @@
return result_id;
}
+uint32_t Builder::GenerateConstantVectorSplatIfNeeded(const sem::Vector* type,
+ uint32_t value_id) {
+ auto type_id = GenerateTypeIfNeeded(type);
+ if (type_id == 0 || value_id == 0) {
+ return 0;
+ }
+
+ uint64_t key = (static_cast<uint64_t>(type->size()) << 32) + value_id;
+ return utils::GetOrCreate(const_splat_to_id_, key, [&] {
+ auto result = result_op();
+ auto result_id = result.to_i();
+
+ OperandList ops;
+ ops.push_back(Operand::Int(type_id));
+ ops.push_back(result);
+ for (uint32_t i = 0; i < type->size(); i++) {
+ ops.push_back(Operand::Int(value_id));
+ }
+ push_type(spv::Op::OpConstantComposite, ops);
+
+ const_splat_to_id_[key] = result_id;
+ return result_id;
+ });
+}
+
uint32_t Builder::GenerateShortCircuitBinaryExpression(
ast::BinaryExpression* expr) {
auto lhs_id = GenerateExpression(expr->lhs());
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index 5ad065f..a81da1e 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -536,7 +536,7 @@
return builder_.TypeOf(expr);
}
- /// Generates a constant if needed
+ /// Generates a scalar constant if needed
/// @param constant the constant to generate.
/// @returns the ID on success or 0 on failure
uint32_t GenerateConstantIfNeeded(const ScalarConstant& constant);
@@ -546,6 +546,13 @@
/// @returns the ID on success or 0 on failure
uint32_t GenerateConstantNullIfNeeded(const sem::Type* type);
+ /// Generates a vector constant splat if needed
+ /// @param type the type of the vector to generate
+ /// @param value_id the ID of the scalar value to splat
+ /// @returns the ID on success or 0 on failure
+ uint32_t GenerateConstantVectorSplatIfNeeded(const sem::Vector* type,
+ uint32_t value_id);
+
ProgramBuilder builder_;
std::string error_;
uint32_t next_id_ = 1;
@@ -567,6 +574,7 @@
std::unordered_map<ScalarConstant, uint32_t> const_to_id_;
std::unordered_map<std::string, uint32_t> type_constructor_to_id_;
std::unordered_map<std::string, uint32_t> const_null_to_id_;
+ std::unordered_map<uint64_t, uint32_t> const_splat_to_id_;
std::unordered_map<std::string, uint32_t>
texture_type_name_to_sampled_image_type_id_;
ScopeStack<uint32_t> scope_stack_;
diff --git a/test/types/function_scope_var_conversions.wgsl b/test/types/function_scope_var_conversions.wgsl
index 7f18422..66cc378 100644
--- a/test/types/function_scope_var_conversions.wgsl
+++ b/test/types/function_scope_var_conversions.wgsl
@@ -11,9 +11,11 @@
var i32_var1 : i32 = i32(123u);
var i32_var2 : i32 = i32(123.0);
+ var i32_var3 : i32 = i32(true);
var u32_var1 : u32 = u32(123);
var u32_var2 : u32 = u32(123.0);
+ var u32_var3 : u32 = u32(true);
var v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(123u));
var v3bool_var11 : vec3<bool> = vec3<bool>(vec3<u32>(1234u));
@@ -22,9 +24,11 @@
var v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(123u));
var v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
+ var v3i32_var3 : vec3<i32> = vec3<i32>(vec3<bool>(true));
var v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(123));
var v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(123.0));
+ var v3u32_var3 : vec3<u32> = vec3<u32>(vec3<bool>(true));
var v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
diff --git a/test/types/function_scope_var_conversions.wgsl.expected.hlsl b/test/types/function_scope_var_conversions.wgsl.expected.hlsl
index 4131d52..b0f76c7 100644
--- a/test/types/function_scope_var_conversions.wgsl.expected.hlsl
+++ b/test/types/function_scope_var_conversions.wgsl.expected.hlsl
@@ -10,16 +10,20 @@
bool bool_var3 = bool(123.0f);
int i32_var1 = int(123u);
int i32_var2 = int(123.0f);
+ int i32_var3 = int(true);
uint u32_var1 = uint(123);
uint u32_var2 = uint(123.0f);
+ uint u32_var3 = uint(true);
bool3 v3bool_var1 = bool3(uint3((123u).xxx));
bool3 v3bool_var11 = bool3(uint3((1234u).xxx));
bool3 v3bool_var2 = bool3(int3((123).xxx));
bool3 v3bool_var3 = bool3(float3((123.0f).xxx));
int3 v3i32_var1 = int3(uint3((123u).xxx));
int3 v3i32_var2 = int3(float3((123.0f).xxx));
+ int3 v3i32_var3 = int3(bool3((true).xxx));
uint3 v3u32_var1 = uint3(int3((123).xxx));
uint3 v3u32_var2 = uint3(float3((123.0f).xxx));
+ uint3 v3u32_var3 = uint3(bool3((true).xxx));
bool3 v3bool_var4 = bool3(bool2(float2((123.0f).xx)), true);
bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
return;
diff --git a/test/types/function_scope_var_conversions.wgsl.expected.msl b/test/types/function_scope_var_conversions.wgsl.expected.msl
index dac4d9b..a656406 100644
--- a/test/types/function_scope_var_conversions.wgsl.expected.msl
+++ b/test/types/function_scope_var_conversions.wgsl.expected.msl
@@ -12,16 +12,20 @@
bool bool_var3 = bool(123.0f);
int i32_var1 = int(123u);
int i32_var2 = int(123.0f);
+ int i32_var3 = int(true);
uint u32_var1 = uint(123);
uint u32_var2 = uint(123.0f);
+ uint u32_var3 = uint(true);
bool3 v3bool_var1 = bool3(uint3(123u));
bool3 v3bool_var11 = bool3(uint3(1234u));
bool3 v3bool_var2 = bool3(int3(123));
bool3 v3bool_var3 = bool3(float3(123.0f));
int3 v3i32_var1 = int3(uint3(123u));
int3 v3i32_var2 = int3(float3(123.0f));
+ int3 v3i32_var3 = int3(bool3(true));
uint3 v3u32_var1 = uint3(int3(123));
uint3 v3u32_var2 = uint3(float3(123.0f));
+ uint3 v3u32_var3 = uint3(bool3(true));
bool3 v3bool_var4 = bool3(bool2(float2(123.0f)), true);
bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
return;
diff --git a/test/types/function_scope_var_conversions.wgsl.expected.spvasm b/test/types/function_scope_var_conversions.wgsl.expected.spvasm
index aaab7e0..1bf5ab9 100644
--- a/test/types/function_scope_var_conversions.wgsl.expected.spvasm
+++ b/test/types/function_scope_var_conversions.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
-; Bound: 65
+; Bound: 73
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -16,16 +16,20 @@
OpName %bool_var3 "bool_var3"
OpName %i32_var1 "i32_var1"
OpName %i32_var2 "i32_var2"
+ OpName %i32_var3 "i32_var3"
OpName %u32_var1 "u32_var1"
OpName %u32_var2 "u32_var2"
+ OpName %u32_var3 "u32_var3"
OpName %v3bool_var1 "v3bool_var1"
OpName %v3bool_var11 "v3bool_var11"
OpName %v3bool_var2 "v3bool_var2"
OpName %v3bool_var3 "v3bool_var3"
OpName %v3i32_var1 "v3i32_var1"
OpName %v3i32_var2 "v3i32_var2"
+ OpName %v3i32_var3 "v3i32_var3"
OpName %v3u32_var1 "v3u32_var1"
OpName %v3u32_var2 "v3u32_var2"
+ OpName %v3u32_var3 "v3u32_var3"
OpName %v3bool_var4 "v3bool_var4"
OpName %v4bool_var5 "v4bool_var5"
%void = OpTypeVoid
@@ -45,28 +49,32 @@
%int_123 = OpConstant %int 123
%_ptr_Function_int = OpTypePointer Function %int
%29 = OpConstantNull %int
+ %int_1 = OpConstant %int 1
%uint = OpTypeInt 32 0
%uint_123 = OpConstant %uint 123
%_ptr_Function_uint = OpTypePointer Function %uint
- %35 = OpConstantNull %uint
+ %37 = OpConstantNull %uint
+ %uint_1 = OpConstant %uint 1
%v3bool = OpTypeVector %bool 3
- %38 = OpConstantComposite %v3bool %true %true %true
+ %42 = OpConstantComposite %v3bool %true %true %true
%_ptr_Function_v3bool = OpTypePointer Function %v3bool
- %41 = OpConstantNull %v3bool
+ %45 = OpConstantNull %v3bool
%v3int = OpTypeVector %int 3
- %46 = OpConstantComposite %v3int %int_123 %int_123 %int_123
+ %50 = OpConstantComposite %v3int %int_123 %int_123 %int_123
%_ptr_Function_v3int = OpTypePointer Function %v3int
- %49 = OpConstantNull %v3int
+ %53 = OpConstantNull %v3int
+ %55 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%v3uint = OpTypeVector %uint 3
- %52 = OpConstantComposite %v3uint %uint_123 %uint_123 %uint_123
+ %58 = OpConstantComposite %v3uint %uint_123 %uint_123 %uint_123
%_ptr_Function_v3uint = OpTypePointer Function %v3uint
- %55 = OpConstantNull %v3uint
- %57 = OpConstantComposite %v3bool %true %true %true
+ %61 = OpConstantNull %v3uint
+ %63 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+ %65 = OpConstantComposite %v3bool %true %true %true
%v4bool = OpTypeVector %bool 4
%false = OpConstantFalse %bool
- %61 = OpConstantComposite %v4bool %true %false %true %false
+ %69 = OpConstantComposite %v4bool %true %false %true %false
%_ptr_Function_v4bool = OpTypePointer Function %v4bool
- %64 = OpConstantNull %v4bool
+ %72 = OpConstantNull %v4bool
%constant_with_non_constant = OpFunction %void None %1
%4 = OpLabel
%a = OpVariable %_ptr_Function_float Function %6
@@ -84,34 +92,42 @@
%bool_var3 = OpVariable %_ptr_Function_bool Function %22
%i32_var1 = OpVariable %_ptr_Function_int Function %29
%i32_var2 = OpVariable %_ptr_Function_int Function %29
- %u32_var1 = OpVariable %_ptr_Function_uint Function %35
- %u32_var2 = OpVariable %_ptr_Function_uint Function %35
-%v3bool_var1 = OpVariable %_ptr_Function_v3bool Function %41
-%v3bool_var11 = OpVariable %_ptr_Function_v3bool Function %41
-%v3bool_var2 = OpVariable %_ptr_Function_v3bool Function %41
-%v3bool_var3 = OpVariable %_ptr_Function_v3bool Function %41
- %v3i32_var1 = OpVariable %_ptr_Function_v3int Function %49
- %v3i32_var2 = OpVariable %_ptr_Function_v3int Function %49
- %v3u32_var1 = OpVariable %_ptr_Function_v3uint Function %55
- %v3u32_var2 = OpVariable %_ptr_Function_v3uint Function %55
-%v3bool_var4 = OpVariable %_ptr_Function_v3bool Function %41
-%v4bool_var5 = OpVariable %_ptr_Function_v4bool Function %64
+ %i32_var3 = OpVariable %_ptr_Function_int Function %29
+ %u32_var1 = OpVariable %_ptr_Function_uint Function %37
+ %u32_var2 = OpVariable %_ptr_Function_uint Function %37
+ %u32_var3 = OpVariable %_ptr_Function_uint Function %37
+%v3bool_var1 = OpVariable %_ptr_Function_v3bool Function %45
+%v3bool_var11 = OpVariable %_ptr_Function_v3bool Function %45
+%v3bool_var2 = OpVariable %_ptr_Function_v3bool Function %45
+%v3bool_var3 = OpVariable %_ptr_Function_v3bool Function %45
+ %v3i32_var1 = OpVariable %_ptr_Function_v3int Function %53
+ %v3i32_var2 = OpVariable %_ptr_Function_v3int Function %53
+ %v3i32_var3 = OpVariable %_ptr_Function_v3int Function %53
+ %v3u32_var1 = OpVariable %_ptr_Function_v3uint Function %61
+ %v3u32_var2 = OpVariable %_ptr_Function_v3uint Function %61
+ %v3u32_var3 = OpVariable %_ptr_Function_v3uint Function %61
+%v3bool_var4 = OpVariable %_ptr_Function_v3bool Function %45
+%v4bool_var5 = OpVariable %_ptr_Function_v4bool Function %72
OpStore %bool_var1 %true
OpStore %bool_var2 %true
OpStore %bool_var3 %true
OpStore %i32_var1 %int_123
OpStore %i32_var2 %int_123
+ OpStore %i32_var3 %int_1
OpStore %u32_var1 %uint_123
OpStore %u32_var2 %uint_123
- OpStore %v3bool_var1 %38
- OpStore %v3bool_var11 %38
- OpStore %v3bool_var2 %38
- OpStore %v3bool_var3 %38
- OpStore %v3i32_var1 %46
- OpStore %v3i32_var2 %46
- OpStore %v3u32_var1 %52
- OpStore %v3u32_var2 %52
- OpStore %v3bool_var4 %57
- OpStore %v4bool_var5 %61
+ OpStore %u32_var3 %uint_1
+ OpStore %v3bool_var1 %42
+ OpStore %v3bool_var11 %42
+ OpStore %v3bool_var2 %42
+ OpStore %v3bool_var3 %42
+ OpStore %v3i32_var1 %50
+ OpStore %v3i32_var2 %50
+ OpStore %v3i32_var3 %55
+ OpStore %v3u32_var1 %58
+ OpStore %v3u32_var2 %58
+ OpStore %v3u32_var3 %63
+ OpStore %v3bool_var4 %65
+ OpStore %v4bool_var5 %69
OpReturn
OpFunctionEnd
diff --git a/test/types/function_scope_var_conversions.wgsl.expected.wgsl b/test/types/function_scope_var_conversions.wgsl.expected.wgsl
index 6c40126..de961c6 100644
--- a/test/types/function_scope_var_conversions.wgsl.expected.wgsl
+++ b/test/types/function_scope_var_conversions.wgsl.expected.wgsl
@@ -10,16 +10,20 @@
var bool_var3 : bool = bool(123.0);
var i32_var1 : i32 = i32(123u);
var i32_var2 : i32 = i32(123.0);
+ var i32_var3 : i32 = i32(true);
var u32_var1 : u32 = u32(123);
var u32_var2 : u32 = u32(123.0);
+ var u32_var3 : u32 = u32(true);
var v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(123u));
var v3bool_var11 : vec3<bool> = vec3<bool>(vec3<u32>(1234u));
var v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(123));
var v3bool_var3 : vec3<bool> = vec3<bool>(vec3<f32>(123.0));
var v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(123u));
var v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
+ var v3i32_var3 : vec3<i32> = vec3<i32>(vec3<bool>(true));
var v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(123));
var v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(123.0));
+ var v3u32_var3 : vec3<u32> = vec3<u32>(vec3<bool>(true));
var v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
}
diff --git a/test/types/module_scope_var_conversions.wgsl b/test/types/module_scope_var_conversions.wgsl
index e853046..935a1e4 100644
--- a/test/types/module_scope_var_conversions.wgsl
+++ b/test/types/module_scope_var_conversions.wgsl
@@ -4,9 +4,11 @@
var<private> i32_var1 : i32 = i32(1u);
var<private> i32_var2 : i32 = i32(1.0);
+var<private> i32_var3 : i32 = i32(true);
var<private> u32_var1 : u32 = u32(1);
var<private> u32_var2 : u32 = u32(1.0);
+var<private> u32_var3 : u32 = u32(true);
var<private> v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(1u));
var<private> v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(1));
@@ -14,9 +16,11 @@
var<private> v3i32_var1 : vec3<i32> = vec3<i32>(vec3<u32>(1u));
var<private> v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(1.0));
+var<private> v3i32_var3 : vec3<i32> = vec3<i32>(vec3<bool>(true));
var<private> v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(1));
var<private> v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(1.0));
+var<private> v3u32_var3 : vec3<u32> = vec3<u32>(vec3<bool>(true));
var<private> v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var<private> v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
@@ -29,8 +33,10 @@
bool_var3 = bool();
i32_var1 = i32();
i32_var2 = i32();
+ i32_var3 = i32();
u32_var1 = u32();
u32_var2 = u32();
+ u32_var3 = u32();
v3bool_var1 = vec3<bool>();
v3bool_var2 = vec3<bool>();
v3bool_var3 = vec3<bool>();
@@ -38,6 +44,8 @@
v4bool_var5 = vec4<bool>();
v3i32_var1 = vec3<i32>();
v3i32_var2 = vec3<i32>();
+ v3i32_var3 = vec3<i32>();
v3u32_var1 = vec3<u32>();
v3u32_var2 = vec3<u32>();
+ v3u32_var3 = vec3<u32>();
}
diff --git a/test/types/module_scope_var_conversions.wgsl.expected.hlsl b/test/types/module_scope_var_conversions.wgsl.expected.hlsl
index e2ae7ad..e637207 100644
--- a/test/types/module_scope_var_conversions.wgsl.expected.hlsl
+++ b/test/types/module_scope_var_conversions.wgsl.expected.hlsl
@@ -3,15 +3,19 @@
static bool bool_var3 = bool(1.0f);
static int i32_var1 = int(1u);
static int i32_var2 = int(1.0f);
+static int i32_var3 = int(true);
static uint u32_var1 = uint(1);
static uint u32_var2 = uint(1.0f);
+static uint u32_var3 = uint(true);
static bool3 v3bool_var1 = bool3(uint3((1u).xxx));
static bool3 v3bool_var2 = bool3(int3((1).xxx));
static bool3 v3bool_var3 = bool3(float3((1.0f).xxx));
static int3 v3i32_var1 = int3(uint3((1u).xxx));
static int3 v3i32_var2 = int3(float3((1.0f).xxx));
+static int3 v3i32_var3 = int3(bool3((true).xxx));
static uint3 v3u32_var1 = uint3(int3((1).xxx));
static uint3 v3u32_var2 = uint3(float3((1.0f).xxx));
+static uint3 v3u32_var3 = uint3(bool3((true).xxx));
static bool3 v3bool_var4 = bool3(bool2(float2((123.0f).xx)), true);
static bool4 v4bool_var5 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
@@ -22,8 +26,10 @@
bool_var3 = false;
i32_var1 = 0;
i32_var2 = 0;
+ i32_var3 = 0;
u32_var1 = 0u;
u32_var2 = 0u;
+ u32_var3 = 0u;
v3bool_var1 = bool3(false, false, false);
v3bool_var2 = bool3(false, false, false);
v3bool_var3 = bool3(false, false, false);
@@ -31,7 +37,9 @@
v4bool_var5 = bool4(false, false, false, false);
v3i32_var1 = int3(0, 0, 0);
v3i32_var2 = int3(0, 0, 0);
+ v3i32_var3 = int3(0, 0, 0);
v3u32_var1 = uint3(0u, 0u, 0u);
v3u32_var2 = uint3(0u, 0u, 0u);
+ v3u32_var3 = uint3(0u, 0u, 0u);
return;
}
diff --git a/test/types/module_scope_var_conversions.wgsl.expected.msl b/test/types/module_scope_var_conversions.wgsl.expected.msl
index 3cda311..072e9b0 100644
--- a/test/types/module_scope_var_conversions.wgsl.expected.msl
+++ b/test/types/module_scope_var_conversions.wgsl.expected.msl
@@ -7,33 +7,41 @@
thread bool tint_symbol_3 = bool(1.0f);
thread int tint_symbol_4 = int(1u);
thread int tint_symbol_5 = int(1.0f);
- thread uint tint_symbol_6 = uint(1);
- thread uint tint_symbol_7 = uint(1.0f);
- thread bool3 tint_symbol_8 = bool3(uint3(1u));
- thread bool3 tint_symbol_9 = bool3(int3(1));
- thread bool3 tint_symbol_10 = bool3(float3(1.0f));
- thread bool3 tint_symbol_11 = bool3(bool2(float2(123.0f)), true);
- thread bool4 tint_symbol_12 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
- thread int3 tint_symbol_13 = int3(uint3(1u));
- thread int3 tint_symbol_14 = int3(float3(1.0f));
- thread uint3 tint_symbol_15 = uint3(int3(1));
- thread uint3 tint_symbol_16 = uint3(float3(1.0f));
+ thread int tint_symbol_6 = int(true);
+ thread uint tint_symbol_7 = uint(1);
+ thread uint tint_symbol_8 = uint(1.0f);
+ thread uint tint_symbol_9 = uint(true);
+ thread bool3 tint_symbol_10 = bool3(uint3(1u));
+ thread bool3 tint_symbol_11 = bool3(int3(1));
+ thread bool3 tint_symbol_12 = bool3(float3(1.0f));
+ thread bool3 tint_symbol_13 = bool3(bool2(float2(123.0f)), true);
+ thread bool4 tint_symbol_14 = bool4(bool2(float2(123.0f, 0.0f)), bool2(true, bool(float(0.0f))));
+ thread int3 tint_symbol_15 = int3(uint3(1u));
+ thread int3 tint_symbol_16 = int3(float3(1.0f));
+ thread int3 tint_symbol_17 = int3(bool3(true));
+ thread uint3 tint_symbol_18 = uint3(int3(1));
+ thread uint3 tint_symbol_19 = uint3(float3(1.0f));
+ thread uint3 tint_symbol_20 = uint3(bool3(true));
tint_symbol_1 = bool();
tint_symbol_2 = bool();
tint_symbol_3 = bool();
tint_symbol_4 = int();
tint_symbol_5 = int();
- tint_symbol_6 = uint();
+ tint_symbol_6 = int();
tint_symbol_7 = uint();
- tint_symbol_8 = bool3();
- tint_symbol_9 = bool3();
+ tint_symbol_8 = uint();
+ tint_symbol_9 = uint();
tint_symbol_10 = bool3();
tint_symbol_11 = bool3();
- tint_symbol_12 = bool4();
- tint_symbol_13 = int3();
- tint_symbol_14 = int3();
- tint_symbol_15 = uint3();
- tint_symbol_16 = uint3();
+ tint_symbol_12 = bool3();
+ tint_symbol_13 = bool3();
+ tint_symbol_14 = bool4();
+ tint_symbol_15 = int3();
+ tint_symbol_16 = int3();
+ tint_symbol_17 = int3();
+ tint_symbol_18 = uint3();
+ tint_symbol_19 = uint3();
+ tint_symbol_20 = uint3();
return;
}
diff --git a/test/types/module_scope_var_conversions.wgsl.expected.spvasm b/test/types/module_scope_var_conversions.wgsl.expected.spvasm
index bfe6b27..7c8e142 100644
--- a/test/types/module_scope_var_conversions.wgsl.expected.spvasm
+++ b/test/types/module_scope_var_conversions.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.3
; Generator: Google Tint Compiler; 0
-; Bound: 51
+; Bound: 55
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -12,15 +12,19 @@
OpName %bool_var3 "bool_var3"
OpName %i32_var1 "i32_var1"
OpName %i32_var2 "i32_var2"
+ OpName %i32_var3 "i32_var3"
OpName %u32_var1 "u32_var1"
OpName %u32_var2 "u32_var2"
+ OpName %u32_var3 "u32_var3"
OpName %v3bool_var1 "v3bool_var1"
OpName %v3bool_var2 "v3bool_var2"
OpName %v3bool_var3 "v3bool_var3"
OpName %v3i32_var1 "v3i32_var1"
OpName %v3i32_var2 "v3i32_var2"
+ OpName %v3i32_var3 "v3i32_var3"
OpName %v3u32_var1 "v3u32_var1"
OpName %v3u32_var2 "v3u32_var2"
+ OpName %v3u32_var3 "v3u32_var3"
OpName %v3bool_var4 "v3bool_var4"
OpName %v4bool_var5 "v4bool_var5"
OpName %main "main"
@@ -35,60 +39,68 @@
%_ptr_Private_int = OpTypePointer Private %int
%i32_var1 = OpVariable %_ptr_Private_int Private %int_1
%i32_var2 = OpVariable %_ptr_Private_int Private %int_1
+ %i32_var3 = OpVariable %_ptr_Private_int Private %int_1
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_ptr_Private_uint = OpTypePointer Private %uint
%u32_var1 = OpVariable %_ptr_Private_uint Private %uint_1
%u32_var2 = OpVariable %_ptr_Private_uint Private %uint_1
+ %u32_var3 = OpVariable %_ptr_Private_uint Private %uint_1
%v3bool = OpTypeVector %bool 3
- %18 = OpConstantComposite %v3bool %true %true %true
+ %20 = OpConstantComposite %v3bool %true %true %true
%_ptr_Private_v3bool = OpTypePointer Private %v3bool
-%v3bool_var1 = OpVariable %_ptr_Private_v3bool Private %18
-%v3bool_var2 = OpVariable %_ptr_Private_v3bool Private %18
-%v3bool_var3 = OpVariable %_ptr_Private_v3bool Private %18
+%v3bool_var1 = OpVariable %_ptr_Private_v3bool Private %20
+%v3bool_var2 = OpVariable %_ptr_Private_v3bool Private %20
+%v3bool_var3 = OpVariable %_ptr_Private_v3bool Private %20
%v3int = OpTypeVector %int 3
- %24 = OpConstantComposite %v3int %int_1 %int_1 %int_1
+ %26 = OpConstantComposite %v3int %int_1 %int_1 %int_1
%_ptr_Private_v3int = OpTypePointer Private %v3int
- %v3i32_var1 = OpVariable %_ptr_Private_v3int Private %24
- %v3i32_var2 = OpVariable %_ptr_Private_v3int Private %24
+ %v3i32_var1 = OpVariable %_ptr_Private_v3int Private %26
+ %v3i32_var2 = OpVariable %_ptr_Private_v3int Private %26
+ %v3i32_var3 = OpVariable %_ptr_Private_v3int Private %26
%v3uint = OpTypeVector %uint 3
- %29 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+ %32 = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
%_ptr_Private_v3uint = OpTypePointer Private %v3uint
- %v3u32_var1 = OpVariable %_ptr_Private_v3uint Private %29
- %v3u32_var2 = OpVariable %_ptr_Private_v3uint Private %29
- %33 = OpConstantComposite %v3bool %true %true %true
-%v3bool_var4 = OpVariable %_ptr_Private_v3bool Private %33
+ %v3u32_var1 = OpVariable %_ptr_Private_v3uint Private %32
+ %v3u32_var2 = OpVariable %_ptr_Private_v3uint Private %32
+ %v3u32_var3 = OpVariable %_ptr_Private_v3uint Private %32
+ %37 = OpConstantComposite %v3bool %true %true %true
+%v3bool_var4 = OpVariable %_ptr_Private_v3bool Private %37
%v4bool = OpTypeVector %bool 4
%false = OpConstantFalse %bool
- %37 = OpConstantComposite %v4bool %true %false %true %false
+ %41 = OpConstantComposite %v4bool %true %false %true %false
%_ptr_Private_v4bool = OpTypePointer Private %v4bool
-%v4bool_var5 = OpVariable %_ptr_Private_v4bool Private %37
+%v4bool_var5 = OpVariable %_ptr_Private_v4bool Private %41
%void = OpTypeVoid
- %40 = OpTypeFunction %void
- %44 = OpConstantNull %bool
- %45 = OpConstantNull %int
- %46 = OpConstantNull %uint
- %47 = OpConstantNull %v3bool
- %48 = OpConstantNull %v4bool
- %49 = OpConstantNull %v3int
- %50 = OpConstantNull %v3uint
- %main = OpFunction %void None %40
- %43 = OpLabel
- OpStore %bool_var1 %44
- OpStore %bool_var2 %44
- OpStore %bool_var3 %44
- OpStore %i32_var1 %45
- OpStore %i32_var2 %45
- OpStore %u32_var1 %46
- OpStore %u32_var2 %46
- OpStore %v3bool_var1 %47
- OpStore %v3bool_var2 %47
- OpStore %v3bool_var3 %47
- OpStore %v3bool_var4 %47
- OpStore %v4bool_var5 %48
- OpStore %v3i32_var1 %49
- OpStore %v3i32_var2 %49
- OpStore %v3u32_var1 %50
- OpStore %v3u32_var2 %50
+ %44 = OpTypeFunction %void
+ %48 = OpConstantNull %bool
+ %49 = OpConstantNull %int
+ %50 = OpConstantNull %uint
+ %51 = OpConstantNull %v3bool
+ %52 = OpConstantNull %v4bool
+ %53 = OpConstantNull %v3int
+ %54 = OpConstantNull %v3uint
+ %main = OpFunction %void None %44
+ %47 = OpLabel
+ OpStore %bool_var1 %48
+ OpStore %bool_var2 %48
+ OpStore %bool_var3 %48
+ OpStore %i32_var1 %49
+ OpStore %i32_var2 %49
+ OpStore %i32_var3 %49
+ OpStore %u32_var1 %50
+ OpStore %u32_var2 %50
+ OpStore %u32_var3 %50
+ OpStore %v3bool_var1 %51
+ OpStore %v3bool_var2 %51
+ OpStore %v3bool_var3 %51
+ OpStore %v3bool_var4 %51
+ OpStore %v4bool_var5 %52
+ OpStore %v3i32_var1 %53
+ OpStore %v3i32_var2 %53
+ OpStore %v3i32_var3 %53
+ OpStore %v3u32_var1 %54
+ OpStore %v3u32_var2 %54
+ OpStore %v3u32_var3 %54
OpReturn
OpFunctionEnd
diff --git a/test/types/module_scope_var_conversions.wgsl.expected.wgsl b/test/types/module_scope_var_conversions.wgsl.expected.wgsl
index 457e128..f3b8876 100644
--- a/test/types/module_scope_var_conversions.wgsl.expected.wgsl
+++ b/test/types/module_scope_var_conversions.wgsl.expected.wgsl
@@ -8,10 +8,14 @@
var<private> i32_var2 : i32 = i32(1.0);
+var<private> i32_var3 : i32 = i32(true);
+
var<private> u32_var1 : u32 = u32(1);
var<private> u32_var2 : u32 = u32(1.0);
+var<private> u32_var3 : u32 = u32(true);
+
var<private> v3bool_var1 : vec3<bool> = vec3<bool>(vec3<u32>(1u));
var<private> v3bool_var2 : vec3<bool> = vec3<bool>(vec3<i32>(1));
@@ -22,10 +26,14 @@
var<private> v3i32_var2 : vec3<i32> = vec3<i32>(vec3<f32>(1.0));
+var<private> v3i32_var3 : vec3<i32> = vec3<i32>(vec3<bool>(true));
+
var<private> v3u32_var1 : vec3<u32> = vec3<u32>(vec3<i32>(1));
var<private> v3u32_var2 : vec3<u32> = vec3<u32>(vec3<f32>(1.0));
+var<private> v3u32_var3 : vec3<u32> = vec3<u32>(vec3<bool>(true));
+
var<private> v3bool_var4 : vec3<bool> = vec3<bool>(vec2<bool>(vec2<f32>(123.0)), true);
var<private> v4bool_var5 : vec4<bool> = vec4<bool>(vec2<bool>(vec2<f32>(123.0, 0.0)), vec2<bool>(true, bool(f32(0.0))));
@@ -37,8 +45,10 @@
bool_var3 = bool();
i32_var1 = i32();
i32_var2 = i32();
+ i32_var3 = i32();
u32_var1 = u32();
u32_var2 = u32();
+ u32_var3 = u32();
v3bool_var1 = vec3<bool>();
v3bool_var2 = vec3<bool>();
v3bool_var3 = vec3<bool>();
@@ -46,6 +56,8 @@
v4bool_var5 = vec4<bool>();
v3i32_var1 = vec3<i32>();
v3i32_var2 = vec3<i32>();
+ v3i32_var3 = vec3<i32>();
v3u32_var1 = vec3<u32>();
v3u32_var2 = vec3<u32>();
+ v3u32_var3 = vec3<u32>();
}