Import Tint changes from Dawn Changes: - 25b7e98d1100f3dd5b261915867fc2fbf3dedae0 tint/writer/glsl: Inline constant expressions by Ben Clayton <bclayton@google.com> - 37d92ca244bfef3de3d6f550fef4cf8547186397 tint/spirv: Fix atomicCompareExchangeWeak by James Price <jrprice@google.com> - 7e495d8f2e06c7cea5813abb1cc5efbfe101faae tint/resolver: Implement candidate overload resolution by Ben Clayton <bclayton@google.com> - bfb5fd794c13e846e40a4cb89e7dc20fbc1275a9 tint/sem: Add more helpers to Constant by Ben Clayton <bclayton@google.com> - 8bd5fec4827798143c44422db34a378124a3bedd tint/writer/wgsl: Emit 'f' suffix on FloatLiteralExpressi... by Ben Clayton <bclayton@google.com> - 22bd00440900120d9245a3459cbf367a853e9e42 tint/resolver: Materialize RHS of non-phony assignments by Ben Clayton <bclayton@google.com> - 649d3d9602e46f59b4cd895ac4f40f74c43d109e tint/resolver: Materialize array size expression by Ben Clayton <bclayton@google.com> - 49a09140b9384da37715738cdb9fb45f93a14abd tint/resolver: Materialize array index expression by Ben Clayton <bclayton@google.com> - 08f4b557fcf03e7fa6fea0342fb47b7c194f27be Implement atomicCompareExchangeWeak returning struct inst... by Antonio Maiorano <amaiorano@google.com> - 61537d3f57736c99aed0b0077a3229fca5b01ed9 tint: Add Checked[Add|Mul|Madd]() by Ben Clayton <bclayton@google.com> GitOrigin-RevId: 25b7e98d1100f3dd5b261915867fc2fbf3dedae0 Change-Id: Ie16c7cf14e70eec1b1a6dc8b34984cf329043147 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/92200 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/ast/float_literal_expression.cc b/src/tint/ast/float_literal_expression.cc index ab2d6cf..36cb42a 100644 --- a/src/tint/ast/float_literal_expression.cc +++ b/src/tint/ast/float_literal_expression.cc
@@ -36,4 +36,15 @@ return ctx->dst->create<FloatLiteralExpression>(src, value, suffix); } +std::ostream& operator<<(std::ostream& out, FloatLiteralExpression::Suffix suffix) { + switch (suffix) { + default: + return out; + case FloatLiteralExpression::Suffix::kF: + return out << "f"; + case FloatLiteralExpression::Suffix::kH: + return out << "h"; + } +} + } // namespace tint::ast
diff --git a/src/tint/ast/float_literal_expression.h b/src/tint/ast/float_literal_expression.h index 72a395f..7f03caf 100644 --- a/src/tint/ast/float_literal_expression.h +++ b/src/tint/ast/float_literal_expression.h
@@ -55,6 +55,12 @@ const Suffix suffix; }; +/// Writes the float literal suffix to the std::ostream. +/// @param out the std::ostream to write to +/// @param suffix the suffix to write +/// @returns out so calls can be chained +std::ostream& operator<<(std::ostream& out, FloatLiteralExpression::Suffix suffix); + } // namespace tint::ast #endif // SRC_TINT_AST_FLOAT_LITERAL_EXPRESSION_H_
diff --git a/src/tint/ast/float_literal_expression_test.cc b/src/tint/ast/float_literal_expression_test.cc index a2f9b25..5ec5f0f 100644 --- a/src/tint/ast/float_literal_expression_test.cc +++ b/src/tint/ast/float_literal_expression_test.cc
@@ -33,5 +33,24 @@ EXPECT_EQ(i->suffix, FloatLiteralExpression::Suffix::kF); } +TEST_F(FloatLiteralExpressionTest, SuffixH) { + auto* i = create<FloatLiteralExpression>(42.0, FloatLiteralExpression::Suffix::kH); + ASSERT_TRUE(i->Is<FloatLiteralExpression>()); + EXPECT_EQ(i->value, 42); + EXPECT_EQ(i->suffix, FloatLiteralExpression::Suffix::kH); +} + +TEST_F(FloatLiteralExpressionTest, SuffixStringStream) { + auto to_str = [](FloatLiteralExpression::Suffix suffix) { + std::stringstream ss; + ss << suffix; + return ss.str(); + }; + + EXPECT_EQ("", to_str(FloatLiteralExpression::Suffix::kNone)); + EXPECT_EQ("f", to_str(FloatLiteralExpression::Suffix::kF)); + EXPECT_EQ("h", to_str(FloatLiteralExpression::Suffix::kH)); +} + } // namespace } // namespace tint::ast
diff --git a/src/tint/ast/int_literal_expression_test.cc b/src/tint/ast/int_literal_expression_test.cc index 8bc3d2f..969e1b9 100644 --- a/src/tint/ast/int_literal_expression_test.cc +++ b/src/tint/ast/int_literal_expression_test.cc
@@ -40,5 +40,17 @@ EXPECT_EQ(i->suffix, IntLiteralExpression::Suffix::kU); } +TEST_F(IntLiteralExpressionTest, SuffixStringStream) { + auto to_str = [](IntLiteralExpression::Suffix suffix) { + std::stringstream ss; + ss << suffix; + return ss.str(); + }; + + EXPECT_EQ("", to_str(IntLiteralExpression::Suffix::kNone)); + EXPECT_EQ("i", to_str(IntLiteralExpression::Suffix::kI)); + EXPECT_EQ("u", to_str(IntLiteralExpression::Suffix::kU)); +} + } // namespace } // namespace tint::ast
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def index bc4bf28..28be2d9 100644 --- a/src/tint/intrinsics.def +++ b/src/tint/intrinsics.def
@@ -118,6 +118,8 @@ type __frexp_result [[display("__frexp_result_vec{N}")]] type __frexp_result_vec<N: num> +type __atomic_compare_exchange_result<T> + //////////////////////////////////////////////////////////////////////////////// // Type matchers // // // @@ -206,13 +208,12 @@ // Matching algorithm for a single overload: // // ----------------------------------------- // // // -// The goal of matching is to compare a function call's arguments in the // -// program source against a possibly-templated overload declaration, and // -// determine if the call satisfies the form and type constraints of the // -// overload. Currently it is impossible for a call to match more than one // -// overload definition. In the event that more than one overload matches, an // -// ICE will be raised. Note that Tint may need to support multiple-overload // -// resolution in the future, depending on future overload definitions. // +// The goal of matching is to compare a function call's arguments and any // +// explicitly provided template types in the program source against an // +// overload declaration in this file, and determine if the call satisfies // +// the form and type constraints of the overload. If the call matches an // +// overload, then the overload is added to the list of 'overload candidates' // +// used for overload resolution (described below). // // // // Prior to matching an overload, all template types are undefined. // // // @@ -256,11 +257,11 @@ // need to be checked next. If the defined type does not match the // // 'match' constraint, then the overload is no longer considered. // // // -// This algorithm is less general than the overload resolution described in // -// the WGSL spec. But it makes the same decisions because the overloads // -// defined by WGSL are monotonic in the sense that once a template parameter // -// has been refined, there is never a need to backtrack and un-refine it to // -// match a later argument. // +// This algorithm for matching a single overload is less general than the // +// algorithm described in the WGSL spec. But it makes the same decisions // +// because the overloads defined by WGSL are monotonic in the sense that once // +// a template parameter has been refined, there is never a need to backtrack // +// and un-refine it to match a later argument. // // // // The algorithm for matching template numbers is similar to matching // // template types, except numbers need to exactly match across all uses - // @@ -268,7 +269,24 @@ // numbers or enumerators. // // // // // -// * More examples: // +// Overload resolution for candidate overloads // +// ------------------------------------------- // +// // +// If multiple candidate overloads match a given set of arguments, then a // +// final overload resolution pass needs to be performed. The arguments and // +// overload parameter types for each candidate overload are compared, // +// following the algorithm described at: // +// https://www.w3.org/TR/WGSL/#overload-resolution-section // +// // +// If the candidate list contains a single entry, then that single candidate // +// is picked, and no overload resolution needs to be performed. // +// // +// If the candidate list is empty, then the call fails to resolve and an // +// error diagnostic is raised. // +// // +// // +// More examples // +// ------------- // // // // fn F() // // - Function called F. // @@ -603,7 +621,7 @@ [[stage("fragment", "compute")]] fn atomicOr<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T [[stage("fragment", "compute")]] fn atomicXor<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T [[stage("fragment", "compute")]] fn atomicExchange<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T -[[stage("fragment", "compute")]] fn atomicCompareExchangeWeak<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> vec2<T> +[[stage("fragment", "compute")]] fn atomicCompareExchangeWeak<T: iu32, S: workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> //////////////////////////////////////////////////////////////////////////////// // Type constructors //
diff --git a/src/tint/number.h b/src/tint/number.h index 6efb023..b4c5ca4 100644 --- a/src/tint/number.h +++ b/src/tint/number.h
@@ -19,7 +19,10 @@ #include <functional> #include <limits> #include <ostream> +// TODO(https://crbug.com/dawn/1379) Update cpplint and remove NOLINT +#include <optional> // NOLINT(build/include_order)) +#include "src/tint/utils/compiler_macros.h" #include "src/tint/utils/result.h" // Forward declaration @@ -184,33 +187,6 @@ return !(a == b); } -/// Enumerator of failure reasons when converting from one number to another. -enum class ConversionFailure { - kExceedsPositiveLimit, // The value was too big (+'ve) to fit in the target type - kExceedsNegativeLimit, // The value was too big (-'ve) to fit in the target type -}; - -/// Writes the conversion failure message to the ostream. -/// @param out the std::ostream to write to -/// @param failure the ConversionFailure -/// @return the std::ostream so calls can be chained -std::ostream& operator<<(std::ostream& out, ConversionFailure failure); - -/// Converts a number from one type to another, checking that the value fits in the target type. -/// @returns the resulting value of the conversion, or a failure reason. -template <typename TO, typename FROM> -utils::Result<TO, ConversionFailure> CheckedConvert(Number<FROM> num) { - using T = decltype(UnwrapNumber<TO>() + num.value); - const auto value = static_cast<T>(num.value); - if (value > static_cast<T>(TO::kHighest)) { - return ConversionFailure::kExceedsPositiveLimit; - } - if (value < static_cast<T>(TO::kLowest)) { - return ConversionFailure::kExceedsNegativeLimit; - } - return TO(value); // Success -} - /// The partial specification of Number for f16 type, storing the f16 value as float, /// and enforcing proper explicit casting. template <> @@ -282,6 +258,114 @@ /// However since C++ don't have native binary16 type, the value is stored as float. using f16 = Number<detail::NumberKindF16>; +/// Enumerator of failure reasons when converting from one number to another. +enum class ConversionFailure { + kExceedsPositiveLimit, // The value was too big (+'ve) to fit in the target type + kExceedsNegativeLimit, // The value was too big (-'ve) to fit in the target type +}; + +/// Writes the conversion failure message to the ostream. +/// @param out the std::ostream to write to +/// @param failure the ConversionFailure +/// @return the std::ostream so calls can be chained +std::ostream& operator<<(std::ostream& out, ConversionFailure failure); + +/// Converts a number from one type to another, checking that the value fits in the target type. +/// @returns the resulting value of the conversion, or a failure reason. +template <typename TO, typename FROM> +utils::Result<TO, ConversionFailure> CheckedConvert(Number<FROM> num) { + using T = decltype(UnwrapNumber<TO>() + num.value); + const auto value = static_cast<T>(num.value); + if (value > static_cast<T>(TO::kHighest)) { + return ConversionFailure::kExceedsPositiveLimit; + } + if (value < static_cast<T>(TO::kLowest)) { + return ConversionFailure::kExceedsNegativeLimit; + } + return TO(value); // Success +} + +/// Define 'TINT_HAS_OVERFLOW_BUILTINS' if the compiler provide overflow checking builtins. +/// If the compiler does not support these builtins, then these are emulated with algorithms +/// described in: +/// https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow +#if defined(__GNUC__) && __GNUC__ >= 5 +#define TINT_HAS_OVERFLOW_BUILTINS +#elif defined(__clang__) +#if __has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_mul_overflow) +#define TINT_HAS_OVERFLOW_BUILTINS +#endif +#endif + +/// @returns a + b, or an empty optional if the resulting value overflowed the AInt +inline std::optional<AInt> CheckedAdd(AInt a, AInt b) { + int64_t result; +#ifdef TINT_HAS_OVERFLOW_BUILTINS + if (__builtin_add_overflow(a.value, b.value, &result)) { + return {}; + } +#else // TINT_HAS_OVERFLOW_BUILTINS + if (a.value >= 0) { + if (AInt::kHighest - a.value < b.value) { + return {}; + } + } else { + if (b.value < AInt::kLowest - a.value) { + return {}; + } + } + result = a.value + b.value; +#endif // TINT_HAS_OVERFLOW_BUILTINS + return AInt(result); +} + +/// @returns a * b, or an empty optional if the resulting value overflowed the AInt +inline std::optional<AInt> CheckedMul(AInt a, AInt b) { + int64_t result; +#ifdef TINT_HAS_OVERFLOW_BUILTINS + if (__builtin_mul_overflow(a.value, b.value, &result)) { + return {}; + } +#else // TINT_HAS_OVERFLOW_BUILTINS + if (a > 0) { + if (b > 0) { + if (a > (AInt::kHighest / b)) { + return {}; + } + } else { + if (b < (AInt::kLowest / a)) { + return {}; + } + } + } else { + if (b > 0) { + if (a < (AInt::kLowest / b)) { + return {}; + } + } else { + if ((a != 0) && (b < (AInt::kHighest / a))) { + return {}; + } + } + } + result = a.value * b.value; +#endif // TINT_HAS_OVERFLOW_BUILTINS + return AInt(result); +} + +/// @returns a * b + c, or an empty optional if the value overflowed the AInt +inline std::optional<AInt> CheckedMadd(AInt a, AInt b, AInt c) { + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 + TINT_BEGIN_DISABLE_WARNING(MAYBE_UNINITIALIZED); + + if (auto mul = CheckedMul(a, b)) { + return CheckedAdd(mul.value(), c); + } + return {}; + + TINT_END_DISABLE_WARNING(MAYBE_UNINITIALIZED); +} + } // namespace tint namespace tint::number_suffixes {
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc index a7bb2fe..34b4d39 100644 --- a/src/tint/number_test.cc +++ b/src/tint/number_test.cc
@@ -13,6 +13,8 @@ // limitations under the License. #include <cmath> +#include <tuple> +#include <vector> #include "src/tint/program_builder.h" #include "src/tint/utils/compiler_macros.h" @@ -141,6 +143,165 @@ EXPECT_TRUE(std::isnan(f16(nan))); } +using BinaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt>; + +#undef OVERFLOW // corecrt_math.h :( +#define OVERFLOW \ + {} + +using CheckedAddTest = testing::TestWithParam<BinaryCheckedCase>; +TEST_P(CheckedAddTest, Test) { + auto expect = std::get<0>(GetParam()); + auto a = std::get<1>(GetParam()); + auto b = std::get<2>(GetParam()); + EXPECT_EQ(CheckedAdd(a, b), expect) << std::hex << "0x" << a << " * 0x" << b; + EXPECT_EQ(CheckedAdd(b, a), expect) << std::hex << "0x" << a << " * 0x" << b; +} +INSTANTIATE_TEST_SUITE_P( + CheckedAddTest, + CheckedAddTest, + testing::ValuesIn(std::vector<BinaryCheckedCase>{ + {AInt(0), AInt(0), AInt(0)}, + {AInt(1), AInt(1), AInt(0)}, + {AInt(2), AInt(1), AInt(1)}, + {AInt(0), AInt(-1), AInt(1)}, + {AInt(3), AInt(2), AInt(1)}, + {AInt(-1), AInt(-2), AInt(1)}, + {AInt(0x300), AInt(0x100), AInt(0x200)}, + {AInt(0x100), AInt(-0x100), AInt(0x200)}, + {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest - 1)}, + {AInt(AInt::kLowest), AInt(-1), AInt(AInt::kLowest + 1)}, + {AInt(AInt::kHighest), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)}, + {AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)}, + {AInt(AInt::kLowest), AInt(AInt::kLowest), AInt(0)}, + {OVERFLOW, AInt(1), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(-1), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(2), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(-2), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(10000), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(-10000), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(AInt::kLowest), AInt(AInt::kLowest)}, + //////////////////////////////////////////////////////////////////////// + })); + +using CheckedMulTest = testing::TestWithParam<BinaryCheckedCase>; +TEST_P(CheckedMulTest, Test) { + auto expect = std::get<0>(GetParam()); + auto a = std::get<1>(GetParam()); + auto b = std::get<2>(GetParam()); + EXPECT_EQ(CheckedMul(a, b), expect) << std::hex << "0x" << a << " * 0x" << b; + EXPECT_EQ(CheckedMul(b, a), expect) << std::hex << "0x" << a << " * 0x" << b; +} +INSTANTIATE_TEST_SUITE_P( + CheckedMulTest, + CheckedMulTest, + testing::ValuesIn(std::vector<BinaryCheckedCase>{ + {AInt(0), AInt(0), AInt(0)}, + {AInt(0), AInt(1), AInt(0)}, + {AInt(1), AInt(1), AInt(1)}, + {AInt(-1), AInt(-1), AInt(1)}, + {AInt(2), AInt(2), AInt(1)}, + {AInt(-2), AInt(-2), AInt(1)}, + {AInt(0x20000), AInt(0x100), AInt(0x200)}, + {AInt(-0x20000), AInt(-0x100), AInt(0x200)}, + {AInt(0x4000000000000000ll), AInt(0x80000000ll), AInt(0x80000000ll)}, + {AInt(0x4000000000000000ll), AInt(-0x80000000ll), AInt(-0x80000000ll)}, + {AInt(0x1000000000000000ll), AInt(0x40000000ll), AInt(0x40000000ll)}, + {AInt(-0x1000000000000000ll), AInt(-0x40000000ll), AInt(0x40000000ll)}, + {AInt(0x100000000000000ll), AInt(0x1000000), AInt(0x100000000ll)}, + {AInt(0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(2)}, + {AInt(-0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(-2)}, + {AInt(-0x2000000000000000ll), AInt(-0x1000000000000000ll), AInt(2)}, + {AInt(-0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(-2)}, + {AInt(0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(4)}, + {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4)}, + {AInt(-0x4000000000000000ll), AInt(-0x1000000000000000ll), AInt(4)}, + {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4)}, + {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8)}, + {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8)}, + {AInt(0), AInt(AInt::kHighest), AInt(0)}, + {AInt(0), AInt(AInt::kLowest), AInt(0)}, + {OVERFLOW, AInt(0x1000000000000000ll), AInt(8)}, + {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8)}, + {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10)}, + {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll)}, + {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest)}, + //////////////////////////////////////////////////////////////////////// + })); + +using TernaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt, AInt>; + +using CheckedMaddTest = testing::TestWithParam<TernaryCheckedCase>; +TEST_P(CheckedMaddTest, Test) { + auto expect = std::get<0>(GetParam()); + auto a = std::get<1>(GetParam()); + auto b = std::get<2>(GetParam()); + auto c = std::get<3>(GetParam()); + EXPECT_EQ(CheckedMadd(a, b, c), expect) + << std::hex << "0x" << a << " * 0x" << b << " + 0x" << c; + EXPECT_EQ(CheckedMadd(b, a, c), expect) + << std::hex << "0x" << a << " * 0x" << b << " + 0x" << c; +} +INSTANTIATE_TEST_SUITE_P( + CheckedMaddTest, + CheckedMaddTest, + testing::ValuesIn(std::vector<TernaryCheckedCase>{ + {AInt(0), AInt(0), AInt(0), AInt(0)}, + {AInt(0), AInt(1), AInt(0), AInt(0)}, + {AInt(1), AInt(1), AInt(1), AInt(0)}, + {AInt(2), AInt(1), AInt(1), AInt(1)}, + {AInt(0), AInt(1), AInt(-1), AInt(1)}, + {AInt(-1), AInt(1), AInt(-2), AInt(1)}, + {AInt(-1), AInt(-1), AInt(1), AInt(0)}, + {AInt(2), AInt(2), AInt(1), AInt(0)}, + {AInt(-2), AInt(-2), AInt(1), AInt(0)}, + {AInt(0), AInt(AInt::kHighest), AInt(0), AInt(0)}, + {AInt(0), AInt(AInt::kLowest), AInt(0), AInt(0)}, + {AInt(3), AInt(1), AInt(2), AInt(1)}, + {AInt(0x300), AInt(1), AInt(0x100), AInt(0x200)}, + {AInt(0x100), AInt(1), AInt(-0x100), AInt(0x200)}, + {AInt(0x20000), AInt(0x100), AInt(0x200), AInt(0)}, + {AInt(-0x20000), AInt(-0x100), AInt(0x200), AInt(0)}, + {AInt(0x4000000000000000ll), AInt(0x80000000ll), AInt(0x80000000ll), AInt(0)}, + {AInt(0x4000000000000000ll), AInt(-0x80000000ll), AInt(-0x80000000ll), AInt(0)}, + {AInt(0x1000000000000000ll), AInt(0x40000000ll), AInt(0x40000000ll), AInt(0)}, + {AInt(-0x1000000000000000ll), AInt(-0x40000000ll), AInt(0x40000000ll), AInt(0)}, + {AInt(0x100000000000000ll), AInt(0x1000000), AInt(0x100000000ll), AInt(0)}, + {AInt(0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(2), AInt(0)}, + {AInt(-0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(-2), AInt(0)}, + {AInt(-0x2000000000000000ll), AInt(-0x1000000000000000ll), AInt(2), AInt(0)}, + {AInt(-0x2000000000000000ll), AInt(0x1000000000000000ll), AInt(-2), AInt(0)}, + {AInt(0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(4), AInt(0)}, + {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4), AInt(0)}, + {AInt(-0x4000000000000000ll), AInt(-0x1000000000000000ll), AInt(4), AInt(0)}, + {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4), AInt(0)}, + {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8), AInt(0)}, + {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8), AInt(0)}, + {AInt(AInt::kHighest), AInt(1), AInt(1), AInt(AInt::kHighest - 1)}, + {AInt(AInt::kLowest), AInt(1), AInt(-1), AInt(AInt::kLowest + 1)}, + {AInt(AInt::kHighest), AInt(1), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)}, + {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest), AInt(0)}, + {AInt(AInt::kLowest), AInt(1), AInt(AInt::kLowest), AInt(0)}, + {OVERFLOW, AInt(0x1000000000000000ll), AInt(8), AInt(0)}, + {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8), AInt(0)}, + {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10), AInt(0)}, + {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll), AInt(0)}, + {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)}, + {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest), AInt(0)}, + {OVERFLOW, AInt(1), AInt(1), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(1), AInt(-1), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(1), AInt(2), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(1), AInt(-2), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(1), AInt(10000), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(1), AInt(-10000), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(AInt::kHighest)}, + {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(AInt::kLowest)}, + {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(1)}, + {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(-1)}, + })); + TINT_END_DISABLE_WARNING(CONSTANT_OVERFLOW); } // namespace
diff --git a/src/tint/reader/spirv/function_arithmetic_test.cc b/src/tint/reader/spirv/function_arithmetic_test.cc index 9db49d9..0597916 100644 --- a/src/tint/reader/spirv/function_arithmetic_test.cc +++ b/src/tint/reader/spirv/function_arithmetic_test.cc
@@ -93,10 +93,10 @@ return "bitcast<vec2<u32>>(vec2<i32>(40i, 30i))"; } if (assembly == "v2float_50_60") { - return "vec2<f32>(50.0, 60.0)"; + return "vec2<f32>(50.0f, 60.0f)"; } if (assembly == "v2float_60_50") { - return "vec2<f32>(60.0, 50.0)"; + return "vec2<f32>(60.0f, 50.0f)"; } return "bad case"; } @@ -253,7 +253,7 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : f32 = -(50.0);")); + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : f32 = -(50.0f);")); } TEST_F(SpvUnaryArithTest, FNegate_Vector) { @@ -270,7 +270,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : vec2<f32> = -(vec2<f32>(50.0, 60.0));")); + HasSubstr("let x_1 : vec2<f32> = -(vec2<f32>(50.0f, 60.0f));")); } struct BinaryData { @@ -394,8 +394,8 @@ SpvBinaryArithTest, ::testing::Values( // Scalar float - BinaryData{"float", "float_50", "OpFAdd", "float_60", "f32", "50.0", - "+", "60.0"}, // Vector float + BinaryData{"float", "float_50", "OpFAdd", "float_60", "f32", "50.0f", + "+", "60.0f"}, // Vector float BinaryData{"v2float", "v2float_50_60", "OpFAdd", "v2float_60_50", "vec2<f32>", AstFor("v2float_50_60"), "+", AstFor("v2float_60_50")})); @@ -441,8 +441,8 @@ SpvBinaryArithTest, ::testing::Values( // Scalar float - BinaryData{"float", "float_50", "OpFSub", "float_60", "f32", "50.0", - "-", "60.0"}, // Vector float + BinaryData{"float", "float_50", "OpFSub", "float_60", "f32", "50.0f", + "-", "60.0f"}, // Vector float BinaryData{"v2float", "v2float_50_60", "OpFSub", "v2float_60_50", "vec2<f32>", AstFor("v2float_50_60"), "-", AstFor("v2float_60_50")})); @@ -488,8 +488,8 @@ SpvBinaryArithTest, ::testing::Values( // Scalar float - BinaryData{"float", "float_50", "OpFMul", "float_60", "f32", "50.0", - "*", "60.0"}, // Vector float + BinaryData{"float", "float_50", "OpFMul", "float_60", "f32", "50.0f", + "*", "60.0f"}, // Vector float BinaryData{"v2float", "v2float_50_60", "OpFMul", "v2float_60_50", "vec2<f32>", AstFor("v2float_50_60"), "*", AstFor("v2float_60_50")})); @@ -576,8 +576,8 @@ SpvBinaryArithTest, ::testing::Values( // Scalar float - BinaryData{"float", "float_50", "OpFDiv", "float_60", "f32", "50.0", - "/", "60.0"}, // Vector float + BinaryData{"float", "float_50", "OpFDiv", "float_60", "f32", "50.0f", + "/", "60.0f"}, // Vector float BinaryData{"v2float", "v2float_50_60", "OpFDiv", "v2float_60_50", "vec2<f32>", AstFor("v2float_50_60"), "/", AstFor("v2float_60_50")})); @@ -667,8 +667,8 @@ SpvBinaryArithTest, ::testing::Values( // Scalar float - BinaryData{"float", "float_50", "OpFRem", "float_60", "f32", "50.0", - "%", "60.0"}, // Vector float + BinaryData{"float", "float_50", "OpFRem", "float_60", "f32", "50.0f", + "%", "60.0f"}, // Vector float BinaryData{"v2float", "v2float_50_60", "OpFRem", "v2float_60_50", "vec2<f32>", AstFor("v2float_50_60"), "%", AstFor("v2float_60_50")})); @@ -687,7 +687,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : f32 = (50.0 - (60.0 * floor((50.0 / 60.0))));")); + HasSubstr("let x_1 : f32 = (50.0f - (60.0f * floor((50.0f / 60.0f))));")); } TEST_F(SpvBinaryArithTestBasic, FMod_Vector) { @@ -706,7 +706,7 @@ EXPECT_THAT( test::ToString(p->program(), ast_body), HasSubstr( - R"(let x_1 : vec2<f32> = (vec2<f32>(50.0, 60.0) - (vec2<f32>(60.0, 50.0) * floor((vec2<f32>(50.0, 60.0) / vec2<f32>(60.0, 50.0)))));)")); + R"(let x_1 : vec2<f32> = (vec2<f32>(50.0f, 60.0f) - (vec2<f32>(60.0f, 50.0f) * floor((vec2<f32>(50.0f, 60.0f) / vec2<f32>(60.0f, 50.0f)))));)")); } TEST_F(SpvBinaryArithTestBasic, VectorTimesScalar) {
diff --git a/src/tint/reader/spirv/function_composite_test.cc b/src/tint/reader/spirv/function_composite_test.cc index 2e15743..2b26d14 100644 --- a/src/tint/reader/spirv/function_composite_test.cc +++ b/src/tint/reader/spirv/function_composite_test.cc
@@ -98,7 +98,7 @@ EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(let x_1 : vec2<u32> = vec2<u32>(10u, 20u); let x_2 : vec2<i32> = vec2<i32>(30i, 40i); -let x_3 : vec2<f32> = vec2<f32>(50.0, 60.0); +let x_3 : vec2<f32> = vec2<f32>(50.0f, 60.0f); )")); } @@ -117,9 +117,9 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : mat3x2<f32> = mat3x2<f32>(" - "vec2<f32>(50.0, 60.0), " - "vec2<f32>(60.0, 50.0), " - "vec2<f32>(70.0, 70.0));")); + "vec2<f32>(50.0f, 60.0f), " + "vec2<f32>(60.0f, 50.0f), " + "vec2<f32>(70.0f, 70.0f));")); } TEST_F(SpvParserTest_Composite_Construct, Array) { @@ -153,7 +153,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : S = S(vec2<f32>(50.0, 60.0), 5u, 30i);")); + HasSubstr("let x_1 : S = S(vec2<f32>(50.0f, 60.0f), 5u, 30i);")); } TEST_F(SpvParserTest_Composite_Construct, ConstantComposite_Struct_NoDeduplication) { @@ -201,7 +201,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : f32 = vec2<f32>(50.0, 60.0).y;")); + HasSubstr("let x_1 : f32 = vec2<f32>(50.0f, 60.0f).y;")); } TEST_F(SpvParserTest_CompositeExtract, Vector_IndexTooBigError) { @@ -448,8 +448,8 @@ auto ast_body = fe.ast_body(); auto got = test::ToString(p->program(), ast_body); const auto* expected = - R"(var x_1_1 : vec2<f32> = vec2<f32>(50.0, 60.0); -x_1_1.y = 70.0; + R"(var x_1_1 : vec2<f32> = vec2<f32>(50.0f, 60.0f); +x_1_1.y = 70.0f; let x_1 : vec2<f32> = x_1_1; return; )"; @@ -492,7 +492,7 @@ auto ast_body = fe.ast_body(); auto body_str = test::ToString(p->program(), ast_body); EXPECT_THAT(body_str, HasSubstr(R"(var x_2_1 : mat3x2<f32> = x_1; -x_2_1[2u] = vec2<f32>(50.0, 60.0); +x_2_1[2u] = vec2<f32>(50.0f, 60.0f); let x_2 : mat3x2<f32> = x_2_1; )")) << body_str; } @@ -537,7 +537,7 @@ auto ast_body = fe.ast_body(); auto body_str = test::ToString(p->program(), ast_body); EXPECT_THAT(body_str, HasSubstr(R"(var x_2_1 : mat3x2<f32> = x_1; -x_2_1[2u] = vec2<f32>(50.0, 60.0); +x_2_1[2u] = vec2<f32>(50.0f, 60.0f); let x_2 : mat3x2<f32> = x_2_1; return; )")) << body_str; @@ -713,7 +713,7 @@ EXPECT_THAT(body_str, HasSubstr(R"(var x_38 : S_1; let x_1 : S_1 = x_38; var x_2_1 : S_1 = x_1; -x_2_1.field1[2u][0u].y = 70.0; +x_2_1.field1[2u][0u].y = 70.0f; let x_2 : S_1 = x_2_1; )")) << body_str; }
diff --git a/src/tint/reader/spirv/function_conversion_test.cc b/src/tint/reader/spirv/function_conversion_test.cc index e2f10b2..eab0031 100644 --- a/src/tint/reader/spirv/function_conversion_test.cc +++ b/src/tint/reader/spirv/function_conversion_test.cc
@@ -83,7 +83,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : u32 = bitcast<u32>(50.0);")); + HasSubstr("let x_1 : u32 = bitcast<u32>(50.0f);")); } TEST_F(SpvUnaryConversionTest, Bitcast_Vector) {
diff --git a/src/tint/reader/spirv/function_decl_test.cc b/src/tint/reader/spirv/function_decl_test.cc index bced935..8af9da2 100644 --- a/src/tint/reader/spirv/function_decl_test.cc +++ b/src/tint/reader/spirv/function_decl_test.cc
@@ -93,7 +93,7 @@ auto got = test::ToString(p->program()); std::string expect = R"(fn x_200() -> f32 { - return 0.0; + return 0.0f; } )"; EXPECT_THAT(got, HasSubstr(expect));
diff --git a/src/tint/reader/spirv/function_glsl_std_450_test.cc b/src/tint/reader/spirv/function_glsl_std_450_test.cc index 319332a..4836a68 100644 --- a/src/tint/reader/spirv/function_glsl_std_450_test.cc +++ b/src/tint/reader/spirv/function_glsl_std_450_test.cc
@@ -673,7 +673,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); const auto body = test::ToString(p->program(), ast_body); - EXPECT_THAT(body, HasSubstr("let x_1 : f32 = 1.0;")) << body; + EXPECT_THAT(body, HasSubstr("let x_1 : f32 = 1.0f;")) << body; } TEST_F(SpvParserTest, Normalize_Vector2) { @@ -981,7 +981,7 @@ auto ast_body = fe.ast_body(); const auto body = test::ToString(p->program(), ast_body); const auto* expected = - R"(let x_1 : f32 = refract(vec2<f32>(f1, 0.0), vec2<f32>(f2, 0.0), f3).x;)"; + R"(let x_1 : f32 = refract(vec2<f32>(f1, 0.0f), vec2<f32>(f2, 0.0f), f3).x;)"; EXPECT_THAT(body, HasSubstr(expected)) << body; } @@ -1019,7 +1019,7 @@ // The %99 sum only has one use. Ensure it is evaluated only once by // making a let-declaration for it, since it is the normal operand to // the builtin function, and code generation uses it twice. - const auto* expected = R"(let x_1 : f32 = select(-(x_99), x_99, ((f2 * f3) < 0.0));)"; + const auto* expected = R"(let x_1 : f32 = select(-(x_99), x_99, ((f2 * f3) < 0.0f));)"; EXPECT_THAT(body, HasSubstr(expected)) << body; } @@ -1059,7 +1059,7 @@ // The %99 sum only has one use. Ensure it is evaluated only once by // making a let-declaration for it, since it is the normal operand to // the builtin function, and code generation uses it twice. - const auto* expected = R"(let x_1 : f32 = (x_98 - (2.0 * (x_99 * (x_99 * x_98))));)"; + const auto* expected = R"(let x_1 : f32 = (x_98 - (2.0f * (x_99 * (x_99 * x_98))));)"; EXPECT_THAT(body, HasSubstr(expected)) << body; }
diff --git a/src/tint/reader/spirv/function_logical_test.cc b/src/tint/reader/spirv/function_logical_test.cc index ba73d5d..474af2e 100644 --- a/src/tint/reader/spirv/function_logical_test.cc +++ b/src/tint/reader/spirv/function_logical_test.cc
@@ -112,10 +112,10 @@ return "bitcast<vec2<u32>>(vec2<i32>(40i, 30i))"; } if (assembly == "v2float_50_60") { - return "vec2<f32>(50.0, 60.0)"; + return "vec2<f32>(50.0f, 60.0f)"; } if (assembly == "v2float_60_50") { - return "vec2<f32>(60.0, 50.0)"; + return "vec2<f32>(60.0f, 50.0f)"; } return "bad case"; } @@ -219,7 +219,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdEqual, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdEqual", "float_60", - "bool", "50.0", "==", "60.0"}, + "bool", "50.0f", "==", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdEqual", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), @@ -249,7 +249,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdNotEqual, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdNotEqual", - "float_60", "bool", "50.0", "!=", "60.0"}, + "float_60", "bool", "50.0f", "!=", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdNotEqual", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), @@ -258,7 +258,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdLessThan, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdLessThan", - "float_60", "bool", "50.0", "<", "60.0"}, + "float_60", "bool", "50.0f", "<", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdLessThan", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), "<", @@ -267,7 +267,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdLessThanEqual, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdLessThanEqual", - "float_60", "bool", "50.0", "<=", "60.0"}, + "float_60", "bool", "50.0f", "<=", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdLessThanEqual", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), @@ -276,7 +276,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdGreaterThan, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdGreaterThan", - "float_60", "bool", "50.0", ">", "60.0"}, + "float_60", "bool", "50.0f", ">", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdGreaterThan", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), ">", @@ -285,7 +285,7 @@ INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdGreaterThanEqual, SpvBinaryLogicalTest, ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdGreaterThanEqual", - "float_60", "bool", "50.0", ">=", "60.0"}, + "float_60", "bool", "50.0f", ">=", "60.0f"}, BinaryData{"v2bool", "v2float_50_60", "OpFOrdGreaterThanEqual", "v2float_60_50", "vec2<bool>", AstFor("v2float_50_60"), @@ -515,7 +515,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 != 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f != 60.0f));")); } TEST_F(SpvFUnordTest, FUnordEqual_Vector) { @@ -533,7 +533,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = " - "!((vec2<f32>(50.0, 60.0) != vec2<f32>(60.0, 50.0)));")); + "!((vec2<f32>(50.0f, 60.0f) != vec2<f32>(60.0f, 50.0f)));")); } TEST_F(SpvFUnordTest, FUnordNotEqual_Scalar) { @@ -550,7 +550,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 == 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f == 60.0f));")); } TEST_F(SpvFUnordTest, FUnordNotEqual_Vector) { @@ -568,7 +568,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = " - "!((vec2<f32>(50.0, 60.0) == vec2<f32>(60.0, 50.0)));")); + "!((vec2<f32>(50.0f, 60.0f) == vec2<f32>(60.0f, 50.0f)));")); } TEST_F(SpvFUnordTest, FUnordLessThan_Scalar) { @@ -585,7 +585,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 >= 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f >= 60.0f));")); } TEST_F(SpvFUnordTest, FUnordLessThan_Vector) { @@ -603,7 +603,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = " - "!((vec2<f32>(50.0, 60.0) >= vec2<f32>(60.0, 50.0)));")); + "!((vec2<f32>(50.0f, 60.0f) >= vec2<f32>(60.0f, 50.0f)));")); } TEST_F(SpvFUnordTest, FUnordLessThanEqual_Scalar) { @@ -620,7 +620,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 > 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f > 60.0f));")); } TEST_F(SpvFUnordTest, FUnordLessThanEqual_Vector) { @@ -638,7 +638,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = " - "!((vec2<f32>(50.0, 60.0) > vec2<f32>(60.0, 50.0)));")); + "!((vec2<f32>(50.0f, 60.0f) > vec2<f32>(60.0f, 50.0f)));")); } TEST_F(SpvFUnordTest, FUnordGreaterThan_Scalar) { @@ -655,7 +655,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 <= 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f <= 60.0f));")); } TEST_F(SpvFUnordTest, FUnordGreaterThan_Vector) { @@ -673,7 +673,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = " - "!((vec2<f32>(50.0, 60.0) <= vec2<f32>(60.0, 50.0)));")); + "!((vec2<f32>(50.0f, 60.0f) <= vec2<f32>(60.0f, 50.0f)));")); } TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Scalar) { @@ -690,7 +690,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : bool = !((50.0 < 60.0));")); + HasSubstr("let x_1 : bool = !((50.0f < 60.0f));")); } TEST_F(SpvFUnordTest, FUnordGreaterThanEqual_Vector) { @@ -708,7 +708,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : vec2<bool> = !((" - "vec2<f32>(50.0, 60.0) < vec2<f32>(60.0, 50.0)" + "vec2<f32>(50.0f, 60.0f) < vec2<f32>(60.0f, 50.0f)" "));")); } @@ -762,7 +762,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : f32 = select(60.0, 50.0, true);")); + HasSubstr("let x_1 : f32 = select(60.0f, 50.0f, true);")); } TEST_F(SpvLogicalTest, Select_BoolCond_VectorParams) { @@ -859,7 +859,8 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : bool = isNan(50.0);")); + EXPECT_THAT(test::ToString(p->program(), ast_body), + HasSubstr("let x_1 : bool = isNan(50.0f);")); } TEST_F(SpvLogicalTest, IsNan_Vector) { @@ -876,7 +877,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : vec2<bool> = isNan(vec2<f32>(50.0, 60.0));")); + HasSubstr("let x_1 : vec2<bool> = isNan(vec2<f32>(50.0f, 60.0f));")); } TEST_F(SpvLogicalTest, IsInf_Scalar) { @@ -892,7 +893,8 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_1 : bool = isInf(50.0);")); + EXPECT_THAT(test::ToString(p->program(), ast_body), + HasSubstr("let x_1 : bool = isInf(50.0f);")); } TEST_F(SpvLogicalTest, IsInf_Vector) { @@ -909,7 +911,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_1 : vec2<bool> = isInf(vec2<f32>(50.0, 60.0));")); + HasSubstr("let x_1 : vec2<bool> = isInf(vec2<f32>(50.0f, 60.0f));")); } // TODO(dneto): Kernel-guarded instructions.
diff --git a/src/tint/reader/spirv/function_memory_test.cc b/src/tint/reader/spirv/function_memory_test.cc index 58cceda..ed39e21 100644 --- a/src/tint/reader/spirv/function_memory_test.cc +++ b/src/tint/reader/spirv/function_memory_test.cc
@@ -133,8 +133,9 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(x_1 = 42.0; -x_1 = 0.0; + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(x_1 = 42.0f; +x_1 = 0.0f; +return; )")); } @@ -497,7 +498,7 @@ EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("myvar[2u] = vec4<f32>(42.0, 42.0, 42.0, 42.0);")); + HasSubstr("myvar[2u] = vec4<f32>(42.0f, 42.0f, 42.0f, 42.0f);")); } TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_Array) { @@ -529,7 +530,7 @@ EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("myvar[2u] = vec4<f32>(42.0, 42.0, 42.0, 42.0);")); + HasSubstr("myvar[2u] = vec4<f32>(42.0f, 42.0f, 42.0f, 42.0f);")); } TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_Struct) { @@ -559,7 +560,7 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar.age = 42.0;")); + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar.age = 42.0f;")); } TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_Struct_DifferOnlyMemberName) { @@ -601,8 +602,9 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(myvar.age = 42.0; -myvar2.ancientness = 420.0; + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(myvar.age = 42.0f; +myvar2.ancientness = 420.0f; +return; )")); } @@ -706,7 +708,7 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar.age[2u] = 42.0;")); + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar.age[2u] = 42.0f;")); } TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_Compound_Matrix_Vector) { @@ -737,7 +739,7 @@ auto fe = p->function_emitter(100); EXPECT_TRUE(fe.EmitBody()); auto ast_body = fe.ast_body(); - EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar[2u].w = 42.0;")); + EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("myvar[2u].w = 42.0f;")); } TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_InvalidPointeeType) {
diff --git a/src/tint/reader/spirv/function_misc_test.cc b/src/tint/reader/spirv/function_misc_test.cc index 9d40ffc..3f9c398 100644 --- a/src/tint/reader/spirv/function_misc_test.cc +++ b/src/tint/reader/spirv/function_misc_test.cc
@@ -75,7 +75,8 @@ EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(let x_11 : bool = false; let x_12 : u32 = 0u; let x_13 : i32 = 0i; -let x_14 : f32 = 0.0; +let x_14 : f32 = 0.0f; +return; )")); } @@ -133,7 +134,8 @@ EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(let x_11 : bool = false; let x_12 : u32 = 0u; let x_13 : i32 = 0i; -let x_14 : f32 = 0.0; +let x_14 : f32 = 0.0f; +return; )")); } @@ -224,7 +226,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("let x_11 : S = S(false, 0u, 0i, 0.0);")); + HasSubstr("let x_11 : S = S(false, 0u, 0i, 0.0f);")); } TEST_F(SpvParserTestMiscInstruction, OpNop) { @@ -330,7 +332,7 @@ EXPECT_TRUE(fe.EmitBody()) << p->error(); auto ast_body = fe.ast_body(); const auto got = test::ToString(p->program(), ast_body); - EXPECT_THAT(got, HasSubstr("let x_81 : f32 = (0.0 * 42.0);")); + EXPECT_THAT(got, HasSubstr("let x_81 : f32 = (0.0f * 42.0f);")); } // TODO(dneto): OpSizeof : requires Kernel (OpenCL)
diff --git a/src/tint/reader/spirv/function_var_test.cc b/src/tint/reader/spirv/function_var_test.cc index c986af8..6371234 100644 --- a/src/tint/reader/spirv/function_var_test.cc +++ b/src/tint/reader/spirv/function_var_test.cc
@@ -184,7 +184,7 @@ var b : bool = false; var c : i32 = -1i; var d : u32 = 1u; -var e : f32 = 1.5; +var e : f32 = 1.5f; )")); } @@ -212,7 +212,7 @@ EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr(R"(var a : bool = false; var b : i32 = 0i; var c : u32 = 0u; -var d : f32 = 0.0; +var d : f32 = 0.0f; )")); } @@ -234,7 +234,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("var x_200 : vec2<f32> = vec2<f32>(1.5, 2.0);")); + HasSubstr("var x_200 : vec2<f32> = vec2<f32>(1.5f, 2.0f);")); } TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_MatrixInitializer) { @@ -261,9 +261,9 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("var x_200 : mat3x2<f32> = mat3x2<f32>(" - "vec2<f32>(1.5, 2.0), " - "vec2<f32>(2.0, 3.0), " - "vec2<f32>(3.0, 4.0));")); + "vec2<f32>(1.5f, 2.0f), " + "vec2<f32>(2.0f, 3.0f), " + "vec2<f32>(3.0f, 4.0f));")); } TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ArrayInitializer) { @@ -382,7 +382,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("var x_200 : S = S(1u, 1.5, array<u32, 2u>(1u, 2u));")); + HasSubstr("var x_200 : S = S(1u, 1.5f, array<u32, 2u>(1u, 2u));")); } TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_StructInitializer_Null) { @@ -404,7 +404,7 @@ auto ast_body = fe.ast_body(); EXPECT_THAT(test::ToString(p->program(), ast_body), - HasSubstr("var x_200 : S = S(0u, 0.0, array<u32, 2u>());")); + HasSubstr("var x_200 : S = S(0u, 0.0f, array<u32, 2u>());")); } TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_Decorate_RelaxedPrecision) {
diff --git a/src/tint/reader/spirv/parser_impl_function_decl_test.cc b/src/tint/reader/spirv/parser_impl_function_decl_test.cc index c821c85..fe6b1e0 100644 --- a/src/tint/reader/spirv/parser_impl_function_decl_test.cc +++ b/src/tint/reader/spirv/parser_impl_function_decl_test.cc
@@ -402,7 +402,16 @@ Program program = p->program(); const auto program_ast = test::ToString(program); EXPECT_THAT(program_ast, HasSubstr(R"(fn ret_float() -> f32 { - return 0.0; + return 0.0f; +} + +fn x_100_1() { + return; +} + +@stage(fragment) +fn x_100() { + x_100_1(); } )")) << program_ast; }
diff --git a/src/tint/reader/spirv/parser_impl_handle_test.cc b/src/tint/reader/spirv/parser_impl_handle_test.cc index 0af3cc5..84f3dcb 100644 --- a/src/tint/reader/spirv/parser_impl_handle_test.cc +++ b/src/tint/reader/spirv/parser_impl_handle_test.cc
@@ -1648,7 +1648,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d;)", - "textureGatherCompare(x_20, x_10, coords12, 0.200000003)"}, + "textureGatherCompare(x_20, x_10, coords12, 0.200000003f)"}, // OpImageDrefGather 2DDepth ConstOffset signed ImageAccessCase{"%float 2D 1 0 0 1 Unknown", "%result = OpImageDrefGather " @@ -1656,7 +1656,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d;)", - "textureGatherCompare(x_20, x_10, coords12, 0.200000003, " + "textureGatherCompare(x_20, x_10, coords12, 0.200000003f, " "vec2<i32>(3i, 4i))"}, // OpImageDrefGather 2DDepth ConstOffset unsigned ImageAccessCase{"%float 2D 1 0 0 1 Unknown", @@ -1666,7 +1666,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d;)", - "textureGatherCompare(x_20, x_10, coords12, 0.200000003, " + "textureGatherCompare(x_20, x_10, coords12, 0.200000003f, " "vec2<i32>(vec2<u32>(3u, 4u)))"}, // OpImageDrefGather 2DDepth Array ImageAccessCase{"%float 2D 1 1 0 1 Unknown", @@ -1676,7 +1676,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", "textureGatherCompare(x_20, x_10, coords123.xy, " - "i32(round(coords123.z)), 0.200000003)"}, + "i32(round(coords123.z)), 0.200000003f)"}, // OpImageDrefGather 2DDepth Array ConstOffset signed ImageAccessCase{"%float 2D 1 1 0 1 Unknown", "%result = OpImageDrefGather " @@ -1685,7 +1685,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", "textureGatherCompare(x_20, x_10, coords123.xy, " - "i32(round(coords123.z)), 0.200000003, vec2<i32>(3i, 4i))"}, + "i32(round(coords123.z)), 0.200000003f, vec2<i32>(3i, 4i))"}, // OpImageDrefGather 2DDepth Array ConstOffset unsigned ImageAccessCase{"%float 2D 1 1 0 1 Unknown", "%result = OpImageDrefGather " @@ -1695,7 +1695,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", "textureGatherCompare(x_20, x_10, coords123.xy, " - "i32(round(coords123.z)), 0.200000003, " + "i32(round(coords123.z)), 0.200000003f, " "vec2<i32>(vec2<u32>(3u, 4u)))"}, // OpImageDrefGather DepthCube ImageAccessCase{"%float Cube 1 0 0 1 Unknown", @@ -1704,7 +1704,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_cube;)", - "textureGatherCompare(x_20, x_10, coords123, 0.200000003)"}, + "textureGatherCompare(x_20, x_10, coords123, 0.200000003f)"}, // OpImageDrefGather DepthCube Array ImageAccessCase{"%float Cube 1 1 0 1 Unknown", "%result = OpImageDrefGather " @@ -1713,7 +1713,7 @@ @group(2) @binding(1) var x_20 : texture_depth_cube_array;)", "textureGatherCompare(x_20, x_10, coords1234.xyz, " - "i32(round(coords1234.w)), 0.200000003)"}})); + "i32(round(coords1234.w)), 0.200000003f)"}})); INSTANTIATE_TEST_SUITE_P( ImageSampleImplicitLod, @@ -1764,7 +1764,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - "textureSampleBias(x_20, x_10, coords12, 7.0)"}, + "textureSampleBias(x_20, x_10, coords12, 7.0f)"}, // OpImageSampleImplicitLod arrayed with Bias ImageAccessCase{ @@ -1774,7 +1774,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d_array<f32>;)", - R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0))"}, + R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0f))"}, // OpImageSampleImplicitLod with Bias and signed ConstOffset ImageAccessCase{"%float 2D 0 0 0 1 Unknown", @@ -1784,7 +1784,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleBias(x_20, x_10, coords12, 7.0, vec2<i32>(3i, 4i))"}, + R"(textureSampleBias(x_20, x_10, coords12, 7.0f, vec2<i32>(3i, 4i))"}, // OpImageSampleImplicitLod with Bias and unsigned ConstOffset // Convert ConstOffset to signed @@ -1796,7 +1796,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleBias(x_20, x_10, coords12, 7.0, vec2<i32>(vec2<u32>(3u, 4u)))"}, + R"(textureSampleBias(x_20, x_10, coords12, 7.0f, vec2<i32>(vec2<u32>(3u, 4u)))"}, // OpImageSampleImplicitLod arrayed with Bias ImageAccessCase{ "%float 2D 0 1 0 1 Unknown", @@ -1806,7 +1806,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d_array<f32>;)", - R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0, vec2<i32>(3i, 4i))"})); + R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0f, vec2<i32>(3i, 4i))"})); INSTANTIATE_TEST_SUITE_P( // This test shows the use of a sampled image used with both regular @@ -1831,8 +1831,8 @@ @group(0) @binding(1) var x_30 : sampler_comparison; )", R"( - let x_200 : vec4<f32> = vec4<f32>(textureSample(x_20, x_10, coords12), 0.0, 0.0, 0.0); - let x_210 : f32 = textureSampleCompare(x_20, x_30, coords12, 0.200000003); + let x_200 : vec4<f32> = vec4<f32>(textureSample(x_20, x_10, coords12), 0.0f, 0.0f, 0.0f); + let x_210 : f32 = textureSampleCompare(x_20, x_30, coords12, 0.200000003f); )"})); INSTANTIATE_TEST_SUITE_P( @@ -1847,7 +1847,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompare(x_20, x_10, coords12, 0.200000003))"}, + R"(textureSampleCompare(x_20, x_10, coords12, 0.200000003f))"}, // ImageSampleDrefImplicitLod - arrayed ImageAccessCase{ "%float 2D 0 1 0 1 Unknown", @@ -1856,7 +1856,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", - R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003))"}, + R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003f))"}, // ImageSampleDrefImplicitLod with ConstOffset ImageAccessCase{ "%float 2D 0 0 0 1 Unknown", @@ -1866,7 +1866,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompare(x_20, x_10, coords12, 0.200000003, vec2<i32>(3i, 4i)))"}, + R"(textureSampleCompare(x_20, x_10, coords12, 0.200000003f, vec2<i32>(3i, 4i)))"}, // ImageSampleDrefImplicitLod arrayed with ConstOffset ImageAccessCase{ "%float 2D 0 1 0 1 Unknown", @@ -1875,7 +1875,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", - R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003, vec2<i32>(3i, 4i)))"})); + R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003f, vec2<i32>(3i, 4i)))"})); INSTANTIATE_TEST_SUITE_P( ImageSampleDrefExplicitLod, @@ -1891,7 +1891,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompareLevel(x_20, x_10, coords12, 0.200000003))"}, + R"(textureSampleCompareLevel(x_20, x_10, coords12, 0.200000003f))"}, // 2D array ImageAccessCase{ "%float 2D 1 1 0 1 Unknown", @@ -1900,7 +1900,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", - R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003))"}, + R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003f))"}, // 2D, ConstOffset ImageAccessCase{ "%float 2D 1 0 0 1 Unknown", @@ -1911,7 +1911,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompareLevel(x_20, x_10, coords12, 0.200000003, vec2<i32>(3i, 4i)))"}, + R"(textureSampleCompareLevel(x_20, x_10, coords12, 0.200000003f, vec2<i32>(3i, 4i)))"}, // 2D array, ConstOffset ImageAccessCase{ "%float 2D 1 1 0 1 Unknown", @@ -1921,7 +1921,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_2d_array;)", - R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003, vec2<i32>(3i, 4i)))"}, + R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003f, vec2<i32>(3i, 4i)))"}, // Cube ImageAccessCase{"%float Cube 1 0 0 1 Unknown", "%result = OpImageSampleDrefExplicitLod " @@ -1929,7 +1929,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_cube;)", - R"(textureSampleCompareLevel(x_20, x_10, coords123, 0.200000003))"}, + R"(textureSampleCompareLevel(x_20, x_10, coords123, 0.200000003f))"}, // Cube array ImageAccessCase{ "%float Cube 1 1 0 1 Unknown", @@ -1938,7 +1938,7 @@ R"(@group(0) @binding(0) var x_10 : sampler_comparison; @group(2) @binding(1) var x_20 : texture_depth_cube_array;)", - R"(textureSampleCompareLevel(x_20, x_10, coords1234.xyz, i32(round(coords1234.w)), 0.200000003))"})); + R"(textureSampleCompareLevel(x_20, x_10, coords1234.xyz, i32(round(coords1234.w)), 0.200000003f))"})); INSTANTIATE_TEST_SUITE_P( ImageSampleExplicitLod_UsingLod, @@ -1952,7 +1952,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleLevel(x_20, x_10, coords12, 0.0))"}, + R"(textureSampleLevel(x_20, x_10, coords12, 0.0f))"}, // OpImageSampleExplicitLod arrayed - using Lod ImageAccessCase{ @@ -1962,7 +1962,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d_array<f32>;)", - R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0))"}, + R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0f))"}, // OpImageSampleExplicitLod - using Lod and ConstOffset ImageAccessCase{"%float 2D 0 0 0 1 Unknown", @@ -1972,7 +1972,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleLevel(x_20, x_10, coords12, 0.0, vec2<i32>(3i, 4i)))"}, + R"(textureSampleLevel(x_20, x_10, coords12, 0.0f, vec2<i32>(3i, 4i)))"}, // OpImageSampleExplicitLod - using Lod and unsigned ConstOffset // Convert the ConstOffset operand to signed @@ -1984,7 +1984,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleLevel(x_20, x_10, coords12, 0.0, vec2<i32>(vec2<u32>(3u, 4u)))"}, + R"(textureSampleLevel(x_20, x_10, coords12, 0.0f, vec2<i32>(vec2<u32>(3u, 4u)))"}, // OpImageSampleExplicitLod arrayed - using Lod and ConstOffset ImageAccessCase{ @@ -1995,7 +1995,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d_array<f32>;)", - R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0, vec2<i32>(3i, 4i)))"})); + R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0f, vec2<i32>(3i, 4i)))"})); INSTANTIATE_TEST_SUITE_P( ImageSampleExplicitLod_UsingGrad, @@ -2092,7 +2092,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(vec4<f32>(textureSampleLevel(x_20, x_10, vf12, i32(f1)), 0.0, 0.0, 0.0))"}})); + R"(vec4<f32>(textureSampleLevel(x_20, x_10, vf12, i32(f1)), 0.0f, 0.0f, 0.0f))"}})); ///// // Projection sampling @@ -2176,7 +2176,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0))"}, + R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0f))"}, // OpImageSampleProjImplicitLod with Bias and signed ConstOffset ImageAccessCase{ @@ -2187,7 +2187,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0, vec2<i32>(3i, 4i)))"}, + R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0f, vec2<i32>(3i, 4i)))"}, // OpImageSampleProjImplicitLod with Bias and unsigned ConstOffset // Convert ConstOffset to signed @@ -2199,7 +2199,7 @@ R"(@group(0) @binding(0) var x_10 : sampler; @group(2) @binding(1) var x_20 : texture_2d<f32>;)", - R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0, vec2<i32>(vec2<u32>(3u, 4u))))"})); + R"(textureSampleBias(x_20, x_10, (coords123.xy / coords123.z), 7.0f, vec2<i32>(vec2<u32>(3u, 4u))))"})); INSTANTIATE_TEST_SUITE_P( ImageSampleProjExplicitLod_Lod, @@ -2266,7 +2266,7 @@ // Sampling the depth texture yields an f32, but the // SPIR-V operation yiedls vec4<f32>, so fill out the // remaining components with 0. - R"(vec4<f32>(textureSample(x_20, x_10, (coords123.xy / coords123.z)), 0.0, 0.0, 0.0))"})); + R"(vec4<f32>(textureSample(x_20, x_10, (coords123.xy / coords123.z)), 0.0f, 0.0f, 0.0f))"})); INSTANTIATE_TEST_SUITE_P( ImageSampleProjDrefImplicitLod, @@ -2311,7 +2311,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompare(x_20, x_10, (coords123.xy / coords123.z), 0.200000003, 0.0))"}, + R"(textureSampleCompare(x_20, x_10, (coords123.xy / coords123.z), 0.200000003f, 0.0f))"}, // OpImageSampleProjDrefImplicitLod 2D depth-texture, Lod ConstOffset ImageAccessCase{ @@ -2323,7 +2323,7 @@ @group(2) @binding(1) var x_20 : texture_depth_2d; )", - R"(textureSampleCompareLevel(x_20, x_10, (coords123.xy / coords123.z), 0.200000003, 0.0, vec2<i32>(3i, 4i)))"})); + R"(textureSampleCompareLevel(x_20, x_10, (coords123.xy / coords123.z), 0.200000003f, 0.0f, vec2<i32>(3i, 4i)))"})); ///// // End projection sampling @@ -2416,15 +2416,15 @@ // Source 1 component {"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vi12 %f1", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<r32float, write>;)", - "textureStore(x_20, vi12, vec4<f32>(f1, 0.0, 0.0, 0.0));"}, + "textureStore(x_20, vi12, vec4<f32>(f1, 0.0f, 0.0f, 0.0f));"}, // Source 2 component, dest 1 component {"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vi12 %vf12", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<r32float, write>;)", - "textureStore(x_20, vi12, vec4<f32>(vf12, 0.0, 0.0));"}, + "textureStore(x_20, vi12, vec4<f32>(vf12, 0.0f, 0.0f));"}, // Source 3 component, dest 1 component {"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vi12 %vf123", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<r32float, write>;)", - "textureStore(x_20, vi12, vec4<f32>(vf123, 0.0));"}, + "textureStore(x_20, vi12, vec4<f32>(vf123, 0.0f));"}, // Source 4 component, dest 1 component {"%float 2D 0 0 0 2 R32f", "OpImageWrite %im %vi12 %vf1234", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<r32float, write>;)", @@ -2432,11 +2432,11 @@ // Source 2 component, dest 2 component {"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vi12 %vf12", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<rg32float, write>;)", - "textureStore(x_20, vi12, vec4<f32>(vf12, 0.0, 0.0));"}, + "textureStore(x_20, vi12, vec4<f32>(vf12, 0.0f, 0.0f));"}, // Source 3 component, dest 2 component {"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vi12 %vf123", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<rg32float, write>;)", - "textureStore(x_20, vi12, vec4<f32>(vf123, 0.0));"}, + "textureStore(x_20, vi12, vec4<f32>(vf123, 0.0f));"}, // Source 4 component, dest 2 component {"%float 2D 0 0 0 2 Rg32f", "OpImageWrite %im %vi12 %vf1234", R"(@group(2) @binding(1) var x_20 : texture_storage_2d<rg32float, write>;)", @@ -2583,11 +2583,11 @@ // Level of detail is injected for depth texture {"%float 2D 1 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vi12", R"(@group(2) @binding(1) var x_20 : texture_depth_2d;)", - R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 0i), 0.0, 0.0, 0.0);)"}, + R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 0i), 0.0f, 0.0f, 0.0f);)"}, // OpImageFetch with extra params, on depth texture {"%float 2D 1 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vi12 Lod %int_3", R"(@group(2) @binding(1) var x_20 : texture_depth_2d;)", - R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 3i), 0.0, 0.0, 0.0);)"}})); + R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 3i), 0.0f, 0.0f, 0.0f);)"}})); INSTANTIATE_TEST_SUITE_P( ImageFetch_Depth, @@ -2600,7 +2600,7 @@ // ImageFetch on depth image. {"%float 2D 1 0 0 1 Unknown", "%99 = OpImageFetch %v4float %im %vi12 ", R"(@group(2) @binding(1) var x_20 : texture_depth_2d;)", - R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 0i), 0.0, 0.0, 0.0);)"}})); + R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, 0i), 0.0f, 0.0f, 0.0f);)"}})); INSTANTIATE_TEST_SUITE_P( ImageFetch_DepthMultisampled, @@ -2613,7 +2613,7 @@ // ImageFetch on multisampled depth image. {"%float 2D 1 0 1 1 Unknown", "%99 = OpImageFetch %v4float %im %vi12 Sample %i1", R"(@group(2) @binding(1) var x_20 : texture_depth_multisampled_2d;)", - R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, i1), 0.0, 0.0, 0.0);)"}})); + R"(let x_99 : vec4<f32> = vec4<f32>(textureLoad(x_20, vi12, i1), 0.0f, 0.0f, 0.0f);)"}})); INSTANTIATE_TEST_SUITE_P(ImageFetch_Multisampled, SpvParserHandleTest_ImageAccessTest,
diff --git a/src/tint/reader/spirv/parser_impl_module_var_test.cc b/src/tint/reader/spirv/parser_impl_module_var_test.cc index 8ef704e..622d383 100644 --- a/src/tint/reader/spirv/parser_impl_module_var_test.cc +++ b/src/tint/reader/spirv/parser_impl_module_var_test.cc
@@ -408,7 +408,7 @@ EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("gl_Position.y = 0.0;")) << module_str; + EXPECT_THAT(module_str, HasSubstr("gl_Position.y = 0.0f;")) << module_str; } TEST_F(SpvModuleScopeVarParserTest, BuiltinPosition_StorePositionMember_TwoAccessChain) { @@ -430,7 +430,7 @@ EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("gl_Position.y = 0.0;")) << module_str; + EXPECT_THAT(module_str, HasSubstr("gl_Position.y = 0.0f;")) << module_str; } TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_Write1_IsErased) { @@ -510,7 +510,7 @@ var<private> gl_Position : vec4<f32>; fn main_1() { - x_900 = 1.0; + x_900 = 1.0f; return; } @@ -681,7 +681,7 @@ var<private> x_900 : f32; fn main_1() { - x_900 = 1.0; + x_900 = 1.0f; return; } @@ -889,7 +889,7 @@ var<private> x_4 : u32 = 1u; -var<private> x_5 : f32 = 1.5; +var<private> x_5 : f32 = 1.5f; )")); } @@ -914,7 +914,7 @@ var<private> x_3 : u32 = 0u; -var<private> x_4 : f32 = 0.0; +var<private> x_4 : f32 = 0.0f; )")); } @@ -939,7 +939,7 @@ var<private> x_3 : u32 = 0u; -var<private> x_4 : f32 = 0.0; +var<private> x_4 : f32 = 0.0f; )")); // This example module emits ok, but is not valid SPIR-V in the first place. @@ -956,7 +956,7 @@ ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : vec2<f32> = vec2<f32>(1.5, 2.0);")); + EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : vec2<f32> = vec2<f32>(1.5f, 2.0f);")); } TEST_F(SpvModuleScopeVarParserTest, VectorBoolNullInitializer) { @@ -1083,9 +1083,9 @@ EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : mat3x2<f32> = mat3x2<f32>(" - "vec2<f32>(1.5, 2.0), " - "vec2<f32>(2.0, 3.0), " - "vec2<f32>(3.0, 4.0));")); + "vec2<f32>(1.5f, 2.0f), " + "vec2<f32>(2.0f, 3.0f), " + "vec2<f32>(3.0f, 4.0f));")); } TEST_F(SpvModuleScopeVarParserTest, MatrixNullInitializer) { @@ -1168,7 +1168,7 @@ EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); EXPECT_THAT(module_str, - HasSubstr("var<private> x_200 : S = S(1u, 1.5, array<u32, 2u>(1u, 2u));")) + HasSubstr("var<private> x_200 : S = S(1u, 1.5f, array<u32, 2u>(1u, 2u));")) << module_str; } @@ -1181,7 +1181,7 @@ ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error(); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : S = S(0u, 0.0, array<u32, 2u>());")) + EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : S = S(0u, 0.0f, array<u32, 2u>());")) << module_str; } @@ -1195,7 +1195,7 @@ EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : S = S(0u, 0.0, array<u32, 2u>());")) + EXPECT_THAT(module_str, HasSubstr("var<private> x_200 : S = S(0u, 0.0f, array<u32, 2u>());")) << module_str; // This example module emits ok, but is not valid SPIR-V in the first place. @@ -1565,7 +1565,7 @@ ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error(); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("@id(12) override myconst : f32 = 2.5;")) << module_str; + EXPECT_THAT(module_str, HasSubstr("@id(12) override myconst : f32 = 2.5f;")) << module_str; } TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_F32_WithoutSpecId) { @@ -1580,7 +1580,7 @@ ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error(); EXPECT_TRUE(p->error().empty()); const auto module_str = test::ToString(p->program()); - EXPECT_THAT(module_str, HasSubstr("override myconst : f32 = 2.5;")) << module_str; + EXPECT_THAT(module_str, HasSubstr("override myconst : f32 = 2.5f;")) << module_str; } TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_UsedInFunction) { @@ -3854,7 +3854,7 @@ ASSERT_TRUE(p->Parse()) << p->error() << assembly; EXPECT_TRUE(p->error().empty()); const auto got = test::ToString(p->program()); - const std::string expected = R"(var<private> x_1 : f32 = 0.0; + const std::string expected = R"(var<private> x_1 : f32 = 0.0f; fn main_1() { return; @@ -3957,7 +3957,7 @@ const auto got = test::ToString(p->program()); const std::string expected = - R"(var<private> gl_Position : vec4<f32> = vec4<f32>(1.0, 2.0, 3.0, 4.0); + R"(var<private> gl_Position : vec4<f32> = vec4<f32>(1.0f, 2.0f, 3.0f, 4.0f); fn main_1() { return;
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc index 9323b23..d9ef10e 100644 --- a/src/tint/resolver/array_accessor_test.cc +++ b/src/tint/resolver/array_accessor_test.cc
@@ -156,19 +156,36 @@ EXPECT_TRUE(ref->StoreType()->Is<sem::F32>()); } -TEST_F(ResolverIndexAccessorTest, Array) { - auto* idx = Expr(2_i); +TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) { Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate); - - auto* acc = IndexAccessor("my_var", idx); + auto* acc = IndexAccessor("my_var", 2_i); WrapInFunction(acc); - EXPECT_TRUE(r()->Resolve()) << r()->error(); - ASSERT_NE(TypeOf(acc), nullptr); - ASSERT_TRUE(TypeOf(acc)->Is<sem::Reference>()); - auto* ref = TypeOf(acc)->As<sem::Reference>(); + ASSERT_NE(ref, nullptr); + EXPECT_TRUE(ref->StoreType()->Is<sem::F32>()); +} + +TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) { + Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate); + auto* acc = IndexAccessor("my_var", 2_u); + WrapInFunction(acc); + EXPECT_TRUE(r()->Resolve()) << r()->error(); + ASSERT_NE(TypeOf(acc), nullptr); + auto* ref = TypeOf(acc)->As<sem::Reference>(); + ASSERT_NE(ref, nullptr); + EXPECT_TRUE(ref->StoreType()->Is<sem::F32>()); +} + +TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) { + Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate); + auto* acc = IndexAccessor("my_var", 2_a); + WrapInFunction(acc); + EXPECT_TRUE(r()->Resolve()) << r()->error(); + ASSERT_NE(TypeOf(acc), nullptr); + auto* ref = TypeOf(acc)->As<sem::Reference>(); + ASSERT_NE(ref, nullptr); EXPECT_TRUE(ref->StoreType()->Is<sem::F32>()); } @@ -249,7 +266,7 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverIndexAccessorTest, EXpr_Deref_FuncGoodParent) { +TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncGoodParent) { // fn func(p: ptr<function, vec4<f32>>) -> f32 { // let idx: u32 = u32(); // let x: f32 = (*p)[idx]; @@ -265,7 +282,7 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverIndexAccessorTest, EXpr_Deref_FuncBadParent) { +TEST_F(ResolverIndexAccessorTest, Expr_Deref_FuncBadParent) { // fn func(p: ptr<function, vec4<f32>>) -> f32 { // let idx: u32 = u32(); // let x: f32 = *p[idx];
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc index e9fb7bf..64363e3 100644 --- a/src/tint/resolver/assignment_validation_test.cc +++ b/src/tint/resolver/assignment_validation_test.cc
@@ -147,29 +147,33 @@ // var my_var : i32 = 2i; // 1 = my_var; - auto* var = Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2_i)); - WrapInFunction(var, Assign(Expr(Source{{12, 34}}, 1_i), "my_var")); + WrapInFunction(Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(2_i)), // + Assign(Expr(Source{{12, 34}}, 1_i), "my_var")); EXPECT_FALSE(r()->Resolve()); EXPECT_EQ(r()->error(), "12:34 error: cannot assign to value of type 'i32'"); } TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypes_Pass) { - // var a : i32 = 2i; - // a = 2i - auto* var = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i)); - WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2_i)); + // var a : i32 = 1i; + // a = 2i; + // a = 3; + WrapInFunction(Var("a", ty.i32(), ast::StorageClass::kNone, Expr(1_i)), // + Assign("a", 2_i), // + Assign("a", 3_a)); EXPECT_TRUE(r()->Resolve()) << r()->error(); } TEST_F(ResolverAssignmentValidationTest, AssignCompatibleTypesThroughAlias_Pass) { - // alias myint = i32; - // var a : myint = 2i; - // a = 2 - auto* myint = Alias("myint", ty.i32()); - auto* var = Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(2_i)); - WrapInFunction(var, Assign(Source{{12, 34}}, "a", 2_i)); + // alias myint = u32; + // var a : myint = 1u; + // a = 2u; + // a = 3; + auto* myint = Alias("myint", ty.u32()); + WrapInFunction(Var("a", ty.Of(myint), ast::StorageClass::kNone, Expr(1_u)), // + Assign("a", 2_u), // + Assign("a", 3_a)); EXPECT_TRUE(r()->Resolve()) << r()->error(); } @@ -178,9 +182,9 @@ // var a : i32 = 2i; // var b : i32 = 3i; // a = b; - auto* var_a = Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i)); - auto* var_b = Var("b", ty.i32(), ast::StorageClass::kNone, Expr(3_i)); - WrapInFunction(var_a, var_b, Assign(Source{{12, 34}}, "a", "b")); + WrapInFunction(Var("a", ty.i32(), ast::StorageClass::kNone, Expr(2_i)), // + Var("b", ty.i32(), ast::StorageClass::kNone, Expr(3_i)), // + Assign("a", "b")); EXPECT_TRUE(r()->Resolve()) << r()->error(); } @@ -190,14 +194,26 @@ // let b : ptr<function,i32> = &a; // *b = 2i; const auto func = ast::StorageClass::kFunction; - auto* var_a = Var("a", ty.i32(), func, Expr(2_i)); - auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a"))); - WrapInFunction(var_a, var_b, Assign(Source{{12, 34}}, Deref("b"), 2_i)); + WrapInFunction(Var("a", ty.i32(), func, Expr(2_i)), // + Let("b", ty.pointer<i32>(func), AddressOf(Expr("a"))), // + Assign(Deref("b"), 2_i)); EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) { +TEST_F(ResolverAssignmentValidationTest, AssignMaterializedThroughPointer_Pass) { + // var a : i32; + // let b : ptr<function,i32> = &a; + // *b = 2; + const auto func = ast::StorageClass::kFunction; + auto* var_a = Var("a", ty.i32(), func, Expr(2_i)); + auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a"))); + WrapInFunction(var_a, var_b, Assign(Deref("b"), 2_a)); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverAssignmentValidationTest, AssignToLet_Fail) { // { // let a : i32 = 2i; // a = 2i @@ -328,8 +344,12 @@ // fn f() { // _ = 1i; // _ = 2u; - // _ = 3.0; - // _ = vec2<bool>(); + // _ = 3.0f; + // _ = 4; + // _ = 5.0; + // _ = vec2(6); + // _ = vec3(7.0); + // _ = vec4<bool>(); // _ = tex; // _ = smp; // _ = &s; @@ -354,7 +374,11 @@ WrapInFunction(Assign(Phony(), 1_i), // Assign(Phony(), 2_u), // Assign(Phony(), 3_f), // - Assign(Phony(), vec2<bool>()), // + Assign(Phony(), 4_a), // + Assign(Phony(), 5.0_a), // + Assign(Phony(), vec(nullptr, 2u, 6_a)), // + Assign(Phony(), vec(nullptr, 3u, 7.0_a)), // + Assign(Phony(), vec4<bool>()), // Assign(Phony(), "tex"), // Assign(Phony(), "smp"), // Assign(Phony(), AddressOf("s")), //
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc index 6c19f7c..4d9ab77 100644 --- a/src/tint/resolver/intrinsic_table.cc +++ b/src/tint/resolver/intrinsic_table.cc
@@ -722,6 +722,14 @@ return true; } +bool match_atomic_compare_exchange_result(const sem::Type* ty, const sem::Type*& T) { + if (ty->Is<Any>()) { + T = ty; + return true; + } + return false; +} + struct NameAndType { std::string name; sem::Type* type; @@ -779,6 +787,13 @@ {{"sig", vec_f32}, {"exp", vec_i32}}); } +const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const sem::Type* ty) { + return build_struct( + state, "__atomic_compare_exchange_result" + ty->FriendlyName(state.builder.Symbols()), + {{"old_value", const_cast<sem::Type*>(ty)}, + {"exchanged", state.builder.create<sem::Bool>()}}); +} + /// ParameterInfo describes a parameter struct ParameterInfo { /// The parameter usage (parameter name in definition file) @@ -929,6 +944,12 @@ /// Callback function when no overloads match. using OnNoMatch = std::function<void(Candidates)>; + /// Sorts the candidates based on their score, with the lowest (best-ranking) scores first. + static inline void SortCandidates(Candidates& candidates) { + std::stable_sort(candidates.begin(), candidates.end(), + [&](const Candidate& a, const Candidate& b) { return a.score < b.score; }); + } + /// Attempts to find a single intrinsic overload that matches the provided argument types. /// @param intrinsic the intrinsic being called /// @param intrinsic_name the name of the intrinsic @@ -947,7 +968,7 @@ TemplateState templates, OnNoMatch on_no_match) const; - /// Evaluates the overload for the provided argument types. + /// Evaluates the single overload for the provided argument types. /// @param overload the overload being considered /// @param args the argument types /// @param templates initial template state. This may contain explicitly specified template @@ -958,6 +979,21 @@ const std::vector<const sem::Type*>& args, TemplateState templates) const; + /// Performs overload resolution given the list of candidates, by ranking the conversions of + /// arguments to the each of the candidate's parameter types. + /// @param candidates the list of candidate overloads + /// @param intrinsic_name the name of the intrinsic + /// @param args the argument types + /// @param templates initial template state. This may contain explicitly specified template + /// arguments. For example `vec3<f32>()` would have the first template-type + /// template as `f32`. + /// @see https://www.w3.org/TR/WGSL/#overload-resolution-section + /// @returns the resolved Candidate. + Candidate ResolveCandidate(Candidates&& candidates, + const char* intrinsic_name, + const std::vector<const sem::Type*>& args, + TemplateState templates) const; + /// Match constructs a new MatchState /// @param templates the template state used for matcher evaluation /// @param overload the overload being evaluated @@ -976,12 +1012,11 @@ const Candidates& candidates, const char* intrinsic_name) const; - /// Raises an ICE when multiple overload candidates match, as this should never happen. - void ErrMultipleOverloadsMatched(size_t num_matched, - const char* intrinsic_name, - const std::vector<const sem::Type*>& args, - TemplateState templates, - Candidates candidates) const; + /// Raises an error when no overload is a clear winner of overload resolution + void ErrAmbiguousOverload(const char* intrinsic_name, + const std::vector<const sem::Type*>& args, + TemplateState templates, + Candidates candidates) const; ProgramBuilder& builder; Matchers matchers; @@ -1265,38 +1300,38 @@ TemplateState templates, OnNoMatch on_no_match) const { size_t num_matched = 0; + size_t match_idx = 0; Candidates candidates; candidates.reserve(intrinsic.num_overloads); for (size_t overload_idx = 0; overload_idx < static_cast<size_t>(intrinsic.num_overloads); overload_idx++) { auto candidate = ScoreOverload(&intrinsic.overloads[overload_idx], args, templates); if (candidate.score == 0) { + match_idx = overload_idx; num_matched++; } candidates.emplace_back(std::move(candidate)); } - // Sort the candidates with the most promising first - std::stable_sort(candidates.begin(), candidates.end(), - [&](const Candidate& a, const Candidate& b) { return a.score < b.score; }); - // How many candidates matched? - switch (num_matched) { - case 0: - on_no_match(std::move(candidates)); - return {}; - case 1: - break; - default: - // Note: Currently the intrinsic table does not contain any overloads which may result - // in ambiguities, so here we call ErrMultipleOverloadsMatched() which will produce and - // ICE. If we end up in the situation where this is unavoidable, we'll need to perform - // further overload resolution as described in - // https://www.w3.org/TR/WGSL/#overload-resolution-section. - ErrMultipleOverloadsMatched(num_matched, intrinsic_name, args, templates, candidates); + if (num_matched == 0) { + // Sort the candidates with the most promising first + SortCandidates(candidates); + on_no_match(std::move(candidates)); + return {}; } - auto match = candidates[0]; + Candidate match; + + if (num_matched == 1) { + match = std::move(candidates[match_idx]); + } else { + match = ResolveCandidate(std::move(candidates), intrinsic_name, args, std::move(templates)); + if (!match.overload) { + // Ambiguous overload. ResolveCandidate() will have already raised an error diagnostic. + return {}; + } + } // Build the return type const sem::Type* return_type = nullptr; @@ -1408,6 +1443,70 @@ return Candidate{overload, templates, parameters, score}; } +Impl::Candidate Impl::ResolveCandidate(Impl::Candidates&& candidates, + const char* intrinsic_name, + const std::vector<const sem::Type*>& args, + TemplateState templates) const { + std::vector<uint32_t> best_ranks(args.size(), 0xffffffff); + size_t num_matched = 0; + Candidate* best = nullptr; + for (auto& candidate : candidates) { + if (candidate.score > 0) { + continue; // Candidate has already been ruled out. + } + bool some_won = false; // An argument ranked less than the 'best' overload's argument + bool some_lost = false; // An argument ranked more than the 'best' overload's argument + for (size_t i = 0; i < args.size(); i++) { + auto rank = sem::Type::ConversionRank(args[i], candidate.parameters[i].type); + if (best_ranks[i] > rank) { + best_ranks[i] = rank; + some_won = true; + } else if (best_ranks[i] < rank) { + some_lost = true; + } + } + // If no arguments of this candidate ranked worse than the previous best candidate, then + // this candidate becomes the new best candidate. + // If no arguments of this candidate ranked better than the previous best candidate, then + // this candidate is removed from the list of matches. + // If neither of the above apply, then we have two candidates with no clear winner, which + // results in an ambiguous overload error. In this situation the loop ends with + // `num_matched > 1`. + if (some_won) { + // One or more arguments of this candidate ranked better than the previous best + // candidate's argument(s). + num_matched++; + if (!some_lost) { + // All arguments were at as-good or better than the previous best. + if (best) { + // Mark the previous best candidate as no longer being in the running, by + // setting its score to a non-zero value. We pick 1 as this is the closest to 0 + // (match) as we can get. + best->score = 1; + num_matched--; + } + // This candidate is the new best. + best = &candidate; + } + } else { + // No arguments ranked better than the current best. + // Change the score of this candidate to a non-zero value, so that it's not considered a + // match. + candidate.score = 1; + } + } + + if (num_matched > 1) { + // Re-sort the candidates with the most promising first + SortCandidates(candidates); + // Raise an error + ErrAmbiguousOverload(intrinsic_name, args, templates, candidates); + return {}; + } + + return std::move(*best); +} + MatchState Impl::Match(TemplateState& templates, const OverloadInfo* overload, MatcherIndex const* matcher_indices) const { @@ -1497,13 +1596,12 @@ return matcher->String(this); } -void Impl::ErrMultipleOverloadsMatched(size_t num_matched, - const char* intrinsic_name, - const std::vector<const sem::Type*>& args, - TemplateState templates, - Candidates candidates) const { +void Impl::ErrAmbiguousOverload(const char* intrinsic_name, + const std::vector<const sem::Type*>& args, + TemplateState templates, + Candidates candidates) const { std::stringstream ss; - ss << num_matched << " overloads matched " << intrinsic_name; + ss << "ambiguous overload while attempting to match " << intrinsic_name; for (size_t i = 0; i < std::numeric_limits<size_t>::max(); i++) { if (auto* ty = templates.Type(i)) { ss << ((i == 0) ? "<" : ", ") << ty->FriendlyName(builder.Symbols());
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl index c518e58..7a422fb 100644 --- a/src/tint/resolver/intrinsic_table.inl +++ b/src/tint/resolver/intrinsic_table.inl
@@ -1512,8 +1512,41 @@ return ss.str(); } +/// TypeMatcher for 'type __atomic_compare_exchange_result' +/// @see src/tint/intrinsics.def:121:6 +class AtomicCompareExchangeResult : public TypeMatcher { + public: + /// Checks whether the given type matches the matcher rules. + /// Match may define and refine the template types and numbers in state. + /// @param state the MatchState + /// @param type the type to match + /// @returns the canonicalized type on match, otherwise nullptr + const sem::Type* Match(MatchState& state, + const sem::Type* type) const override; + /// @param state the MatchState + /// @return a string representation of the matcher. + std::string String(MatchState* state) const override; +}; + +const sem::Type* AtomicCompareExchangeResult::Match(MatchState& state, const sem::Type* ty) const { + const sem::Type* T = nullptr; + if (!match_atomic_compare_exchange_result(ty, T)) { + return nullptr; + } + T = state.Type(T); + if (T == nullptr) { + return nullptr; + } + return build_atomic_compare_exchange_result(state, T); +} + +std::string AtomicCompareExchangeResult::String(MatchState* state) const { + const std::string T = state->TypeName(); + return "__atomic_compare_exchange_result<" + T + ">"; +} + /// TypeMatcher for 'match fiu32' -/// @see src/tint/intrinsics.def:127:7 +/// @see src/tint/intrinsics.def:129:7 class Fiu32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1551,7 +1584,7 @@ } /// TypeMatcher for 'match fi32' -/// @see src/tint/intrinsics.def:128:7 +/// @see src/tint/intrinsics.def:130:7 class Fi32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1586,7 +1619,7 @@ } /// TypeMatcher for 'match iu32' -/// @see src/tint/intrinsics.def:129:7 +/// @see src/tint/intrinsics.def:131:7 class Iu32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1621,7 +1654,7 @@ } /// TypeMatcher for 'match scalar' -/// @see src/tint/intrinsics.def:130:7 +/// @see src/tint/intrinsics.def:132:7 class Scalar : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1662,7 +1695,7 @@ } /// TypeMatcher for 'match abstract_or_scalar' -/// @see src/tint/intrinsics.def:131:7 +/// @see src/tint/intrinsics.def:133:7 class AbstractOrScalar : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1709,7 +1742,7 @@ } /// TypeMatcher for 'match af_f32' -/// @see src/tint/intrinsics.def:132:7 +/// @see src/tint/intrinsics.def:134:7 class AfF32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1744,7 +1777,7 @@ } /// TypeMatcher for 'match scalar_no_f32' -/// @see src/tint/intrinsics.def:133:7 +/// @see src/tint/intrinsics.def:135:7 class ScalarNoF32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1782,7 +1815,7 @@ } /// TypeMatcher for 'match scalar_no_i32' -/// @see src/tint/intrinsics.def:134:7 +/// @see src/tint/intrinsics.def:136:7 class ScalarNoI32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1820,7 +1853,7 @@ } /// TypeMatcher for 'match scalar_no_u32' -/// @see src/tint/intrinsics.def:135:7 +/// @see src/tint/intrinsics.def:137:7 class ScalarNoU32 : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1858,7 +1891,7 @@ } /// TypeMatcher for 'match scalar_no_bool' -/// @see src/tint/intrinsics.def:136:7 +/// @see src/tint/intrinsics.def:138:7 class ScalarNoBool : public TypeMatcher { public: /// Checks whether the given type matches the matcher rules, and returns the @@ -1896,7 +1929,7 @@ } /// EnumMatcher for 'match f32_texel_format' -/// @see src/tint/intrinsics.def:147:7 +/// @see src/tint/intrinsics.def:149:7 class F32TexelFormat : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -1929,7 +1962,7 @@ } /// EnumMatcher for 'match i32_texel_format' -/// @see src/tint/intrinsics.def:149:7 +/// @see src/tint/intrinsics.def:151:7 class I32TexelFormat : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -1961,7 +1994,7 @@ } /// EnumMatcher for 'match u32_texel_format' -/// @see src/tint/intrinsics.def:151:7 +/// @see src/tint/intrinsics.def:153:7 class U32TexelFormat : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -1993,7 +2026,7 @@ } /// EnumMatcher for 'match write_only' -/// @see src/tint/intrinsics.def:154:7 +/// @see src/tint/intrinsics.def:156:7 class WriteOnly : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -2019,7 +2052,7 @@ } /// EnumMatcher for 'match function_private_workgroup' -/// @see src/tint/intrinsics.def:156:7 +/// @see src/tint/intrinsics.def:158:7 class FunctionPrivateWorkgroup : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -2049,7 +2082,7 @@ } /// EnumMatcher for 'match workgroup_or_storage' -/// @see src/tint/intrinsics.def:157:7 +/// @see src/tint/intrinsics.def:159:7 class WorkgroupOrStorage : public NumberMatcher { public: /// Checks whether the given number matches the enum matcher rules. @@ -2206,6 +2239,7 @@ ModfResultVec ModfResultVec_; FrexpResult FrexpResult_; FrexpResultVec FrexpResultVec_; + AtomicCompareExchangeResult AtomicCompareExchangeResult_; Fiu32 Fiu32_; Fi32 Fi32_; Iu32 Iu32_; @@ -2233,7 +2267,7 @@ ~Matchers(); /// The template types, types, and type matchers - TypeMatcher const* const type[58] = { + TypeMatcher const* const type[59] = { /* [0] */ &template_type_0_, /* [1] */ &template_type_1_, /* [2] */ &Bool_, @@ -2282,16 +2316,17 @@ /* [45] */ &ModfResultVec_, /* [46] */ &FrexpResult_, /* [47] */ &FrexpResultVec_, - /* [48] */ &Fiu32_, - /* [49] */ &Fi32_, - /* [50] */ &Iu32_, - /* [51] */ &Scalar_, - /* [52] */ &AbstractOrScalar_, - /* [53] */ &AfF32_, - /* [54] */ &ScalarNoF32_, - /* [55] */ &ScalarNoI32_, - /* [56] */ &ScalarNoU32_, - /* [57] */ &ScalarNoBool_, + /* [48] */ &AtomicCompareExchangeResult_, + /* [49] */ &Fiu32_, + /* [50] */ &Fi32_, + /* [51] */ &Iu32_, + /* [52] */ &Scalar_, + /* [53] */ &AbstractOrScalar_, + /* [54] */ &AfF32_, + /* [55] */ &ScalarNoF32_, + /* [56] */ &ScalarNoI32_, + /* [57] */ &ScalarNoU32_, + /* [58] */ &ScalarNoBool_, }; /// The template numbers, and number matchers @@ -2488,34 +2523,36 @@ /* [170] */ 7, /* [171] */ 17, /* [172] */ 0, - /* [173] */ 18, - /* [174] */ 7, + /* [173] */ 48, + /* [174] */ 0, /* [175] */ 18, - /* [176] */ 0, - /* [177] */ 27, - /* [178] */ 7, - /* [179] */ 28, + /* [176] */ 7, + /* [177] */ 18, + /* [178] */ 0, + /* [179] */ 27, /* [180] */ 7, - /* [181] */ 29, + /* [181] */ 28, /* [182] */ 7, - /* [183] */ 19, + /* [183] */ 29, /* [184] */ 7, - /* [185] */ 30, + /* [185] */ 19, /* [186] */ 7, - /* [187] */ 31, + /* [187] */ 30, /* [188] */ 7, - /* [189] */ 32, + /* [189] */ 31, /* [190] */ 7, - /* [191] */ 25, - /* [192] */ 26, - /* [193] */ 37, - /* [194] */ 36, - /* [195] */ 35, - /* [196] */ 34, - /* [197] */ 43, - /* [198] */ 38, - /* [199] */ 44, - /* [200] */ 46, + /* [191] */ 32, + /* [192] */ 7, + /* [193] */ 25, + /* [194] */ 26, + /* [195] */ 37, + /* [196] */ 36, + /* [197] */ 35, + /* [198] */ 34, + /* [199] */ 43, + /* [200] */ 38, + /* [201] */ 44, + /* [202] */ 46, }; // Assert that the MatcherIndex is big enough to index all the matchers, plus @@ -2853,12 +2890,12 @@ { /* [65] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [66] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [67] */ @@ -2888,12 +2925,12 @@ { /* [72] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [73] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [74] */ @@ -2948,12 +2985,12 @@ { /* [84] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [85] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [86] */ @@ -3018,7 +3055,7 @@ { /* [98] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [99] */ @@ -3038,12 +3075,12 @@ { /* [102] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [103] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [104] */ @@ -3068,12 +3105,12 @@ { /* [108] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [109] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [110] */ @@ -3098,12 +3135,12 @@ { /* [114] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [115] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [116] */ @@ -3128,12 +3165,12 @@ { /* [120] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[189], + /* matcher indices */ &kMatcherIndices[191], }, { /* [121] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [122] */ @@ -3158,12 +3195,12 @@ { /* [126] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [127] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [128] */ @@ -3188,12 +3225,12 @@ { /* [132] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [133] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [134] */ @@ -3218,12 +3255,12 @@ { /* [138] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [139] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [140] */ @@ -3248,12 +3285,12 @@ { /* [144] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [145] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [146] */ @@ -3278,12 +3315,12 @@ { /* [150] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [151] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [152] */ @@ -3303,12 +3340,12 @@ { /* [155] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [156] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [157] */ @@ -3328,12 +3365,12 @@ { /* [160] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [161] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [162] */ @@ -3353,12 +3390,12 @@ { /* [165] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[189], + /* matcher indices */ &kMatcherIndices[191], }, { /* [166] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [167] */ @@ -3378,12 +3415,12 @@ { /* [170] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [171] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [172] */ @@ -3403,12 +3440,12 @@ { /* [175] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [176] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [177] */ @@ -3428,12 +3465,12 @@ { /* [180] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [181] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [182] */ @@ -3453,12 +3490,12 @@ { /* [185] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [186] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [187] */ @@ -3478,12 +3515,12 @@ { /* [190] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [191] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [192] */ @@ -3503,12 +3540,12 @@ { /* [195] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [196] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [197] */ @@ -3528,12 +3565,12 @@ { /* [200] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [201] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [202] */ @@ -3553,12 +3590,12 @@ { /* [205] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [206] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [207] */ @@ -3578,12 +3615,12 @@ { /* [210] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[187], + /* matcher indices */ &kMatcherIndices[189], }, { /* [211] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [212] */ @@ -3603,12 +3640,12 @@ { /* [215] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [216] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [217] */ @@ -3628,12 +3665,12 @@ { /* [220] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [221] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [222] */ @@ -3653,12 +3690,12 @@ { /* [225] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [226] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [227] */ @@ -3688,7 +3725,7 @@ { /* [232] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [233] */ @@ -3713,7 +3750,7 @@ { /* [237] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [238] */ @@ -3728,12 +3765,12 @@ { /* [240] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [241] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [242] */ @@ -3753,12 +3790,12 @@ { /* [245] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [246] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [247] */ @@ -3778,12 +3815,12 @@ { /* [250] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [251] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [252] */ @@ -3813,7 +3850,7 @@ { /* [257] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [258] */ @@ -3828,12 +3865,12 @@ { /* [260] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [261] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [262] */ @@ -3853,12 +3890,12 @@ { /* [265] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [266] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [267] */ @@ -3878,12 +3915,12 @@ { /* [270] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[189], + /* matcher indices */ &kMatcherIndices[191], }, { /* [271] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [272] */ @@ -3903,12 +3940,12 @@ { /* [275] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [276] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [277] */ @@ -3928,12 +3965,12 @@ { /* [280] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [281] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [282] */ @@ -3953,12 +3990,12 @@ { /* [285] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [286] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [287] */ @@ -3978,12 +4015,12 @@ { /* [290] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [291] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [292] */ @@ -4003,12 +4040,12 @@ { /* [295] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [296] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [297] */ @@ -4023,12 +4060,12 @@ { /* [299] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [300] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [301] */ @@ -4043,12 +4080,12 @@ { /* [303] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [304] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [305] */ @@ -4063,12 +4100,12 @@ { /* [307] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[187], + /* matcher indices */ &kMatcherIndices[189], }, { /* [308] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [309] */ @@ -4083,12 +4120,12 @@ { /* [311] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [312] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [313] */ @@ -4103,12 +4140,12 @@ { /* [315] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [316] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [317] */ @@ -4123,12 +4160,12 @@ { /* [319] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [320] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [321] */ @@ -4163,12 +4200,12 @@ { /* [327] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [328] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [329] */ @@ -4183,12 +4220,12 @@ { /* [331] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [332] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [333] */ @@ -4203,12 +4240,12 @@ { /* [335] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [336] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [337] */ @@ -4223,12 +4260,12 @@ { /* [339] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[187], + /* matcher indices */ &kMatcherIndices[189], }, { /* [340] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [341] */ @@ -4243,12 +4280,12 @@ { /* [343] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [344] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [345] */ @@ -4263,12 +4300,12 @@ { /* [347] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [348] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [349] */ @@ -4283,12 +4320,12 @@ { /* [351] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[189], + /* matcher indices */ &kMatcherIndices[191], }, { /* [352] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [353] */ @@ -4303,12 +4340,12 @@ { /* [355] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [356] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [357] */ @@ -4333,7 +4370,7 @@ { /* [361] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [362] */ @@ -4343,12 +4380,12 @@ { /* [363] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[181], + /* matcher indices */ &kMatcherIndices[183], }, { /* [364] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [365] */ @@ -4363,12 +4400,12 @@ { /* [367] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [368] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [369] */ @@ -4383,12 +4420,12 @@ { /* [371] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [372] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [373] */ @@ -4403,12 +4440,12 @@ { /* [375] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [376] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [377] */ @@ -4423,12 +4460,12 @@ { /* [379] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [380] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [381] */ @@ -4483,12 +4520,12 @@ { /* [391] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [392] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[192], + /* matcher indices */ &kMatcherIndices[194], }, { /* [393] */ @@ -4503,12 +4540,12 @@ { /* [395] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [396] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [397] */ @@ -4563,7 +4600,7 @@ { /* [407] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [408] */ @@ -4583,12 +4620,12 @@ { /* [411] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [412] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [413] */ @@ -4603,12 +4640,12 @@ { /* [415] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [416] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [417] */ @@ -4653,7 +4690,7 @@ { /* [425] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [426] */ @@ -4763,12 +4800,12 @@ { /* [447] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [448] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [449] */ @@ -4808,12 +4845,12 @@ { /* [456] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[197], + /* matcher indices */ &kMatcherIndices[199], }, { /* [457] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [458] */ @@ -5198,12 +5235,12 @@ { /* [534] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [535] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [536] */ @@ -5258,12 +5295,12 @@ { /* [546] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [547] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [548] */ @@ -5348,12 +5385,12 @@ { /* [564] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[187], + /* matcher indices */ &kMatcherIndices[189], }, { /* [565] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [566] */ @@ -5378,12 +5415,12 @@ { /* [570] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[185], + /* matcher indices */ &kMatcherIndices[187], }, { /* [571] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [572] */ @@ -5423,7 +5460,7 @@ { /* [579] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [580] */ @@ -5438,12 +5475,12 @@ { /* [582] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[179], + /* matcher indices */ &kMatcherIndices[181], }, { /* [583] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [584] */ @@ -5453,12 +5490,12 @@ { /* [585] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[177], + /* matcher indices */ &kMatcherIndices[179], }, { /* [586] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [587] */ @@ -5468,7 +5505,7 @@ { /* [588] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[198], + /* matcher indices */ &kMatcherIndices[200], }, { /* [589] */ @@ -5498,12 +5535,12 @@ { /* [594] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [595] */ /* usage */ ParameterUsage::kSampler, - /* matcher indices */ &kMatcherIndices[191], + /* matcher indices */ &kMatcherIndices[193], }, { /* [596] */ @@ -5713,7 +5750,7 @@ { /* [637] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [638] */ @@ -5733,7 +5770,7 @@ { /* [641] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [642] */ @@ -5753,7 +5790,7 @@ { /* [645] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [646] */ @@ -5773,7 +5810,7 @@ { /* [649] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [650] */ @@ -6163,7 +6200,7 @@ { /* [727] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[197], + /* matcher indices */ &kMatcherIndices[199], }, { /* [728] */ @@ -6748,7 +6785,7 @@ { /* [844] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[198], + /* matcher indices */ &kMatcherIndices[200], }, { /* [845] */ @@ -6758,7 +6795,7 @@ { /* [846] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [847] */ @@ -6768,17 +6805,17 @@ { /* [848] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [849] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [850] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [851] */ @@ -6848,12 +6885,12 @@ { /* [864] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [865] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [866] */ @@ -6943,7 +6980,7 @@ { /* [883] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[197], + /* matcher indices */ &kMatcherIndices[199], }, { /* [884] */ @@ -6968,27 +7005,27 @@ { /* [888] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[198], + /* matcher indices */ &kMatcherIndices[200], }, { /* [889] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[193], + /* matcher indices */ &kMatcherIndices[195], }, { /* [890] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[194], + /* matcher indices */ &kMatcherIndices[196], }, { /* [891] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[195], + /* matcher indices */ &kMatcherIndices[197], }, { /* [892] */ /* usage */ ParameterUsage::kTexture, - /* matcher indices */ &kMatcherIndices[196], + /* matcher indices */ &kMatcherIndices[198], }, { /* [893] */ @@ -7123,7 +7160,7 @@ { /* [919] */ /* usage */ ParameterUsage::kNone, - /* matcher indices */ &kMatcherIndices[183], + /* matcher indices */ &kMatcherIndices[185], }, { /* [920] */ @@ -7183,7 +7220,7 @@ { /* [931] */ /* usage */ ParameterUsage::kNone, - /* matcher indices */ &kMatcherIndices[173], + /* matcher indices */ &kMatcherIndices[175], }, { /* [932] */ @@ -7486,7 +7523,7 @@ { /* [1] */ /* name */ "U", - /* matcher index */ 57, + /* matcher index */ 58, }, { /* [2] */ @@ -7496,7 +7533,7 @@ { /* [3] */ /* name */ "U", - /* matcher index */ 54, + /* matcher index */ 55, }, { /* [4] */ @@ -7506,7 +7543,7 @@ { /* [5] */ /* name */ "U", - /* matcher index */ 55, + /* matcher index */ 56, }, { /* [6] */ @@ -7516,12 +7553,12 @@ { /* [7] */ /* name */ "U", - /* matcher index */ 56, + /* matcher index */ 57, }, { /* [8] */ /* name */ "T", - /* matcher index */ 48, + /* matcher index */ 49, }, { /* [9] */ @@ -7531,22 +7568,22 @@ { /* [10] */ /* name */ "T", - /* matcher index */ 53, + /* matcher index */ 54, }, { /* [11] */ /* name */ "T", - /* matcher index */ 50, + /* matcher index */ 51, }, { /* [12] */ /* name */ "T", - /* matcher index */ 52, + /* matcher index */ 53, }, { /* [13] */ /* name */ "T", - /* matcher index */ 51, + /* matcher index */ 52, }, { /* [14] */ @@ -7556,27 +7593,27 @@ { /* [15] */ /* name */ "T", - /* matcher index */ 57, + /* matcher index */ 58, }, { /* [16] */ /* name */ "T", - /* matcher index */ 54, + /* matcher index */ 55, }, { /* [17] */ /* name */ "T", - /* matcher index */ 56, + /* matcher index */ 57, }, { /* [18] */ /* name */ "T", - /* matcher index */ 55, + /* matcher index */ 56, }, { /* [19] */ /* name */ "T", - /* matcher index */ 49, + /* matcher index */ 50, }, }; @@ -9952,7 +9989,7 @@ /* template types */ &kTemplateTypes[20], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[990], - /* return matcher indices */ &kMatcherIndices[173], + /* return matcher indices */ &kMatcherIndices[175], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -9963,7 +10000,7 @@ /* template types */ &kTemplateTypes[9], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[931], - /* return matcher indices */ &kMatcherIndices[173], + /* return matcher indices */ &kMatcherIndices[175], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -9974,7 +10011,7 @@ /* template types */ &kTemplateTypes[10], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[928], - /* return matcher indices */ &kMatcherIndices[175], + /* return matcher indices */ &kMatcherIndices[177], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -9985,7 +10022,7 @@ /* template types */ &kTemplateTypes[10], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[28], - /* return matcher indices */ &kMatcherIndices[175], + /* return matcher indices */ &kMatcherIndices[177], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -9996,7 +10033,7 @@ /* template types */ &kTemplateTypes[10], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[435], - /* return matcher indices */ &kMatcherIndices[175], + /* return matcher indices */ &kMatcherIndices[177], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -10117,7 +10154,7 @@ /* template types */ &kTemplateTypes[20], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[990], - /* return matcher indices */ &kMatcherIndices[183], + /* return matcher indices */ &kMatcherIndices[185], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -10128,7 +10165,7 @@ /* template types */ &kTemplateTypes[9], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[919], - /* return matcher indices */ &kMatcherIndices[183], + /* return matcher indices */ &kMatcherIndices[185], /* flags */ OverloadFlags(OverloadFlag::kIsConstructor, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -10843,7 +10880,7 @@ /* template types */ &kTemplateTypes[20], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[843], - /* return matcher indices */ &kMatcherIndices[200], + /* return matcher indices */ &kMatcherIndices[202], /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -10865,7 +10902,7 @@ /* template types */ &kTemplateTypes[20], /* template numbers */ &kTemplateNumbers[10], /* parameters */ &kParameters[973], - /* return matcher indices */ &kMatcherIndices[199], + /* return matcher indices */ &kMatcherIndices[201], /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, { @@ -12526,7 +12563,7 @@ /* template types */ &kTemplateTypes[11], /* template numbers */ &kTemplateNumbers[9], /* parameters */ &kParameters[591], - /* return matcher indices */ &kMatcherIndices[105], + /* return matcher indices */ &kMatcherIndices[173], /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), }, }; @@ -13358,7 +13395,7 @@ }, { /* [106] */ - /* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> vec2<T> */ + /* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> */ /* num overloads */ 1, /* overloads */ &kOverloads[444], },
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc index 4a5c171..9c5de1e 100644 --- a/src/tint/resolver/intrinsic_table_test.cc +++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -793,6 +793,20 @@ ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call")); } +TEST_F(IntrinsicTableTest, OverloadResolution) { + // i32(abstract-int) produces candidates for both: + // ctor i32(i32) -> i32 + // conv i32<T: scalar_no_i32>(T) -> i32 + // The first should win overload resolution. + auto* ai = create<sem::AbstractInt>(); + auto* i32 = create<sem::I32>(); + auto result = table->Lookup(CtorConvIntrinsic::kI32, nullptr, {ai}, Source{}); + ASSERT_NE(result, nullptr); + EXPECT_EQ(result->ReturnType(), i32); + EXPECT_EQ(result->Parameters().size(), 1u); + EXPECT_EQ(result->Parameters()[0]->Type(), i32); +} + //////////////////////////////////////////////////////////////////////////////// // AbstractBinaryTests ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc index 8f4451e..d62ece9 100644 --- a/src/tint/resolver/materialize_test.cc +++ b/src/tint/resolver/materialize_test.cc
@@ -81,6 +81,13 @@ // let a : target_type = abstract_expr; kLet, + // var a : target_type; + // a = abstract_expr; + kAssign, + + // _ = abstract_expr; + kPhonyAssign, + // fn F(v : target_type) {} // fn x() { // F(abstract_expr); @@ -147,6 +154,10 @@ return o << "var"; case Method::kLet: return o << "let"; + case Method::kAssign: + return o << "assign"; + case Method::kPhonyAssign: + return o << "phony-assign"; case Method::kFnArg: return o << "fn-arg"; case Method::kBuiltinArg: @@ -251,6 +262,12 @@ case Method::kLet: WrapInFunction(Decl(Let("a", target_ty(), abstract_expr))); break; + case Method::kAssign: + WrapInFunction(Decl(Var("a", target_ty(), nullptr)), Assign("a", abstract_expr)); + break; + case Method::kPhonyAssign: + WrapInFunction(Assign(Phony(), abstract_expr)); + break; case Method::kFnArg: Func("F", {Param("P", target_ty())}, ty.void_(), {}); WrapInFunction(CallStmt(Call("F", abstract_expr))); @@ -364,20 +381,20 @@ /// Methods that support scalar materialization constexpr Method kScalarMethods[] = { - Method::kLet, Method::kVar, Method::kFnArg, Method::kBuiltinArg, + Method::kLet, Method::kVar, Method::kAssign, Method::kFnArg, Method::kBuiltinArg, Method::kReturn, Method::kArray, Method::kStruct, Method::kBinaryOp, }; /// Methods that support vector materialization constexpr Method kVectorMethods[] = { - Method::kLet, Method::kVar, Method::kFnArg, Method::kBuiltinArg, + Method::kLet, Method::kVar, Method::kAssign, Method::kFnArg, Method::kBuiltinArg, Method::kReturn, Method::kArray, Method::kStruct, Method::kBinaryOp, }; /// Methods that support matrix materialization constexpr Method kMatrixMethods[] = { - Method::kLet, Method::kVar, Method::kFnArg, Method::kReturn, - Method::kArray, Method::kStruct, Method::kBinaryOp, + Method::kLet, Method::kVar, Method::kAssign, Method::kFnArg, + Method::kReturn, Method::kArray, Method::kStruct, Method::kBinaryOp, }; /// Methods that support materialization for switch cases @@ -388,6 +405,12 @@ Method::kSwitchCaseWithAbstractCase, }; +/// Methods that do not materialize +constexpr Method kNoMaterializeMethods[] = { + Method::kPhonyAssign, + // TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary ops: + // Method::kBuiltinArg, Method::kBinaryOp, +}; INSTANTIATE_TEST_SUITE_P( MaterializeScalar, MaterializeAbstractNumericToConcreteType, @@ -486,18 +509,18 @@ Types<u32, AInt>(65535_a, 65535.0), // }))); -// TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary ops. -INSTANTIATE_TEST_SUITE_P(DISABLED_NoMaterialize, +INSTANTIATE_TEST_SUITE_P(NoMaterialize, MaterializeAbstractNumericToConcreteType, testing::Combine(testing::Values(Expectation::kNoMaterialize), - testing::Values(Method::kBuiltinArg, Method::kBinaryOp), + testing::ValuesIn(kNoMaterializeMethods), testing::ValuesIn(std::vector<Data>{ - Types<AInt, AInt>(), // - Types<AFloat, AFloat>(), // - Types<AIntV, AIntV>(), // - Types<AFloatV, AFloatV>(), // - Types<AFloatM, AFloatM>(), // + Types<AInt, AInt>(1_a, 1_a), // + Types<AIntV, AIntV>(1_a, 1_a), // + Types<AFloat, AFloat>(1.0_a, 1.0_a), // + Types<AFloatV, AFloatV>(1.0_a, 1.0_a), // + Types<AFloatM, AFloatM>(1.0_a, 1.0_a), // }))); + INSTANTIATE_TEST_SUITE_P(InvalidConversion, MaterializeAbstractNumericToConcreteType, testing::Combine(testing::Values(Expectation::kInvalidConversion), @@ -566,16 +589,16 @@ // let a = abstract_expr; kLet, - // min(abstract_expr, abstract_expr); + // min(abstract_expr, abstract_expr) kBuiltinArg, - // bitcast<f32>(abstract_expr); + // bitcast<f32>(abstract_expr) kBitcastF32Arg, - // bitcast<vec3<f32>>(abstract_expr); + // bitcast<vec3<f32>>(abstract_expr) kBitcastVec3F32Arg, - // array<i32, abstract_expr>(); + // array<i32, abstract_expr>() kArrayLength, // switch (abstract_expr) { @@ -587,7 +610,10 @@ // @workgroup_size(abstract_expr) // @stage(compute) // fn f() {} - kWorkgroupSize + kWorkgroupSize, + + // arr[abstract_expr] + kIndex, }; static std::ostream& operator<<(std::ostream& o, Method m) { @@ -608,6 +634,8 @@ return o << "switch"; case Method::kWorkgroupSize: return o << "workgroup-size"; + case Method::kIndex: + return o << "index"; } return o << "<unknown>"; } @@ -692,6 +720,10 @@ Func("f", {}, ty.void_(), {}, {WorkgroupSize(abstract_expr()), Stage(ast::PipelineStage::kCompute)}); break; + case Method::kIndex: + Global("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate); + WrapInFunction(IndexAccessor("arr", abstract_expr())); + break; } auto check_types_and_values = [&](const sem::Expression* expr) { @@ -756,6 +788,14 @@ Method::kBitcastF32Arg, }; +/// Methods that support abstract-integer materialization +/// Note: Doesn't contain kWorkgroupSize or kArrayLength as they have tighter constraints on the +/// range of allowed integer values. +constexpr Method kAIntMethods[] = { + Method::kSwitch, + Method::kIndex, +}; + /// Methods that support vector materialization constexpr Method kVectorMethods[] = { Method::kLet, @@ -826,16 +866,29 @@ Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32), // }))); -INSTANTIATE_TEST_SUITE_P(MaterializeSwitch, +INSTANTIATE_TEST_SUITE_P(MaterializeAInt, MaterializeAbstractNumericToDefaultType, testing::Combine(testing::Values(Expectation::kMaterialize), - testing::Values(Method::kSwitch), + testing::ValuesIn(kAIntMethods), testing::ValuesIn(std::vector<Data>{ Types<i32, AInt>(0_a, 0.0), // + Types<i32, AInt>(10_a, 10.0), // Types<i32, AInt>(AInt(kHighestI32), kHighestI32), // Types<i32, AInt>(AInt(kLowestI32), kLowestI32), // }))); +INSTANTIATE_TEST_SUITE_P( + MaterializeArrayLength, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::Values(Method::kArrayLength), + testing::ValuesIn(std::vector<Data>{ + Types<i32, AInt>(1_a, 1.0), // + Types<i32, AInt>(10_a, 10.0), // + Types<i32, AInt>(1000_a, 1000.0), // + // Note: kHighestI32 cannot be used due to max-byte-size validation + }))); + INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize, MaterializeAbstractNumericToDefaultType, testing::Combine(testing::Values(Expectation::kMaterialize), @@ -878,10 +931,10 @@ Types<f32M, AFloatM>(0.0_a, -kTooBigF32), // }))); -INSTANTIATE_TEST_SUITE_P(SwitchValueCannotBeRepresented, +INSTANTIATE_TEST_SUITE_P(AIntValueCannotBeRepresented, MaterializeAbstractNumericToDefaultType, testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::Values(Method::kSwitch), + testing::ValuesIn(kAIntMethods), testing::ValuesIn(std::vector<Data>{ Types<i32, AInt>(0_a, kHighestI32 + 1), // Types<i32, AInt>(0_a, kLowestI32 - 1), // @@ -896,6 +949,14 @@ Types<i32, AInt>(0_a, kLowestI32 - 1), // }))); +INSTANTIATE_TEST_SUITE_P(ArrayLengthValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::Values(Method::kArrayLength), + testing::ValuesIn(std::vector<Data>{ + Types<i32, AInt>(0_a, kHighestI32 + 1), // + }))); + } // namespace materialize_abstract_numeric_to_default_type } // namespace
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index c964d8a..aa09cfa 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc
@@ -1205,7 +1205,10 @@ } sem::Expression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* expr) { - auto* idx = sem_.Get(expr->index); + auto* idx = Materialize(sem_.Get(expr->index)); + if (!idx) { + return nullptr; + } auto* obj = sem_.Get(expr->object); auto* obj_raw_ty = obj->Type(); auto* obj_ty = obj_raw_ty->UnwrapRef(); @@ -2027,7 +2030,7 @@ // sem::Array uses a size of 0 for a runtime-sized array. uint32_t count = 0; if (auto* count_expr = arr->count) { - auto* count_sem = Expression(count_expr); + const auto* count_sem = Materialize(Expression(count_expr)); if (!count_sem) { return nullptr; } @@ -2406,14 +2409,23 @@ return false; } - auto* rhs = Expression(stmt->rhs); + const bool is_phony_assignment = stmt->lhs->Is<ast::PhonyExpression>(); + + const auto* rhs = Expression(stmt->rhs); if (!rhs) { return false; } + if (!is_phony_assignment) { + rhs = Materialize(rhs, lhs->Type()->UnwrapRef()); + if (!rhs) { + return false; + } + } + auto& behaviors = sem->Behaviors(); behaviors = rhs->Behaviors(); - if (!stmt->lhs->Is<ast::PhonyExpression>()) { + if (!is_phony_assignment) { behaviors.Add(lhs->Behaviors()); }
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc index 26b705f..ff1b57b 100644 --- a/src/tint/resolver/type_validation_test.cc +++ b/src/tint/resolver/type_validation_test.cc
@@ -73,7 +73,7 @@ ASSERT_NE(TypeOf(rhs), nullptr); } -TEST_F(ResolverTypeValidationTest, GlobalConstantNoConstructor_Pass) { +TEST_F(ResolverTypeValidationTest, GlobalOverrideNoConstructor_Pass) { // @id(0) override a :i32; Override(Source{{12, 34}}, "a", ty.i32(), nullptr, ast::AttributeList{Id(0)}); @@ -87,8 +87,8 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) { - // const<private> global_var: f32; +TEST_F(ResolverTypeValidationTest, GlobalLetWithStorageClass_Fail) { + // let<private> global_var: f32; AST().AddGlobalVariable(create<ast::Variable>( Source{{12, 34}}, Symbols().Register("global_var"), ast::StorageClass::kPrivate, ast::Access::kUndefined, ty.f32(), true, false, Expr(1.23_f), ast::AttributeList{})); @@ -188,6 +188,12 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Pass) { + // var<private> a : array<f32, 4>; + Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::StorageClass::kPrivate); + EXPECT_TRUE(r()->Resolve()) << r()->error(); +} + TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) { // var<private> a : array<f32, 4u>; Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate); @@ -200,7 +206,7 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Pass) { +TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Pass) { // let size = 4u; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(4_u)); @@ -208,7 +214,7 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } -TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Pass) { +TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Pass) { // let size = 4i; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(4_i)); @@ -216,6 +222,13 @@ EXPECT_TRUE(r()->Resolve()) << r()->error(); } +TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Zero) { + // var<private> a : array<f32, 0>; + Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate); + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1"); +} + TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) { // var<private> a : array<f32, 0u>; Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate); @@ -237,7 +250,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1"); } -TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Zero) { +TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Zero) { // let size = 0u; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(0_u)); @@ -246,7 +259,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1"); } -TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Zero) { +TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Zero) { // let size = 0i; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(0_i)); @@ -255,7 +268,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1"); } -TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Negative) { +TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Negative) { // let size = -10i; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(-10_i)); @@ -279,7 +292,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar"); } -TEST_F(ResolverTypeValidationTest, ArraySize_FloatConstant) { +TEST_F(ResolverTypeValidationTest, ArraySize_FloatLet) { // let size = 10.0; // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Expr(10_f)); @@ -288,7 +301,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar"); } -TEST_F(ResolverTypeValidationTest, ArraySize_IVecConstant) { +TEST_F(ResolverTypeValidationTest, ArraySize_IVecLet) { // let size = vec2<i32>(100, 100); // var<private> a : array<f32, size>; GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100_i, 100_i)); @@ -315,7 +328,7 @@ "is 0x100000000"); } -TEST_F(ResolverTypeValidationTest, ArraySize_OverridableConstant) { +TEST_F(ResolverTypeValidationTest, ArraySize_Overridable) { // override size = 10i; // var<private> a : array<f32, size>; Override("size", nullptr, Expr(10_i)); @@ -333,7 +346,7 @@ EXPECT_EQ(r()->error(), "12:34 error: array size identifier must be a module-scope constant"); } -TEST_F(ResolverTypeValidationTest, ArraySize_FunctionConstant) { +TEST_F(ResolverTypeValidationTest, ArraySize_FunctionLet) { // { // let size = 10; // var a : array<f32, size>;
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index fd59988..2b4d8a9 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc
@@ -48,6 +48,7 @@ #include "src/tint/ast/variable_decl_statement.h" #include "src/tint/ast/vector.h" #include "src/tint/ast/workgroup_attribute.h" +#include "src/tint/sem/abstract_numeric.h" #include "src/tint/sem/array.h" #include "src/tint/sem/atomic.h" #include "src/tint/sem/call.h" @@ -2141,7 +2142,8 @@ if (lhs->Is<ast::PhonyExpression>()) { // https://www.w3.org/TR/WGSL/#phony-assignment-section auto* ty = rhs_ty->UnwrapRef(); - if (!ty->IsConstructible() && !ty->IsAnyOf<sem::Pointer, sem::Texture, sem::Sampler>()) { + if (!ty->IsConstructible() && + !ty->IsAnyOf<sem::Pointer, sem::Texture, sem::Sampler, sem::AbstractNumeric>()) { AddError("cannot assign '" + sem_.TypeNameOf(rhs_ty) + "' to '_'. '_' can only be assigned a constructible, pointer, " "texture or sampler type",
diff --git a/src/tint/sem/constant.cc b/src/tint/sem/constant.cc index 1fa83f5..a2cfe8f 100644 --- a/src/tint/sem/constant.cc +++ b/src/tint/sem/constant.cc
@@ -45,9 +45,9 @@ bool Constant::AnyZero() const { return WithElements([&](auto&& vec) { - for (auto scalar : vec) { - using T = std::remove_reference_t<decltype(scalar)>; - if (scalar == T(0)) { + using T = typename std::decay_t<decltype(vec)>::value_type; + for (auto el : vec) { + if (el == T(0)) { return true; } } @@ -55,6 +55,32 @@ }); } +bool Constant::AllZero() const { + return WithElements([&](auto&& vec) { + using T = typename std::decay_t<decltype(vec)>::value_type; + for (auto el : vec) { + if (el != T(0)) { + return false; + } + } + return true; + }); +} + +bool Constant::AllEqual(size_t start, size_t end) const { + return WithElements([&](auto&& vec) { + if (!vec.empty()) { + auto value = vec[start]; + for (size_t i = start + 1; i < end; i++) { + if (vec[i] != value) { + return false; + } + } + } + return true; + }); +} + const Type* Constant::CheckElemType(const sem::Type* ty, size_t num_elements) { diag::List diag; if (ty->is_abstract_or_scalar() || ty->IsAnyOf<Vector, Matrix>()) {
diff --git a/src/tint/sem/constant.h b/src/tint/sem/constant.h index 43109f7..c99b979 100644 --- a/src/tint/sem/constant.h +++ b/src/tint/sem/constant.h
@@ -132,6 +132,17 @@ /// @returns true if any element is zero bool AnyZero() const; + /// @returns true if all elements are zero + bool AllZero() const; + + /// @returns true if all elements are the same value + bool AllEqual() const { return AllEqual(0, ElementCount()); } + + /// @param start the first element index + /// @param end one past the last element index + /// @returns true if all elements between `[start, end)` are the same value + bool AllEqual(size_t start, size_t end) const; + /// @param index the index of the element /// @return the element at `index`, which must be of type `T`. template <typename T>
diff --git a/src/tint/sem/constant_test.cc b/src/tint/sem/constant_test.cc index 345ebd8..6ad3cd6 100644 --- a/src/tint/sem/constant_test.cc +++ b/src/tint/sem/constant_test.cc
@@ -195,5 +195,43 @@ EXPECT_EQ(c.ElementCount(), 6u); } +TEST_F(ConstantTest, AnyZero) { + 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, {0_a, 2_a, 3_a}).AnyZero(), true); + EXPECT_EQ(Constant(vec3_ai, {1_a, 0_a, 3_a}).AnyZero(), true); + EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 0_a}).AnyZero(), true); + EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AnyZero(), true); +} + +TEST_F(ConstantTest, AllZero) { + auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u); + EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllZero(), false); + EXPECT_EQ(Constant(vec3_ai, {0_a, 2_a, 3_a}).AllZero(), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 0_a, 3_a}).AllZero(), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 0_a}).AllZero(), false); + EXPECT_EQ(Constant(vec3_ai, {0_a, 0_a, 0_a}).AllZero(), true); +} + +TEST_F(ConstantTest, AllEqual) { + auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u); + EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllEqual(), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 3_a}).AllEqual(), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 3_a, 3_a}).AllEqual(), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 1_a}).AllEqual(), true); + EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 2_a}).AllEqual(), true); + EXPECT_EQ(Constant(vec3_ai, {3_a, 3_a, 3_a}).AllEqual(), true); +} + +TEST_F(ConstantTest, AllEqualRange) { + auto* vec3_ai = create<Vector>(create<AbstractInt>(), 3u); + EXPECT_EQ(Constant(vec3_ai, {1_a, 2_a, 3_a}).AllEqual(1, 3), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 3_a}).AllEqual(1, 3), false); + EXPECT_EQ(Constant(vec3_ai, {1_a, 3_a, 3_a}).AllEqual(1, 3), true); + EXPECT_EQ(Constant(vec3_ai, {1_a, 1_a, 1_a}).AllEqual(1, 3), true); + EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 2_a}).AllEqual(1, 3), true); + EXPECT_EQ(Constant(vec3_ai, {2_a, 2_a, 3_a}).AllEqual(1, 3), false); +} + } // namespace } // namespace tint::sem
diff --git a/src/tint/transform/canonicalize_entry_point_io_test.cc b/src/tint/transform/canonicalize_entry_point_io_test.cc index d3fe95a..68ccb8b 100644 --- a/src/tint/transform/canonicalize_entry_point_io_test.cc +++ b/src/tint/transform/canonicalize_entry_point_io_test.cc
@@ -3173,7 +3173,7 @@ fn vert_main() { let inner_result = vert_main_inner(); value = inner_result; - vertex_point_size = 1.0; + vertex_point_size = 1.0f; } )"; @@ -3210,7 +3210,7 @@ let inner_result = vert_main_inner(); var wrapper_result : tint_symbol; wrapper_result.value = inner_result; - wrapper_result.vertex_point_size = 1.0; + wrapper_result.vertex_point_size = 1.0f; return wrapper_result; } )"; @@ -3252,7 +3252,7 @@ fn vert_main() { let inner_result = vert_main_inner(); pos_1 = inner_result.pos; - vertex_point_size = 1.0; + vertex_point_size = 1.0f; } )"; @@ -3289,7 +3289,7 @@ fn vert_main() { let inner_result = vert_main_inner(); pos_1 = inner_result.pos; - vertex_point_size = 1.0; + vertex_point_size = 1.0f; } struct VertOut { @@ -3338,7 +3338,7 @@ let inner_result = vert_main_inner(); var wrapper_result : tint_symbol; wrapper_result.pos = inner_result.pos; - wrapper_result.vertex_point_size = 1.0; + wrapper_result.vertex_point_size = 1.0f; return wrapper_result; } )"; @@ -3380,7 +3380,7 @@ let inner_result = vert_main_inner(); var wrapper_result : tint_symbol; wrapper_result.pos = inner_result.pos; - wrapper_result.vertex_point_size = 1.0; + wrapper_result.vertex_point_size = 1.0f; return wrapper_result; } @@ -3463,7 +3463,7 @@ let inner_result = vert_main_inner(VertIn1(collide_2), VertIn2(collide_3)); vertex_point_size_3 = inner_result.vertex_point_size; vertex_point_size_1_1 = inner_result.vertex_point_size_1; - vertex_point_size_4 = 1.0; + vertex_point_size_4 = 1.0f; } )"; @@ -3522,7 +3522,7 @@ let inner_result = vert_main_inner(VertIn1(collide_2), VertIn2(collide_3)); vertex_point_size_3 = inner_result.vertex_point_size; vertex_point_size_1_1 = inner_result.vertex_point_size_1; - vertex_point_size_4 = 1.0; + vertex_point_size_4 = 1.0f; } struct VertIn1 { @@ -3616,7 +3616,7 @@ var wrapper_result : tint_symbol_2; wrapper_result.vertex_point_size = inner_result.vertex_point_size; wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1; - wrapper_result.vertex_point_size_2 = 1.0; + wrapper_result.vertex_point_size_2 = 1.0f; return wrapper_result; } )"; @@ -3679,7 +3679,7 @@ var wrapper_result : tint_symbol_2; wrapper_result.vertex_point_size = inner_result.vertex_point_size; wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1; - wrapper_result.vertex_point_size_2 = 1.0; + wrapper_result.vertex_point_size_2 = 1.0f; return wrapper_result; } @@ -3768,7 +3768,7 @@ var wrapper_result : tint_symbol_2; wrapper_result.vertex_point_size = inner_result.vertex_point_size; wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1; - wrapper_result.vertex_point_size_2 = 1.0; + wrapper_result.vertex_point_size_2 = 1.0f; return wrapper_result; } )"; @@ -3831,7 +3831,7 @@ var wrapper_result : tint_symbol_2; wrapper_result.vertex_point_size = inner_result.vertex_point_size; wrapper_result.vertex_point_size_1 = inner_result.vertex_point_size_1; - wrapper_result.vertex_point_size_2 = 1.0; + wrapper_result.vertex_point_size_2 = 1.0f; return wrapper_result; } @@ -3953,7 +3953,7 @@ let inner_result = vertex_main(bitcast<u32>(gl_VertexID), bitcast<u32>(gl_InstanceID)); gl_Position = inner_result; gl_Position.y = -(gl_Position.y); - gl_Position.z = ((2.0 * gl_Position.z) - gl_Position.w); + gl_Position.z = ((2.0f * gl_Position.z) - gl_Position.w); } )";
diff --git a/src/tint/transform/combine_samplers_test.cc b/src/tint/transform/combine_samplers_test.cc index 1d84859..cad3109 100644 --- a/src/tint/transform/combine_samplers_test.cc +++ b/src/tint/transform/combine_samplers_test.cc
@@ -872,7 +872,7 @@ @group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_comparison_sampler : sampler_comparison; fn f(t_s : texture_depth_2d, coords : vec2<f32>) -> f32 { - return textureSampleCompare(t_s, placeholder_comparison_sampler, coords, 5.0); + return textureSampleCompare(t_s, placeholder_comparison_sampler, coords, 5.0f); } @group(0) @binding(0) @internal(disable_validation__binding_point_collision) var tex_samp : texture_depth_2d; @@ -912,7 +912,7 @@ @group(0) @binding(0) @internal(disable_validation__binding_point_collision) var placeholder_comparison_sampler : sampler_comparison; fn f(t_s : texture_depth_2d, coords : vec2<f32>) -> f32 { - return textureSampleCompare(t_s, placeholder_comparison_sampler, coords, 5.0); + return textureSampleCompare(t_s, placeholder_comparison_sampler, coords, 5.0f); } )";
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index 775cc05..a90a6e2 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc
@@ -644,14 +644,34 @@ << el_ty->TypeInfo().name; } - auto* ret_ty = CreateASTTypeFor(ctx, intrinsic->ReturnType()); - auto* func = - b.create<ast::Function>(b.Sym(), params, ret_ty, nullptr, - ast::AttributeList{ - atomic, - b.Disable(ast::DisabledValidation::kFunctionHasNoBody), - }, - ast::AttributeList{}); + const ast::Type* ret_ty = nullptr; + + // For intrinsics that return a struct, there is no AST node for it, so create one now. + if (intrinsic->Type() == sem::BuiltinType::kAtomicCompareExchangeWeak) { + auto* str = intrinsic->ReturnType()->As<sem::Struct>(); + TINT_ASSERT(Transform, str && str->Declaration() == nullptr); + + ast::StructMemberList ast_members; + ast_members.reserve(str->Members().size()); + for (auto& m : str->Members()) { + ast_members.push_back( + b.Member(ctx.Clone(m->Name()), CreateASTTypeFor(ctx, m->Type()))); + } + + auto name = b.Symbols().New("atomic_compare_exchange_weak_ret_type"); + auto* new_str = b.Structure(name, std::move(ast_members)); + ret_ty = b.ty.Of(new_str); + } else { + ret_ty = CreateASTTypeFor(ctx, intrinsic->ReturnType()); + } + + auto* func = b.create<ast::Function>( + b.Symbols().New(std::string{"tint_"} + intrinsic->str()), params, ret_ty, nullptr, + ast::AttributeList{ + atomic, + b.Disable(ast::DisabledValidation::kFunctionHasNoBody), + }, + ast::AttributeList{}); b.AST().AddFunction(func); return func->symbol; @@ -753,6 +773,10 @@ storage_class, type); } +bool DecomposeMemoryAccess::Intrinsic::IsAtomic() const { + return op != Op::kLoad && op != Op::kStore; +} + DecomposeMemoryAccess::DecomposeMemoryAccess() = default; DecomposeMemoryAccess::~DecomposeMemoryAccess() = default;
diff --git a/src/tint/transform/decompose_memory_access.h b/src/tint/transform/decompose_memory_access.h index 7a7b783..76cb23e 100644 --- a/src/tint/transform/decompose_memory_access.h +++ b/src/tint/transform/decompose_memory_access.h
@@ -89,6 +89,9 @@ /// @return the newly cloned object const Intrinsic* Clone(CloneContext* ctx) const override; + /// @return true if op is atomic + bool IsAtomic() const; + /// The op of the intrinsic const Op op;
diff --git a/src/tint/transform/decompose_memory_access_test.cc b/src/tint/transform/decompose_memory_access_test.cc index 22b5da4..19f8b2e 100644 --- a/src/tint/transform/decompose_memory_access_test.cc +++ b/src/tint/transform/decompose_memory_access_test.cc
@@ -2467,95 +2467,105 @@ @group(0) @binding(0) var<storage, read_write> sb : SB; @internal(intrinsic_atomic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) +fn tint_atomicStore(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) @internal(intrinsic_atomic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> i32 +fn tint_atomicLoad(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> i32 @internal(intrinsic_atomic_add_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicAdd(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_sub_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicSub(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_max_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicMax(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_min_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicMin(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_and_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicAnd(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_or_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicOr(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_xor_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicXor(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_exchange_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicExchange(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 + +struct atomic_compare_exchange_weak_ret_type { + old_value : i32, + exchanged : bool, +} @internal(intrinsic_atomic_compare_exchange_weak_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32, param_2 : i32) -> vec2<i32> +fn tint_atomicCompareExchangeWeak(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32, param_2 : i32) -> atomic_compare_exchange_weak_ret_type @internal(intrinsic_atomic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) +fn tint_atomicStore_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) @internal(intrinsic_atomic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> u32 +fn tint_atomicLoad_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> u32 @internal(intrinsic_atomic_add_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_13(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicAdd_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_sub_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_14(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicSub_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_max_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_15(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicMax_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_min_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_16(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicMin_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_and_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_17(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicAnd_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_or_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_18(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicOr_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_xor_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_19(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicXor_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_exchange_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_20(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicExchange_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 + +struct atomic_compare_exchange_weak_ret_type_1 { + old_value : u32, + exchanged : bool, +} @internal(intrinsic_atomic_compare_exchange_weak_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_21(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32, param_2 : u32) -> vec2<u32> +fn tint_atomicCompareExchangeWeak_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32, param_2 : u32) -> atomic_compare_exchange_weak_ret_type_1 @stage(compute) @workgroup_size(1) fn main() { - tint_symbol(sb, 16u, 123); - tint_symbol_1(sb, 16u); - tint_symbol_2(sb, 16u, 123); - tint_symbol_3(sb, 16u, 123); - tint_symbol_4(sb, 16u, 123); - tint_symbol_5(sb, 16u, 123); - tint_symbol_6(sb, 16u, 123); - tint_symbol_7(sb, 16u, 123); - tint_symbol_8(sb, 16u, 123); - tint_symbol_9(sb, 16u, 123); - tint_symbol_10(sb, 16u, 123, 345); - tint_symbol_11(sb, 20u, 123u); - tint_symbol_12(sb, 20u); - tint_symbol_13(sb, 20u, 123u); - tint_symbol_14(sb, 20u, 123u); - tint_symbol_15(sb, 20u, 123u); - tint_symbol_16(sb, 20u, 123u); - tint_symbol_17(sb, 20u, 123u); - tint_symbol_18(sb, 20u, 123u); - tint_symbol_19(sb, 20u, 123u); - tint_symbol_20(sb, 20u, 123u); - tint_symbol_21(sb, 20u, 123u, 345u); + tint_atomicStore(sb, 16u, 123); + tint_atomicLoad(sb, 16u); + tint_atomicAdd(sb, 16u, 123); + tint_atomicSub(sb, 16u, 123); + tint_atomicMax(sb, 16u, 123); + tint_atomicMin(sb, 16u, 123); + tint_atomicAnd(sb, 16u, 123); + tint_atomicOr(sb, 16u, 123); + tint_atomicXor(sb, 16u, 123); + tint_atomicExchange(sb, 16u, 123); + tint_atomicCompareExchangeWeak(sb, 16u, 123, 345); + tint_atomicStore_1(sb, 20u, 123u); + tint_atomicLoad_1(sb, 20u); + tint_atomicAdd_1(sb, 20u, 123u); + tint_atomicSub_1(sb, 20u, 123u); + tint_atomicMax_1(sb, 20u, 123u); + tint_atomicMin_1(sb, 20u, 123u); + tint_atomicAnd_1(sb, 20u, 123u); + tint_atomicOr_1(sb, 20u, 123u); + tint_atomicXor_1(sb, 20u, 123u); + tint_atomicExchange_1(sb, 20u, 123u); + tint_atomicCompareExchangeWeak_1(sb, 20u, 123u, 345u); } )"; @@ -2604,95 +2614,105 @@ auto* expect = R"( @internal(intrinsic_atomic_store_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) +fn tint_atomicStore(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) @internal(intrinsic_atomic_load_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> i32 +fn tint_atomicLoad(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> i32 @internal(intrinsic_atomic_add_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_2(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicAdd(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_sub_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_3(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicSub(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_max_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_4(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicMax(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_min_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_5(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicMin(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_and_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_6(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicAnd(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_or_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_7(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicOr(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_xor_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_8(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicXor(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 @internal(intrinsic_atomic_exchange_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_9(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 +fn tint_atomicExchange(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32) -> i32 + +struct atomic_compare_exchange_weak_ret_type { + old_value : i32, + exchanged : bool, +} @internal(intrinsic_atomic_compare_exchange_weak_storage_i32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_10(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32, param_2 : i32) -> vec2<i32> +fn tint_atomicCompareExchangeWeak(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : i32, param_2 : i32) -> atomic_compare_exchange_weak_ret_type @internal(intrinsic_atomic_store_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_11(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) +fn tint_atomicStore_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) @internal(intrinsic_atomic_load_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_12(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> u32 +fn tint_atomicLoad_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32) -> u32 @internal(intrinsic_atomic_add_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_13(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicAdd_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_sub_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_14(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicSub_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_max_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_15(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicMax_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_min_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_16(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicMin_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_and_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_17(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicAnd_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_or_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_18(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicOr_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_xor_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_19(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicXor_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 @internal(intrinsic_atomic_exchange_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_20(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 +fn tint_atomicExchange_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32) -> u32 + +struct atomic_compare_exchange_weak_ret_type_1 { + old_value : u32, + exchanged : bool, +} @internal(intrinsic_atomic_compare_exchange_weak_storage_u32) @internal(disable_validation__function_has_no_body) -fn tint_symbol_21(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32, param_2 : u32) -> vec2<u32> +fn tint_atomicCompareExchangeWeak_1(@internal(disable_validation__ignore_constructible_function_parameter) buffer : SB, offset : u32, param_1 : u32, param_2 : u32) -> atomic_compare_exchange_weak_ret_type_1 @stage(compute) @workgroup_size(1) fn main() { - tint_symbol(sb, 16u, 123); - tint_symbol_1(sb, 16u); - tint_symbol_2(sb, 16u, 123); - tint_symbol_3(sb, 16u, 123); - tint_symbol_4(sb, 16u, 123); - tint_symbol_5(sb, 16u, 123); - tint_symbol_6(sb, 16u, 123); - tint_symbol_7(sb, 16u, 123); - tint_symbol_8(sb, 16u, 123); - tint_symbol_9(sb, 16u, 123); - tint_symbol_10(sb, 16u, 123, 345); - tint_symbol_11(sb, 20u, 123u); - tint_symbol_12(sb, 20u); - tint_symbol_13(sb, 20u, 123u); - tint_symbol_14(sb, 20u, 123u); - tint_symbol_15(sb, 20u, 123u); - tint_symbol_16(sb, 20u, 123u); - tint_symbol_17(sb, 20u, 123u); - tint_symbol_18(sb, 20u, 123u); - tint_symbol_19(sb, 20u, 123u); - tint_symbol_20(sb, 20u, 123u); - tint_symbol_21(sb, 20u, 123u, 345u); + tint_atomicStore(sb, 16u, 123); + tint_atomicLoad(sb, 16u); + tint_atomicAdd(sb, 16u, 123); + tint_atomicSub(sb, 16u, 123); + tint_atomicMax(sb, 16u, 123); + tint_atomicMin(sb, 16u, 123); + tint_atomicAnd(sb, 16u, 123); + tint_atomicOr(sb, 16u, 123); + tint_atomicXor(sb, 16u, 123); + tint_atomicExchange(sb, 16u, 123); + tint_atomicCompareExchangeWeak(sb, 16u, 123, 345); + tint_atomicStore_1(sb, 20u, 123u); + tint_atomicLoad_1(sb, 20u); + tint_atomicAdd_1(sb, 20u, 123u); + tint_atomicSub_1(sb, 20u, 123u); + tint_atomicMax_1(sb, 20u, 123u); + tint_atomicMin_1(sb, 20u, 123u); + tint_atomicAnd_1(sb, 20u, 123u); + tint_atomicOr_1(sb, 20u, 123u); + tint_atomicXor_1(sb, 20u, 123u); + tint_atomicExchange_1(sb, 20u, 123u); + tint_atomicCompareExchangeWeak_1(sb, 20u, 123u, 345u); } @group(0) @binding(0) var<storage, read_write> sb : SB;
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc index 53b335e..e911df3 100644 --- a/src/tint/transform/decompose_strided_array_test.cc +++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -374,8 +374,8 @@ @stage(compute) @workgroup_size(1i) fn f() { s.a = array<strided_arr, 4u>(); - s.a = array<strided_arr, 4u>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0)); - s.a[1i].el = 5.0; + s.a = array<strided_arr, 4u>(strided_arr(1.0f), strided_arr(2.0f), strided_arr(3.0f), strided_arr(4.0f)); + s.a[1i].el = 5.0f; } )"; @@ -423,8 +423,8 @@ @stage(compute) @workgroup_size(1i) fn f() { s.a = array<f32, 4u>(); - s.a = array<f32, 4u>(1.0, 2.0, 3.0, 4.0); - s.a[1i] = 5.0; + s.a = array<f32, 4u>(1.0f, 2.0f, 3.0f, 4.0f); + s.a[1i] = 5.0f; } )"; @@ -483,8 +483,8 @@ fn f() { let c = s.a; let d = s.a[1i].el; - s.a = array<strided_arr, 4u>(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0)); - s.a[1i].el = 5.0; + s.a = array<strided_arr, 4u>(strided_arr(1.0f), strided_arr(2.0f), strided_arr(3.0f), strided_arr(4.0f)); + s.a[1i].el = 5.0f; } )"; @@ -546,8 +546,8 @@ let a : ARR = s.a; let b : f32 = s.a[1i].el; s.a = ARR(); - s.a = ARR(strided_arr(1.0), strided_arr(2.0), strided_arr(3.0), strided_arr(4.0)); - s.a[1i].el = 5.0; + s.a = ARR(strided_arr(1.0f), strided_arr(2.0f), strided_arr(3.0f), strided_arr(4.0f)); + s.a[1i].el = 5.0f; } )"; @@ -648,7 +648,7 @@ let c : ARR_A = s.a[3i].el[2i]; let d : f32 = s.a[3i].el[2i][1i].el; s.a = ARR_B(); - s.a[3i].el[2i][1i].el = 5.0; + s.a[3i].el[2i][1i].el = 5.0f; } )";
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc index 803ae73..2367cf1 100644 --- a/src/tint/transform/decompose_strided_matrix_test.cc +++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -376,7 +376,7 @@ @stage(compute) @workgroup_size(1i) fn f() { - s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0))); + s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f))); } )"; @@ -429,7 +429,7 @@ @stage(compute) @workgroup_size(1i) fn f() { - s.m[1i] = vec2<f32>(1.0, 2.0); + s.m[1i] = vec2<f32>(1.0f, 2.0f); } )"; @@ -505,8 +505,8 @@ let x = arr_to_mat2x2_stride_32(s.m); let y = s.m[1i]; let z = x[1i]; - s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0))); - s.m[1i] = vec2<f32>(5.0, 6.0); + s.m = mat2x2_stride_32_to_arr(mat2x2<f32>(vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f))); + s.m[1i] = vec2<f32>(5.0f, 6.0f); } )"; @@ -613,7 +613,7 @@ @stage(compute) @workgroup_size(1i) fn f() { - s.m = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0)); + s.m = mat2x2<f32>(vec2<f32>(1.0f, 2.0f), vec2<f32>(3.0f, 4.0f)); } )";
diff --git a/src/tint/transform/fold_constants_test.cc b/src/tint/transform/fold_constants_test.cc index f27ede6..54bb2e3 100644 --- a/src/tint/transform/fold_constants_test.cc +++ b/src/tint/transform/fold_constants_test.cc
@@ -41,7 +41,7 @@ var<private> b : u32 = 123u; -var<private> c : f32 = 123.0; +var<private> c : f32 = 123.0f; var<private> d : bool = true; @@ -70,7 +70,7 @@ var<private> b : u32 = 123u; -var<private> c : f32 = 123.0; +var<private> c : f32 = 123.0f; var<private> d : bool = true; @@ -99,7 +99,7 @@ var<private> b : u32 = 123u; -var<private> c : f32 = 123.0; +var<private> c : f32 = 123.0f; var<private> d : bool = true; @@ -128,7 +128,7 @@ var<private> b : vec3<u32> = vec3<u32>(123u); -var<private> c : vec3<f32> = vec3<f32>(123.0); +var<private> c : vec3<f32> = vec3<f32>(123.0f); var<private> d : vec3<bool> = vec3<bool>(true); @@ -157,7 +157,7 @@ var<private> b : vec3<u32> = vec3<u32>(123u); -var<private> c : vec3<f32> = vec3<f32>(123.0); +var<private> c : vec3<f32> = vec3<f32>(123.0f); var<private> d : vec3<bool> = vec3<bool>(true); @@ -186,7 +186,7 @@ var<private> b : vec3<u32> = vec3<u32>(123u); -var<private> c : vec3<f32> = vec3<f32>(123.0); +var<private> c : vec3<f32> = vec3<f32>(123.0f); var<private> d : vec3<bool> = vec3<bool>(true); @@ -245,7 +245,7 @@ fn f() { var a : i32 = 123i; var b : u32 = 123u; - var c : f32 = 123.0; + var c : f32 = 123.0f; var d : bool = true; } )"; @@ -269,7 +269,7 @@ fn f() { var a : i32 = 123i; var b : u32 = 123u; - var c : f32 = 123.0; + var c : f32 = 123.0f; var d : bool = true; } )"; @@ -293,7 +293,7 @@ fn f() { var a : i32 = 123i; var b : u32 = 123u; - var c : f32 = 123.0; + var c : f32 = 123.0f; var d : bool = true; } )"; @@ -308,7 +308,7 @@ fn f() { var a : vec3<i32> = vec3<i32>(123i); var b : vec3<u32> = vec3<u32>(123u); - var c : vec3<f32> = vec3<f32>(123.0); + var c : vec3<f32> = vec3<f32>(123.0f); var d : vec3<bool> = vec3<bool>(true); } )"; @@ -317,7 +317,7 @@ fn f() { var a : vec3<i32> = vec3<i32>(123i); var b : vec3<u32> = vec3<u32>(123u); - var c : vec3<f32> = vec3<f32>(123.0); + var c : vec3<f32> = vec3<f32>(123.0f); var d : vec3<bool> = vec3<bool>(true); } )"; @@ -341,7 +341,7 @@ fn f() { var a : vec3<i32> = vec3<i32>(123i); var b : vec3<u32> = vec3<u32>(123u); - var c : vec3<f32> = vec3<f32>(123.0); + var c : vec3<f32> = vec3<f32>(123.0f); var d : vec3<bool> = vec3<bool>(true); } )"; @@ -365,7 +365,7 @@ fn f() { var a : vec3<i32> = vec3<i32>(123i); var b : vec3<u32> = vec3<u32>(123u); - var c : vec3<f32> = vec3<f32>(123.0); + var c : vec3<f32> = vec3<f32>(123.0f); var d : vec3<bool> = vec3<bool>(true); } )"; @@ -412,7 +412,7 @@ auto* expect = R"( fn f() { var a : f32 = f32(); - var b : vec2<f32> = vec2<f32>(1.0, a); + var b : vec2<f32> = vec2<f32>(1.0f, a); } )";
diff --git a/src/tint/transform/manager.cc b/src/tint/transform/manager.cc index 823474c..e5f7682 100644 --- a/src/tint/transform/manager.cc +++ b/src/tint/transform/manager.cc
@@ -49,7 +49,7 @@ Output out; for (const auto& transform : transforms_) { if (!transform->ShouldRun(in, data)) { - TINT_IF_PRINT_PROGRAM(std::cout << "Skipping " << transform->TypeInfo().name); + TINT_IF_PRINT_PROGRAM(std::cout << "Skipping " << transform->TypeInfo().name << std::endl); continue; } TINT_IF_PRINT_PROGRAM(print_program("Input to", transform.get()));
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc index 171df8d..39c4602 100644 --- a/src/tint/transform/multiplanar_external_texture_test.cc +++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -249,14 +249,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -318,14 +318,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -394,12 +394,12 @@ if ((params.numPlanes == 1u)) { color = textureLoad(plane0, coord, 0i).rgb; } else { - color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -462,12 +462,12 @@ if ((params.numPlanes == 1u)) { color = textureLoad(plane0, coord, 0i).rgb; } else { - color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -536,14 +536,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> { @@ -551,12 +551,12 @@ if ((params.numPlanes == 1u)) { color = textureLoad(plane0, coord, 0i).rgb; } else { - color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -619,14 +619,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn textureLoadExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, coord : vec2<i32>, params : ExternalTextureParams) -> vec4<f32> { @@ -634,12 +634,12 @@ if ((params.numPlanes == 1u)) { color = textureLoad(plane0, coord, 0i).rgb; } else { - color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureLoad(plane0, coord, 0i).r, textureLoad(plane1, coord, 0i).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -730,14 +730,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } @stage(fragment) @@ -808,14 +808,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) { @@ -895,14 +895,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) { @@ -972,14 +972,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(s : sampler, t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams) { @@ -1060,14 +1060,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_2 : texture_2d<f32>, ext_tex_params_2 : ExternalTextureParams, s : sampler, t2 : texture_2d<f32>, ext_tex_plane_1_3 : texture_2d<f32>, ext_tex_params_3 : ExternalTextureParams) { @@ -1158,14 +1158,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_2 : texture_2d<f32>, ext_tex_params_2 : ExternalTextureParams, s : sampler, t2 : texture_2d<f32>, ext_tex_plane_1_3 : texture_2d<f32>, ext_tex_params_3 : ExternalTextureParams) { @@ -1243,14 +1243,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn nested(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) { @@ -1333,14 +1333,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn nested(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) { @@ -1463,14 +1463,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) { @@ -1551,14 +1551,14 @@ fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> { var color : vec3<f32>; if ((params.numPlanes == 1u)) { - color = textureSampleLevel(plane0, smp, coord, 0.0).rgb; + color = textureSampleLevel(plane0, smp, coord, 0.0f).rgb; } else { - color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0).r, textureSampleLevel(plane1, smp, coord, 0.0).rg, 1.0) * params.yuvToRgbConversionMatrix); + color = (vec4<f32>(textureSampleLevel(plane0, smp, coord, 0.0f).r, textureSampleLevel(plane1, smp, coord, 0.0f).rg, 1.0f) * params.yuvToRgbConversionMatrix); } color = gammaCorrection(color, params.gammaDecodeParams); color = (params.gamutConversionMatrix * color); color = gammaCorrection(color, params.gammaEncodeParams); - return vec4<f32>(color, 1.0); + return vec4<f32>(color, 1.0f); } fn f(t : texture_2d<f32>, ext_tex_plane_1_1 : texture_2d<f32>, ext_tex_params_1 : ExternalTextureParams, s : sampler) {
diff --git a/src/tint/transform/vertex_pulling_test.cc b/src/tint/transform/vertex_pulling_test.cc index 80768a7..ef37631 100644 --- a/src/tint/transform/vertex_pulling_test.cc +++ b/src/tint/transform/vertex_pulling_test.cc
@@ -1172,22 +1172,22 @@ uint8x4 = (((vec4<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy; sint8x2 = (((vec2<i32>(bitcast<i32>((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] << 16u))) << vec2<u32>(8u, 0u)) >> vec2<u32>(24u))).x; sint8x4 = (((vec4<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec4<u32>(24u, 16u, 8u, 0u)) >> vec4<u32>(24u))).xy; - unorm8x2 = vec4<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0, 1.0); + unorm8x2 = vec4<f32>(unpack4x8unorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0f, 1.0f); unorm8x4 = unpack4x8unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x; - snorm8x2 = vec3<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0); + snorm8x2 = vec3<f32>(unpack4x8snorm((tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)] & 65535u)).xy, 0.0f); snorm8x4 = unpack4x8snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]).x; uint16x2 = vec3<u32>(((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0u); uint16x4 = (((vec2<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).xy; sint16x2 = vec4<i32>(((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)])) << vec2<u32>(16u, 0u)) >> vec2<u32>(16u)), 0i, 1i); sint16x4 = (((vec2<i32>(bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<i32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xxyy << vec4<u32>(16u, 0u, 16u, 0u)) >> vec4<u32>(16u))).x; - unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0); + unorm16x2 = vec3<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f); unorm16x4 = vec4<f32>(unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16unorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x; - snorm16x2 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0); + snorm16x2 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 1.0f); snorm16x4 = vec4<f32>(unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16snorm(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).xyz; - float16x2 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 1.0); + float16x2 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 1.0f); float16x4 = vec4<f32>(unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), unpack2x16float(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])).x; - float32 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0, 0.0, 1.0); - float32x2 = vec4<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0, 1.0); + float32 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), 0.0f, 0.0f, 1.0f); + float32x2 = vec4<f32>(vec2<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)])), 0.0f, 1.0f); float32x3 = vec3<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)])).xy; float32x4 = vec4<f32>(bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 17u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 18u)]), bitcast<f32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 19u)])).xyz; uint32 = vec3<u32>(tint_pulling_vertex_buffer_0.tint_vertex_data[(buffer_array_base_0 + 16u)], 0u, 0u);
diff --git a/src/tint/utils/compiler_macros.h b/src/tint/utils/compiler_macros.h index ada138e..34965c6 100644 --- a/src/tint/utils/compiler_macros.h +++ b/src/tint/utils/compiler_macros.h
@@ -20,23 +20,63 @@ #define TINT_REQUIRE_SEMICOLON static_assert(true) #if defined(_MSC_VER) -#define TINT_WARNING_UNREACHABLE_CODE 4702 -#define TINT_WARNING_CONSTANT_OVERFLOW 4756 +//////////////////////////////////////////////////////////////////////////////// +// MSVC +//////////////////////////////////////////////////////////////////////////////// +#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW __pragma(warning(disable : 4756)) +#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED /* currently no-op */ +#define TINT_DISABLE_WARNING_UNREACHABLE_CODE __pragma(warning(disable : 4702)) // clang-format off -#define TINT_BEGIN_DISABLE_WARNING(name) \ - __pragma(warning(push)) \ - __pragma(warning(disable:TINT_CONCAT(TINT_WARNING_, name))) \ +#define TINT_BEGIN_DISABLE_WARNING(name) \ + __pragma(warning(push)) \ + TINT_CONCAT(TINT_DISABLE_WARNING_, name) \ TINT_REQUIRE_SEMICOLON -#define TINT_END_DISABLE_WARNING(name) \ - __pragma(warning(pop)) \ +#define TINT_END_DISABLE_WARNING(name) \ + __pragma(warning(pop)) \ + TINT_REQUIRE_SEMICOLON +// clang-format on +#elif defined(__clang__) +//////////////////////////////////////////////////////////////////////////////// +// Clang +//////////////////////////////////////////////////////////////////////////////// +#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW /* currently no-op */ +#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED /* currently no-op */ +#define TINT_DISABLE_WARNING_UNREACHABLE_CODE /* currently no-op */ + +// clang-format off +#define TINT_BEGIN_DISABLE_WARNING(name) \ + _Pragma("clang diagnostic push") \ + TINT_CONCAT(TINT_DISABLE_WARNING_, name) \ + TINT_REQUIRE_SEMICOLON +#define TINT_END_DISABLE_WARNING(name) \ + _Pragma("clang diagnostic pop") \ + TINT_REQUIRE_SEMICOLON +// clang-format on +#elif defined(__GNUC__) +//////////////////////////////////////////////////////////////////////////////// +// GCC +//////////////////////////////////////////////////////////////////////////////// +#define TINT_DISABLE_WARNING_CONSTANT_OVERFLOW /* currently no-op */ +#define TINT_DISABLE_WARNING_MAYBE_UNINITIALIZED \ + _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +#define TINT_DISABLE_WARNING_UNREACHABLE_CODE /* currently no-op */ + +// clang-format off +#define TINT_BEGIN_DISABLE_WARNING(name) \ + _Pragma("GCC diagnostic push") \ + TINT_CONCAT(TINT_DISABLE_WARNING_, name) \ + TINT_REQUIRE_SEMICOLON +#define TINT_END_DISABLE_WARNING(name) \ + _Pragma("GCC diagnostic pop") \ TINT_REQUIRE_SEMICOLON // clang-format on #else -// clang-format off +//////////////////////////////////////////////////////////////////////////////// +// Other +//////////////////////////////////////////////////////////////////////////////// #define TINT_BEGIN_DISABLE_WARNING(name) TINT_REQUIRE_SEMICOLON #define TINT_END_DISABLE_WARNING(name) TINT_REQUIRE_SEMICOLON -// clang-format on -#endif // defined(_MSC_VER) +#endif #endif // SRC_TINT_UTILS_COMPILER_MACROS_H_
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index ccce06a..eb44f14 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc
@@ -32,10 +32,10 @@ #include "src/tint/sem/atomic.h" #include "src/tint/sem/block_statement.h" #include "src/tint/sem/call.h" +#include "src/tint/sem/constant.h" #include "src/tint/sem/depth_multisampled_texture.h" #include "src/tint/sem/depth_texture.h" #include "src/tint/sem/function.h" -#include "src/tint/sem/materialize.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/module.h" #include "src/tint/sem/multisampled_texture.h" @@ -147,6 +147,18 @@ return "unknown"; } +void PrintF32(std::ostream& out, float value) { + // Note: Currently inf and nan should not be constructable, but this is implemented for the day + // we support them. + if (std::isinf(value)) { + out << (value >= 0 ? "uintBitsToFloat(0x7f800000u)" : "uintBitsToFloat(0xff800000u)"); + } else if (std::isnan(value)) { + out << "uintBitsToFloat(0x7fc00000u)"; + } else { + out << FloatToString(value) << "f"; + } +} + } // namespace SanitizedResult::SanitizedResult() = default; @@ -691,12 +703,7 @@ } bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) { - auto* sem = builder_.Sem().Get(expr); - if (auto* m = sem->As<sem::Materialize>()) { - // TODO(crbug.com/tint/1504): Just emit the constant value. - sem = m->Expr(); - } - auto* call = sem->As<sem::Call>(); + auto* call = builder_.Sem().Get<sem::Call>(expr); auto* target = call->Target(); if (target->Is<sem::Function>()) { @@ -911,39 +918,56 @@ return true; } case sem::BuiltinType::kAtomicCompareExchangeWeak: { - return CallBuiltinHelper( - out, expr, builtin, [&](TextBuffer* b, const std::vector<std::string>& params) { - { - auto pre = line(b); - if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::StorageClass::kNone, - ast::Access::kUndefined, "result")) { - return false; - } - pre << ";"; + // Emit the builtin return type unique to this overload. This does not + // exist in the AST, so it will not be generated in Generate(). + if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) { + return false; + } + + auto* dest = expr->args[0]; + auto* compare_value = expr->args[1]; + auto* value = expr->args[2]; + + std::string result = UniqueIdentifier("atomic_compare_result"); + + { + auto pre = line(); + if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::StorageClass::kNone, + ast::Access::kUndefined, result)) { + return false; + } + pre << ";"; + } + { + auto pre = line(); + pre << result << ".old_value = atomicCompSwap"; + { + ScopedParen sp(pre); + if (!EmitExpression(pre, dest)) { + return false; } - { - auto pre = line(b); - pre << "result.x = atomicCompSwap"; - { - ScopedParen sp(pre); - pre << params[0]; - pre << ", " << params[1]; - pre << ", " << params[2]; - } - pre << ";"; + pre << ", "; + if (!EmitExpression(pre, compare_value)) { + return false; } - { - auto pre = line(b); - pre << "result.y = result.x == " << params[2] << " ? "; - if (TypeOf(expr->args[2])->Is<sem::U32>()) { - pre << "1u : 0u;"; - } else { - pre << "1 : 0;"; - } + pre << ", "; + if (!EmitExpression(pre, value)) { + return false; } - line(b) << "return result;"; - return true; - }); + } + pre << ";"; + } + { + auto pre = line(); + pre << result << ".exchanged = " << result << ".old_value == "; + if (!EmitExpression(pre, compare_value)) { + return false; + } + pre << ";"; + } + + out << result; + return true; } case sem::BuiltinType::kAtomicAdd: @@ -1745,34 +1769,42 @@ } bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* expr) { - if (auto* a = expr->As<ast::IndexAccessorExpression>()) { - return EmitIndexAccessor(out, a); + if (auto* sem = builder_.Sem().Get(expr)) { + if (auto constant = sem->ConstantValue()) { + return EmitConstant(out, constant); + } } - if (auto* b = expr->As<ast::BinaryExpression>()) { - return EmitBinary(out, b); - } - if (auto* b = expr->As<ast::BitcastExpression>()) { - return EmitBitcast(out, b); - } - if (auto* c = expr->As<ast::CallExpression>()) { - return EmitCall(out, c); - } - if (auto* i = expr->As<ast::IdentifierExpression>()) { - return EmitIdentifier(out, i); - } - if (auto* l = expr->As<ast::LiteralExpression>()) { - return EmitLiteral(out, l); - } - if (auto* m = expr->As<ast::MemberAccessorExpression>()) { - return EmitMemberAccessor(out, m); - } - if (auto* u = expr->As<ast::UnaryOpExpression>()) { - return EmitUnaryOp(out, u); - } - - diagnostics_.add_error(diag::System::Writer, - "unknown expression type: " + std::string(expr->TypeInfo().name)); - return false; + return Switch( + expr, + [&](const ast::IndexAccessorExpression* a) { // + return EmitIndexAccessor(out, a); + }, + [&](const ast::BinaryExpression* b) { // + return EmitBinary(out, b); + }, + [&](const ast::BitcastExpression* b) { // + return EmitBitcast(out, b); + }, + [&](const ast::CallExpression* c) { // + return EmitCall(out, c); + }, + [&](const ast::IdentifierExpression* i) { // + return EmitIdentifier(out, i); + }, + [&](const ast::LiteralExpression* l) { // + return EmitLiteral(out, l); + }, + [&](const ast::MemberAccessorExpression* m) { // + return EmitMemberAccessor(out, m); + }, + [&](const ast::UnaryOpExpression* u) { // + return EmitUnaryOp(out, u); + }, + [&](Default) { // + diagnostics_.add_error(diag::System::Writer, "unknown expression type: " + + std::string(expr->TypeInfo().name)); + return false; + }); } bool GeneratorImpl::EmitIdentifier(std::ostream& out, const ast::IdentifierExpression* expr) { @@ -2175,6 +2207,94 @@ return true; } +bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant& constant) { + auto emit_bool = [&](size_t element_idx) { + out << (constant.Element<AInt>(element_idx) ? "true" : "false"); + return true; + }; + auto emit_f32 = [&](size_t element_idx) { + PrintF32(out, static_cast<float>(constant.Element<AFloat>(element_idx))); + return true; + }; + auto emit_i32 = [&](size_t element_idx) { + out << constant.Element<AInt>(element_idx).value; + return true; + }; + auto emit_u32 = [&](size_t element_idx) { + out << constant.Element<AInt>(element_idx).value << "u"; + return true; + }; + auto emit_vector = [&](const sem::Vector* vec_ty, size_t start, size_t end) { + if (!EmitType(out, vec_ty, ast::StorageClass::kNone, ast::Access::kUndefined, "")) { + return false; + } + + ScopedParen sp(out); + + auto emit_els = [&](auto emit_el) { + if (constant.AllEqual(start, end)) { + return emit_el(start); + } + for (size_t i = start; i < end; i++) { + if (i > start) { + out << ", "; + } + if (!emit_el(i)) { + return false; + } + } + return true; + }; + + return Switch( + vec_ty->type(), // + [&](const sem::Bool*) { return emit_els(emit_bool); }, // + [&](const sem::F32*) { return emit_els(emit_f32); }, // + [&](const sem::I32*) { return emit_els(emit_i32); }, // + [&](const sem::U32*) { return emit_els(emit_u32); }, // + [&](Default) { + diagnostics_.add_error(diag::System::Writer, + "unhandled constant vector element type: " + + builder_.FriendlyName(vec_ty->type())); + return false; + }); + }; + auto emit_matrix = [&](const sem::Matrix* m) { + if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined, + "")) { + return false; + } + + ScopedParen sp(out); + + for (size_t column_idx = 0; column_idx < m->columns(); column_idx++) { + if (column_idx > 0) { + out << ", "; + } + size_t start = m->rows() * column_idx; + size_t end = m->rows() * (column_idx + 1); + if (!emit_vector(m->ColumnType(), start, end)) { + return false; + } + } + return true; + }; + return Switch( + constant.Type(), // + [&](const sem::Bool*) { return emit_bool(0); }, // + [&](const sem::F32*) { return emit_f32(0); }, // + [&](const sem::I32*) { return emit_i32(0); }, // + [&](const sem::U32*) { return emit_u32(0); }, // + [&](const sem::Vector* v) { return emit_vector(v, 0, constant.ElementCount()); }, // + [&](const sem::Matrix* m) { return emit_matrix(m); }, // + [&](Default) { + diagnostics_.add_error( + diag::System::Writer, + "unhandled constant type: " + builder_.FriendlyName(constant.Type())); + return false; + }); +} + bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression* lit) { return Switch( lit, @@ -2183,15 +2303,7 @@ return true; }, [&](const ast::FloatLiteralExpression* l) { - auto f32 = static_cast<float>(l->value); - if (std::isinf(f32)) { - out << (l->value >= 0 ? "uintBitsToFloat(0x7f800000u)" - : "uintBitsToFloat(0xff800000u)"); - } else if (std::isnan(l->value)) { - out << "uintBitsToFloat(0x7fc00000u)"; - } else { - out << FloatToString(f32) << "f"; - } + PrintF32(out, static_cast<float>(l->value)); return true; }, [&](const ast::IntLiteralExpression* l) {
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h index 72def34..bcf84b0 100644 --- a/src/tint/writer/glsl/generator_impl.h +++ b/src/tint/writer/glsl/generator_impl.h
@@ -42,6 +42,7 @@ // Forward declarations namespace tint::sem { class Call; +class Constant; class Builtin; class TypeConstructor; class TypeConversion; @@ -174,14 +175,6 @@ /// @param builtin the semantic information for the barrier builtin /// @returns true if the call expression is emitted bool EmitBarrierCall(std::ostream& out, const sem::Builtin* builtin); - /// Handles generating an atomic intrinsic call for a storage buffer variable - /// @param out the output of the expression stream - /// @param expr the call expression - /// @param intrinsic the atomic intrinsic - /// @returns true if the call expression is emitted - bool EmitStorageAtomicCall(std::ostream& out, - const ast::CallExpression* expr, - const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); /// Handles generating an atomic builtin call for a workgroup variable /// @param out the output of the expression stream /// @param expr the call expression @@ -346,6 +339,11 @@ /// @param stmt the statement to emit /// @returns true if the statement was successfully emitted bool EmitIf(const ast::IfStatement* stmt); + /// Handles a constant value + /// @param out the output stream + /// @param constant the constant value to emit + /// @returns true if the constant value was successfully emitted + bool EmitConstant(std::ostream& out, const sem::Constant& constant); /// Handles a literal /// @param out the output stream /// @param lit the literal to emit
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc index 07456d9..0d019a9 100644 --- a/src/tint/writer/glsl/generator_impl_binary_test.cc +++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -134,9 +134,7 @@ std::stringstream out; EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); - EXPECT_EQ(out.str(), - "(vec3(1.0f, 1.0f, 1.0f) * " - "1.0f)"); + EXPECT_EQ(out.str(), "(vec3(1.0f) * 1.0f)"); } TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarVector) { @@ -151,9 +149,7 @@ std::stringstream out; EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); - EXPECT_EQ(out.str(), - "(1.0f * vec3(1.0f, 1.0f, " - "1.0f))"); + EXPECT_EQ(out.str(), "(1.0f * vec3(1.0f))"); } TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar) { @@ -198,7 +194,7 @@ std::stringstream out; EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); - EXPECT_EQ(out.str(), "(mat * vec3(1.0f, 1.0f, 1.0f))"); + EXPECT_EQ(out.str(), "(mat * vec3(1.0f))"); } TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix) { @@ -213,7 +209,7 @@ std::stringstream out; EXPECT_TRUE(gen.EmitExpression(out, expr)) << gen.error(); - EXPECT_EQ(out.str(), "(vec3(1.0f, 1.0f, 1.0f) * mat)"); + EXPECT_EQ(out.str(), "(vec3(1.0f) * mat)"); } TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix) {
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc index 7942ed5..6f2c555 100644 --- a/src/tint/writer/glsl/generator_impl_builtin_test.cc +++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -334,7 +334,7 @@ void test_function() { - tint_modf(vec3(0.0f, 0.0f, 0.0f)); + tint_modf(vec3(0.0f)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; @@ -394,7 +394,7 @@ void test_function() { - tint_frexp(vec3(0.0f, 0.0f, 0.0f)); + tint_frexp(vec3(0.0f)); } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
diff --git a/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc b/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc index cb111ee..42db16b 100644 --- a/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc +++ b/src/tint/writer/glsl/generator_impl_builtin_texture_test.cc
@@ -193,7 +193,7 @@ case ValidTextureOverload::kSampleGrad2dF32: return R"(textureGrad(tint_symbol_sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f));)"; case ValidTextureOverload::kSampleGrad2dOffsetF32: - return R"(textureGradOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7, 7));)"; + return R"(textureGradOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), vec2(3.0f, 4.0f), vec2(5.0f, 6.0f), ivec2(7));)"; case ValidTextureOverload::kSampleGrad2dArrayF32: return R"(textureGrad(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), vec2(4.0f, 5.0f), vec2(6.0f, 7.0f));)"; case ValidTextureOverload::kSampleGrad2dArrayOffsetF32:
diff --git a/src/tint/writer/glsl/generator_impl_cast_test.cc b/src/tint/writer/glsl/generator_impl_cast_test.cc index 3666782..c4f9c05 100644 --- a/src/tint/writer/glsl/generator_impl_cast_test.cc +++ b/src/tint/writer/glsl/generator_impl_cast_test.cc
@@ -29,7 +29,7 @@ std::stringstream out; ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error(); - EXPECT_EQ(out.str(), "float(1)"); + EXPECT_EQ(out.str(), "1.0f"); } TEST_F(GlslGeneratorImplTest_Cast, EmitExpression_Cast_Vector) { @@ -40,7 +40,7 @@ std::stringstream out; ASSERT_TRUE(gen.EmitExpression(out, cast)) << gen.error(); - EXPECT_EQ(out.str(), "vec3(ivec3(1, 2, 3))"); + EXPECT_EQ(out.str(), "vec3(1.0f, 2.0f, 3.0f)"); } } // namespace
diff --git a/src/tint/writer/glsl/generator_impl_constructor_test.cc b/src/tint/writer/glsl/generator_impl_constructor_test.cc index 4fa3c0a..e70ecaf 100644 --- a/src/tint/writer/glsl/generator_impl_constructor_test.cc +++ b/src/tint/writer/glsl/generator_impl_constructor_test.cc
@@ -67,7 +67,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("float(-0.000012f)")); + EXPECT_THAT(gen.result(), HasSubstr("-0.000012f")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Bool) { @@ -76,7 +76,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("bool(true)")); + EXPECT_THAT(gen.result(), HasSubstr("true")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Int) { @@ -85,7 +85,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("int(-12345)")); + EXPECT_THAT(gen.result(), HasSubstr("-12345")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) { @@ -94,7 +94,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("uint(12345u)")); + EXPECT_THAT(gen.result(), HasSubstr("12345u")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec) { @@ -112,7 +112,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("vec3(0.0f, 0.0f, 0.0f)")); + EXPECT_THAT(gen.result(), HasSubstr("vec3(0.0f)")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Float) { @@ -168,7 +168,7 @@ ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("mat2x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)")); + EXPECT_THAT(gen.result(), HasSubstr("mat2x3(vec3(0.0f), vec3(0.0f)")); } TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) {
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc index f352415..201e757 100644 --- a/src/tint/writer/glsl/generator_impl_function_test.cc +++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -222,7 +222,7 @@ }; Interface vert_main() { - Interface tint_symbol = Interface(vec4(0.0f, 0.0f, 0.0f, 0.0f), 0.5f, 0.25f); + Interface tint_symbol = Interface(vec4(0.0f), 0.5f, 0.25f); return tint_symbol; } @@ -789,9 +789,9 @@ ASSERT_TRUE(gen.Generate()) << gen.error(); EXPECT_EQ(gen.result(), R"(#version 310 es -const int width = int(2); -const int height = int(3); -const int depth = int(4); +const int width = 2; +const int height = 3; +const int depth = 4; layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in; void main() { return; @@ -816,15 +816,15 @@ EXPECT_EQ(gen.result(), R"(#version 310 es #ifndef WGSL_SPEC_CONSTANT_7 -#define WGSL_SPEC_CONSTANT_7 int(2) +#define WGSL_SPEC_CONSTANT_7 2 #endif const int width = WGSL_SPEC_CONSTANT_7; #ifndef WGSL_SPEC_CONSTANT_8 -#define WGSL_SPEC_CONSTANT_8 int(3) +#define WGSL_SPEC_CONSTANT_8 3 #endif const int height = WGSL_SPEC_CONSTANT_8; #ifndef WGSL_SPEC_CONSTANT_9 -#define WGSL_SPEC_CONSTANT_9 int(4) +#define WGSL_SPEC_CONSTANT_9 4 #endif const int depth = WGSL_SPEC_CONSTANT_9; layout(local_size_x = WGSL_SPEC_CONSTANT_7, local_size_y = WGSL_SPEC_CONSTANT_8, local_size_z = WGSL_SPEC_CONSTANT_9) in;
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc index 935df75..4f7fdb1 100644 --- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc +++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -291,7 +291,7 @@ mat2x3 b; } data; void tint_symbol() { - data.b = mat2x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + data.b = mat2x3(vec3(0.0f), vec3(0.0f)); } void main() {
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc index d293dba..5d95bc6 100644 --- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc +++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -98,7 +98,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error(); - EXPECT_EQ(gen.result(), R"(vec3 a = vec3(0.0f, 0.0f, 0.0f); + EXPECT_EQ(gen.result(), R"(vec3 a = vec3(0.0f); )"); } @@ -112,7 +112,7 @@ ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error(); EXPECT_EQ(gen.result(), - R"(mat2x3 a = mat2x3(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); + R"(mat2x3 a = mat2x3(vec3(0.0f), vec3(0.0f)); )"); }
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index d6a5fa7..a2cac0f 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -968,7 +968,10 @@ case ast::StorageClass::kUniform: return EmitUniformBufferAccess(out, expr, intrinsic); case ast::StorageClass::kStorage: - return EmitStorageBufferAccess(out, expr, intrinsic); + if (!intrinsic->IsAtomic()) { + return EmitStorageBufferAccess(out, expr, intrinsic); + } + break; default: TINT_UNREACHABLE(Writer, diagnostics_) << "unsupported DecomposeMemoryAccess::Intrinsic storage class:" @@ -1445,19 +1448,10 @@ << static_cast<int>(intrinsic->type); return false; } - - case Op::kAtomicLoad: - case Op::kAtomicStore: - case Op::kAtomicAdd: - case Op::kAtomicSub: - case Op::kAtomicMax: - case Op::kAtomicMin: - case Op::kAtomicAnd: - case Op::kAtomicOr: - case Op::kAtomicXor: - case Op::kAtomicExchange: - case Op::kAtomicCompareExchangeWeak: - return EmitStorageAtomicCall(out, expr, intrinsic); + default: + // Break out to error case below/ + // Note that atomic intrinsics are generated as functions. + break; } TINT_UNREACHABLE(Writer, diagnostics_) @@ -1465,32 +1459,127 @@ return false; } -bool GeneratorImpl::EmitStorageAtomicCall( - std::ostream& out, - const ast::CallExpression* expr, +bool GeneratorImpl::EmitStorageAtomicIntrinsic( + const ast::Function* func, const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) { using Op = transform::DecomposeMemoryAccess::Intrinsic::Op; - auto* result_ty = TypeOf(expr); + const sem::Function* sem_func = builder_.Sem().Get(func); + auto* result_ty = sem_func->ReturnType(); + const auto& params = sem_func->Parameters(); + const auto name = builder_.Symbols().NameFor(func->symbol); + auto& buf = *current_buffer_; - auto& buf = helpers_; + auto rmw = [&](const char* hlsl) -> bool { + { + auto fn = line(&buf); + if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined, + name)) { + return false; + } + fn << "(RWByteAddressBuffer buffer, uint offset, "; + if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined, + "value")) { + return false; + } + fn << ") {"; + } - // generate_helper() generates a helper function that translates the - // DecomposeMemoryAccess::Intrinsic call into the corresponding HLSL - // atomic intrinsic function. - auto generate_helper = [&]() -> std::string { - auto rmw = [&](const char* wgsl, const char* hlsl) -> std::string { - auto name = UniqueIdentifier(wgsl); + buf.IncrementIndent(); + TINT_DEFER({ + buf.DecrementIndent(); + line(&buf) << "}"; + line(&buf); + }); + + { + auto l = line(&buf); + if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined, + "original_value")) { + return false; + } + l << " = 0;"; + } + { + auto l = line(&buf); + l << "buffer." << hlsl << "(offset, "; + if (intrinsic->op == Op::kAtomicSub) { + l << "-"; + } + l << "value, original_value);"; + } + line(&buf) << "return original_value;"; + return true; + }; + + switch (intrinsic->op) { + case Op::kAtomicAdd: + return rmw("InterlockedAdd"); + + case Op::kAtomicSub: + // Use add with the operand negated. + return rmw("InterlockedAdd"); + + case Op::kAtomicMax: + return rmw("InterlockedMax"); + + case Op::kAtomicMin: + return rmw("InterlockedMin"); + + case Op::kAtomicAnd: + return rmw("InterlockedAnd"); + + case Op::kAtomicOr: + return rmw("InterlockedOr"); + + case Op::kAtomicXor: + return rmw("InterlockedXor"); + + case Op::kAtomicExchange: + return rmw("InterlockedExchange"); + + case Op::kAtomicLoad: { + // HLSL does not have an InterlockedLoad, so we emulate it with + // InterlockedOr using 0 as the OR value { auto fn = line(&buf); if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined, name)) { - return ""; + return false; } - fn << "(RWByteAddressBuffer buffer, uint offset, "; - if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, + fn << "(RWByteAddressBuffer buffer, uint offset) {"; + } + + buf.IncrementIndent(); + TINT_DEFER({ + buf.DecrementIndent(); + line(&buf) << "}"; + line(&buf); + }); + + { + auto l = line(&buf); + if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined, "value")) { - return ""; + return false; + } + l << " = 0;"; + } + + line(&buf) << "buffer.InterlockedOr(offset, 0, value);"; + line(&buf) << "return value;"; + return true; + } + case Op::kAtomicStore: { + // HLSL does not have an InterlockedStore, so we emulate it with + // InterlockedExchange and discard the returned value + auto* value_ty = params[2]->Type()->UnwrapRef(); + { + auto fn = line(&buf); + fn << "void " << name << "(RWByteAddressBuffer buffer, uint offset, "; + if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, + ast::Access::kUndefined, "value")) { + return false; } fn << ") {"; } @@ -1504,191 +1593,73 @@ { auto l = line(&buf); - if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "original_value")) { - return ""; + if (!EmitTypeAndName(l, value_ty, ast::StorageClass::kNone, ast::Access::kUndefined, + "ignored")) { + return false; } - l << " = 0;"; + l << ";"; } + line(&buf) << "buffer.InterlockedExchange(offset, value, ignored);"; + return true; + } + case Op::kAtomicCompareExchangeWeak: { + // NOTE: We don't need to emit the return type struct here as DecomposeMemoryAccess + // already added it to the AST, and it should have already been emitted by now. + auto* value_ty = params[2]->Type()->UnwrapRef(); { + auto fn = line(&buf); + if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, + ast::Access::kUndefined, name)) { + return false; + } + fn << "(RWByteAddressBuffer buffer, uint offset, "; + if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, + ast::Access::kUndefined, "compare")) { + return false; + } + fn << ", "; + if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, + ast::Access::kUndefined, "value")) { + return false; + } + fn << ") {"; + } + + buf.IncrementIndent(); + TINT_DEFER({ + buf.DecrementIndent(); + line(&buf) << "}"; + line(&buf); + }); + + { // T result = {0}; auto l = line(&buf); - l << "buffer." << hlsl << "(offset, "; - if (intrinsic->op == Op::kAtomicSub) { - l << "-"; + if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, + ast::Access::kUndefined, "result")) { + return false; } - l << "value, original_value);"; + l << "="; + if (!EmitZeroValue(l, result_ty)) { + return false; + } + l << ";"; } - line(&buf) << "return original_value;"; - return name; - }; - switch (intrinsic->op) { - case Op::kAtomicAdd: - return rmw("atomicAdd", "InterlockedAdd"); + line(&buf) << "buffer.InterlockedCompareExchange(offset, compare, value, " + "result.old_value);"; + line(&buf) << "result.exchanged = result.old_value == compare;"; + line(&buf) << "return result;"; - case Op::kAtomicSub: - // Use add with the operand negated. - return rmw("atomicSub", "InterlockedAdd"); - - case Op::kAtomicMax: - return rmw("atomicMax", "InterlockedMax"); - - case Op::kAtomicMin: - return rmw("atomicMin", "InterlockedMin"); - - case Op::kAtomicAnd: - return rmw("atomicAnd", "InterlockedAnd"); - - case Op::kAtomicOr: - return rmw("atomicOr", "InterlockedOr"); - - case Op::kAtomicXor: - return rmw("atomicXor", "InterlockedXor"); - - case Op::kAtomicExchange: - return rmw("atomicExchange", "InterlockedExchange"); - - case Op::kAtomicLoad: { - // HLSL does not have an InterlockedLoad, so we emulate it with - // InterlockedOr using 0 as the OR value - auto name = UniqueIdentifier("atomicLoad"); - { - auto fn = line(&buf); - if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, name)) { - return ""; - } - fn << "(RWByteAddressBuffer buffer, uint offset) {"; - } - - buf.IncrementIndent(); - TINT_DEFER({ - buf.DecrementIndent(); - line(&buf) << "}"; - line(&buf); - }); - - { - auto l = line(&buf); - if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "value")) { - return ""; - } - l << " = 0;"; - } - - line(&buf) << "buffer.InterlockedOr(offset, 0, value);"; - line(&buf) << "return value;"; - return name; - } - case Op::kAtomicStore: { - // HLSL does not have an InterlockedStore, so we emulate it with - // InterlockedExchange and discard the returned value - auto* value_ty = TypeOf(expr->args[2])->UnwrapRef(); - auto name = UniqueIdentifier("atomicStore"); - { - auto fn = line(&buf); - fn << "void " << name << "(RWByteAddressBuffer buffer, uint offset, "; - if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "value")) { - return ""; - } - fn << ") {"; - } - - buf.IncrementIndent(); - TINT_DEFER({ - buf.DecrementIndent(); - line(&buf) << "}"; - line(&buf); - }); - - { - auto l = line(&buf); - if (!EmitTypeAndName(l, value_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "ignored")) { - return ""; - } - l << ";"; - } - line(&buf) << "buffer.InterlockedExchange(offset, value, ignored);"; - return name; - } - case Op::kAtomicCompareExchangeWeak: { - auto* value_ty = TypeOf(expr->args[2])->UnwrapRef(); - - auto name = UniqueIdentifier("atomicCompareExchangeWeak"); - { - auto fn = line(&buf); - if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, name)) { - return ""; - } - fn << "(RWByteAddressBuffer buffer, uint offset, "; - if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "compare")) { - return ""; - } - fn << ", "; - if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "value")) { - return ""; - } - fn << ") {"; - } - - buf.IncrementIndent(); - TINT_DEFER({ - buf.DecrementIndent(); - line(&buf) << "}"; - line(&buf); - }); - - { // T result = {0, 0}; - auto l = line(&buf); - if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, - ast::Access::kUndefined, "result")) { - return ""; - } - l << " = {0, 0};"; - } - line(&buf) << "buffer.InterlockedCompareExchange(offset, compare, " - "value, result.x);"; - line(&buf) << "result.y = result.x == compare;"; - line(&buf) << "return result;"; - return name; - } - default: - break; + return true; } - TINT_UNREACHABLE(Writer, diagnostics_) - << "unsupported atomic DecomposeMemoryAccess::Intrinsic::Op: " - << static_cast<int>(intrinsic->op); - return ""; - }; - - auto func = utils::GetOrCreate(dma_intrinsics_, DMAIntrinsic{intrinsic->op, intrinsic->type}, - generate_helper); - if (func.empty()) { - return false; + default: + break; } - out << func; - { - ScopedParen sp(out); - bool first = true; - for (auto* arg : expr->args) { - if (!first) { - out << ", "; - } - first = false; - if (!EmitExpression(out, arg)) { - return false; - } - } - } - - return true; + TINT_UNREACHABLE(Writer, diagnostics_) + << "unsupported atomic DecomposeMemoryAccess::Intrinsic::Op: " + << static_cast<int>(intrinsic->op); + return false; } bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out, @@ -1788,6 +1759,12 @@ return true; } case sem::BuiltinType::kAtomicCompareExchangeWeak: { + // Emit the builtin return type unique to this overload. This does not + // exist in the AST, so it will not be generated in Generate(). + if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) { + return false; + } + auto* dest = expr->args[0]; auto* compare_value = expr->args[1]; auto* value = expr->args[2]; @@ -1807,7 +1784,7 @@ pre << ";"; } - { // InterlockedCompareExchange(dst, compare, value, result.x); + { // InterlockedCompareExchange(dst, compare, value, result.old_value); auto pre = line(); pre << "InterlockedCompareExchange"; { @@ -1819,14 +1796,13 @@ if (!EmitExpression(pre, value)) { return false; } - pre << ", " << result << ".x"; + pre << ", " << result << ".old_value"; } pre << ";"; } - { // result.y = result.x == compare; - line() << result << ".y = " << result << ".x == " << compare << ";"; - } + // result.exchanged = result.old_value == compare; + line() << result << ".exchanged = " << result << ".old_value == " << compare << ";"; out << result; return true; @@ -2740,6 +2716,17 @@ bool GeneratorImpl::EmitFunction(const ast::Function* func) { auto* sem = builder_.Sem().Get(func); + // Emit storage atomic helpers + if (auto* intrinsic = + ast::GetAttribute<transform::DecomposeMemoryAccess::Intrinsic>(func->attributes)) { + if (intrinsic->storage_class == ast::StorageClass::kStorage && intrinsic->IsAtomic()) { + if (!EmitStorageAtomicIntrinsic(func, intrinsic)) { + return false; + } + } + return true; + } + if (ast::HasAttribute<ast::InternalAttribute>(func->attributes)) { // An internal function. Do not emit. return true; @@ -3755,13 +3742,9 @@ ScopedIndent si(b); for (auto* mem : str->Members()) { auto mem_name = builder_.Symbols().NameFor(mem->Name()); - auto* ty = mem->Type(); - auto out = line(b); - std::string pre, post; - if (auto* decl = mem->Declaration()) { for (auto* attr : decl->attributes) { if (auto* location = attr->As<ast::LocationAttribute>()) { @@ -3826,7 +3809,6 @@ } line(b) << "};"; - return true; }
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h index 86bbd7d..0e8ca4c 100644 --- a/src/tint/writer/hlsl/generator_impl.h +++ b/src/tint/writer/hlsl/generator_impl.h
@@ -187,6 +187,12 @@ bool EmitStorageAtomicCall(std::ostream& out, const ast::CallExpression* expr, const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); + /// Handles generating the helper function for the atomic intrinsic function + /// @param func the function + /// @param intrinsic the atomic intrinsic + /// @returns true if the function is emitted + bool EmitStorageAtomicIntrinsic(const ast::Function* func, + const transform::DecomposeMemoryAccess::Intrinsic* intrinsic); /// Handles generating an atomic intrinsic call for a workgroup variable /// @param out the output of the expression stream /// @param expr the call expression @@ -511,7 +517,6 @@ TextBuffer helpers_; // Helper functions emitted at the top of the output std::function<bool()> emit_continuing_; - std::unordered_map<DMAIntrinsic, std::string, DMAIntrinsic::Hasher> dma_intrinsics_; std::unordered_map<const sem::Matrix*, std::string> matrix_scalar_ctors_; std::unordered_map<const sem::Builtin*, std::string> builtins_; std::unordered_map<const sem::Struct*, std::string> structure_builders_;
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc index 54d9164..578e78d 100644 --- a/src/tint/writer/msl/generator_impl.cc +++ b/src/tint/writer/msl/generator_impl.cc
@@ -806,6 +806,12 @@ return call("atomic_exchange_explicit", true); case sem::BuiltinType::kAtomicCompareExchangeWeak: { + // Emit the builtin return type unique to this overload. This does not + // exist in the AST, so it will not be generated in Generate(). + if (!EmitStructType(&helpers_, builtin->ReturnType()->As<sem::Struct>())) { + return false; + } + auto* ptr_ty = TypeOf(expr->args[0])->UnwrapRef()->As<sem::Pointer>(); auto sc = ptr_ty->StorageClass(); @@ -816,7 +822,8 @@ line(&buf) << "template <typename A, typename T>"; { auto f = line(&buf); - f << "vec<T, 2> " << name << "("; + auto str_name = StructName(builtin->ReturnType()->As<sem::Struct>()); + f << str_name << " " << name << "("; if (!EmitStorageClass(f, sc)) { return ""; } @@ -830,12 +837,12 @@ line(&buf); }); - line(&buf) << "T prev_value = compare;"; - line(&buf) << "bool matched = " + line(&buf) << "T old_value = compare;"; + line(&buf) << "bool exchanged = " "atomic_compare_exchange_weak_explicit(atomic, " - "&prev_value, value, memory_order_relaxed, " + "&old_value, value, memory_order_relaxed, " "memory_order_relaxed);"; - line(&buf) << "return {prev_value, matched};"; + line(&buf) << "return {old_value, exchanged};"; return name; });
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index e2d1fac..34d550b 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc
@@ -3161,7 +3161,7 @@ return false; } - auto* value_sem_type = TypeOf(call->Arguments()[2]->Declaration()); + auto* value_sem_type = call->Target()->Signature().parameters[2]->Type(); auto value_type = GenerateTypeIfNeeded(value_sem_type); if (value_type == 0) { @@ -3201,42 +3201,12 @@ return false; } - // zero := T(0) - // one := T(1) - uint32_t zero = 0; - uint32_t one = 0; - if (value_sem_type->Is<sem::I32>()) { - zero = GenerateConstantIfNeeded(ScalarConstant::I32(0u)); - one = GenerateConstantIfNeeded(ScalarConstant::I32(1u)); - } else if (value_sem_type->Is<sem::U32>()) { - zero = GenerateConstantIfNeeded(ScalarConstant::U32(0u)); - one = GenerateConstantIfNeeded(ScalarConstant::U32(1u)); - } else { - TINT_UNREACHABLE(Writer, builder_.Diagnostics()) - << "unsupported atomic type " << value_sem_type->TypeInfo().name; - } - if (zero == 0 || one == 0) { - return false; - } - - // xchg_success := values_equal ? one : zero - auto xchg_success = result_op(); - if (!push_function_inst(spv::Op::OpSelect, { - Operand(value_type), - xchg_success, - values_equal, - Operand(one), - Operand(zero), - })) { - return false; - } - - // result := vec2<T>(original_value, xchg_success) + // result := __atomic_compare_exchange_result<T>(original_value, values_equal) return push_function_inst(spv::Op::OpCompositeConstruct, { result_type, result_id, original_value, - xchg_success, + values_equal, }); } default:
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc index 59a567a..7340074 100644 --- a/src/tint/writer/spirv/builder_builtin_test.cc +++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -2018,15 +2018,15 @@ TEST_F(BuiltinBuilderTest, Call_AtomicCompareExchangeWeak) { // struct S { - // u : atomic<u32>; - // i : atomic<i32>; + // u : atomic<u32>, + // i : atomic<i32>, // } // // @binding(1) @group(2) var<storage, read_write> b : S; // // fn a_func() { - // let u : vec2<u32> = atomicCompareExchangeWeak(&b.u, 10u); - // let i : vec2<i32> = atomicCompareExchangeWeak(&b.i, 10); + // let u = atomicCompareExchangeWeak(&b.u, 10u, 20u); + // let i = atomicCompareExchangeWeak(&b.i, 10, 10); // } auto* s = Structure("S", { Member("u", ty.atomic<u32>()), @@ -2040,10 +2040,10 @@ Func("a_func", {}, ty.void_(), ast::StatementList{ - Decl(Let("u", ty.vec2<u32>(), + Decl(Let("u", nullptr, Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "u")), 10_u, 20_u))), - Decl(Let("i", ty.vec2<i32>(), + Decl(Let("i", nullptr, Call("atomicCompareExchangeWeak", AddressOf(MemberAccessor("b", "i")), 10_i, 20_i))), }, @@ -2062,33 +2062,29 @@ %1 = OpVariable %2 StorageBuffer %7 = OpTypeVoid %6 = OpTypeFunction %7 -%11 = OpTypeVector %4 2 -%12 = OpConstant %4 1 -%13 = OpConstant %4 0 -%15 = OpTypePointer StorageBuffer %4 -%17 = OpConstant %4 20 -%18 = OpConstant %4 10 -%19 = OpTypeBool -%24 = OpTypeVector %5 2 -%26 = OpTypePointer StorageBuffer %5 -%28 = OpConstant %5 20 -%29 = OpConstant %5 10 -%32 = OpConstant %5 0 -%33 = OpConstant %5 1 +%12 = OpTypeBool +%11 = OpTypeStruct %4 %12 +%13 = OpConstant %4 1 +%14 = OpConstant %4 0 +%16 = OpTypePointer StorageBuffer %4 +%18 = OpConstant %4 20 +%19 = OpConstant %4 10 +%23 = OpTypeStruct %5 %12 +%25 = OpTypePointer StorageBuffer %5 +%27 = OpConstant %5 20 +%28 = OpConstant %5 10 )"; auto got_types = DumpInstructions(b.types()); EXPECT_EQ(expected_types, got_types); - auto* expected_instructions = R"(%16 = OpAccessChain %15 %1 %13 -%20 = OpAtomicCompareExchange %4 %16 %12 %13 %13 %17 %18 -%21 = OpIEqual %19 %20 %17 -%22 = OpSelect %4 %21 %12 %13 -%10 = OpCompositeConstruct %11 %20 %22 -%27 = OpAccessChain %26 %1 %12 -%30 = OpAtomicCompareExchange %5 %27 %12 %13 %13 %28 %29 -%31 = OpIEqual %19 %30 %28 -%34 = OpSelect %5 %31 %33 %32 -%23 = OpCompositeConstruct %24 %30 %34 + auto* expected_instructions = R"(%17 = OpAccessChain %16 %1 %14 +%20 = OpAtomicCompareExchange %4 %17 %13 %14 %14 %18 %19 +%21 = OpIEqual %12 %20 %18 +%10 = OpCompositeConstruct %11 %20 %21 +%26 = OpAccessChain %25 %1 %13 +%29 = OpAtomicCompareExchange %5 %26 %13 %14 %14 %27 %28 +%30 = OpIEqual %12 %29 %27 +%22 = OpCompositeConstruct %23 %29 %30 OpReturn )"; auto got_instructions = DumpInstructions(b.functions()[0].instructions());
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc index 677421d..c71cd49 100644 --- a/src/tint/writer/wgsl/generator_impl.cc +++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -258,7 +258,7 @@ return true; }, [&](const ast::FloatLiteralExpression* l) { // - out << FloatToBitPreservingString(static_cast<float>(l->value)); + out << FloatToBitPreservingString(static_cast<float>(l->value)) << l->suffix; return true; }, [&](const ast::IntLiteralExpression* l) { //
diff --git a/src/tint/writer/wgsl/generator_impl_constructor_test.cc b/src/tint/writer/wgsl/generator_impl_constructor_test.cc index 7a147c2..ae9f2b7 100644 --- a/src/tint/writer/wgsl/generator_impl_constructor_test.cc +++ b/src/tint/writer/wgsl/generator_impl_constructor_test.cc
@@ -58,7 +58,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("1073741824.0")); + EXPECT_THAT(gen.result(), HasSubstr("1073741824.0f")); } TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Float) { @@ -67,7 +67,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("f32(-0.000012)")); + EXPECT_THAT(gen.result(), HasSubstr("f32(-0.000012f)")); } TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Bool) { @@ -103,7 +103,7 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("vec3<f32>(1.0, 2.0, 3.0)")); + EXPECT_THAT(gen.result(), HasSubstr("vec3<f32>(1.0f, 2.0f, 3.0f)")); } TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Mat) { @@ -112,8 +112,8 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("mat2x3<f32>(vec3<f32>(1.0, 2.0, 3.0), " - "vec3<f32>(3.0, 4.0, 5.0))")); + EXPECT_THAT(gen.result(), HasSubstr("mat2x3<f32>(vec3<f32>(1.0f, 2.0f, 3.0f), " + "vec3<f32>(3.0f, 4.0f, 5.0f))")); } TEST_F(WgslGeneratorImplTest, EmitConstructor_Type_Array) { @@ -123,8 +123,9 @@ GeneratorImpl& gen = Build(); ASSERT_TRUE(gen.Generate()) << gen.error(); - EXPECT_THAT(gen.result(), HasSubstr("array<vec3<f32>, 3u>(vec3<f32>(1.0, 2.0, 3.0), " - "vec3<f32>(4.0, 5.0, 6.0), vec3<f32>(7.0, 8.0, 9.0))")); + EXPECT_THAT(gen.result(), + HasSubstr("array<vec3<f32>, 3u>(vec3<f32>(1.0f, 2.0f, 3.0f), " + "vec3<f32>(4.0f, 5.0f, 6.0f), vec3<f32>(7.0f, 8.0f, 9.0f))")); } } // namespace
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc index da91948..4c43a59 100644 --- a/src/tint/writer/wgsl/generator_impl_function_test.cc +++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -139,7 +139,7 @@ ASSERT_TRUE(gen.EmitFunction(func)); EXPECT_EQ(gen.result(), R"( @stage(fragment) fn frag_main() -> @location(1) f32 { - return 1.0; + return 1.0f; } )"); }
diff --git a/src/tint/writer/wgsl/generator_impl_literal_test.cc b/src/tint/writer/wgsl/generator_impl_literal_test.cc index 353bd36..dd715d4 100644 --- a/src/tint/writer/wgsl/generator_impl_literal_test.cc +++ b/src/tint/writer/wgsl/generator_impl_literal_test.cc
@@ -64,36 +64,37 @@ INSTANTIATE_TEST_SUITE_P(Zero, WgslGenerator_FloatLiteralTest, - ::testing::ValuesIn(std::vector<FloatData>{{0_f, "0.0"}, - {MakeFloat(0, 0, 0), "0.0"}, - {MakeFloat(1, 0, 0), "-0.0"}})); + ::testing::ValuesIn(std::vector<FloatData>{ + {0_f, "0.0f"}, + {MakeFloat(0, 0, 0), "0.0f"}, + {MakeFloat(1, 0, 0), "-0.0f"}})); INSTANTIATE_TEST_SUITE_P(Normal, WgslGenerator_FloatLiteralTest, - ::testing::ValuesIn(std::vector<FloatData>{{1_f, "1.0"}, - {-1_f, "-1.0"}, - {101.375_f, "101.375"}})); + ::testing::ValuesIn(std::vector<FloatData>{{1_f, "1.0f"}, + {-1_f, "-1.0f"}, + {101.375_f, "101.375f"}})); INSTANTIATE_TEST_SUITE_P(Subnormal, WgslGenerator_FloatLiteralTest, ::testing::ValuesIn(std::vector<FloatData>{ - {MakeFloat(0, 0, 1), "0x1p-149"}, // Smallest - {MakeFloat(1, 0, 1), "-0x1p-149"}, - {MakeFloat(0, 0, 2), "0x1p-148"}, - {MakeFloat(1, 0, 2), "-0x1p-148"}, - {MakeFloat(0, 0, 0x7fffff), "0x1.fffffcp-127"}, // Largest - {MakeFloat(1, 0, 0x7fffff), "-0x1.fffffcp-127"}, // Largest - {MakeFloat(0, 0, 0xcafebe), "0x1.2bfaf8p-127"}, // Scattered bits - {MakeFloat(1, 0, 0xcafebe), "-0x1.2bfaf8p-127"}, // Scattered bits - {MakeFloat(0, 0, 0xaaaaa), "0x1.55554p-130"}, // Scattered bits - {MakeFloat(1, 0, 0xaaaaa), "-0x1.55554p-130"}, // Scattered bits + {MakeFloat(0, 0, 1), "0x1p-149f"}, // Smallest + {MakeFloat(1, 0, 1), "-0x1p-149f"}, + {MakeFloat(0, 0, 2), "0x1p-148f"}, + {MakeFloat(1, 0, 2), "-0x1p-148f"}, + {MakeFloat(0, 0, 0x7fffff), "0x1.fffffcp-127f"}, // Largest + {MakeFloat(1, 0, 0x7fffff), "-0x1.fffffcp-127f"}, // Largest + {MakeFloat(0, 0, 0xcafebe), "0x1.2bfaf8p-127f"}, // Scattered bits + {MakeFloat(1, 0, 0xcafebe), "-0x1.2bfaf8p-127f"}, // Scattered bits + {MakeFloat(0, 0, 0xaaaaa), "0x1.55554p-130f"}, // Scattered bits + {MakeFloat(1, 0, 0xaaaaa), "-0x1.55554p-130f"}, // Scattered bits })); INSTANTIATE_TEST_SUITE_P(Infinity, WgslGenerator_FloatLiteralTest, ::testing::ValuesIn(std::vector<FloatData>{ - {MakeFloat(0, 255, 0), "0x1p+128"}, - {MakeFloat(1, 255, 0), "-0x1p+128"}})); + {MakeFloat(0, 255, 0), "0x1p+128f"}, + {MakeFloat(1, 255, 0), "-0x1p+128f"}})); INSTANTIATE_TEST_SUITE_P( // TODO(dneto): It's unclear how Infinity and NaN should be handled. @@ -108,20 +109,20 @@ WgslGenerator_FloatLiteralTest, ::testing::ValuesIn(std::vector<FloatData>{ // LSB only. Smallest mantissa. - {MakeFloat(0, 255, 1), "0x1.000002p+128"}, // Smallest mantissa - {MakeFloat(1, 255, 1), "-0x1.000002p+128"}, + {MakeFloat(0, 255, 1), "0x1.000002p+128f"}, // Smallest mantissa + {MakeFloat(1, 255, 1), "-0x1.000002p+128f"}, // MSB only. - {MakeFloat(0, 255, 0x400000), "0x1.8p+128"}, - {MakeFloat(1, 255, 0x400000), "-0x1.8p+128"}, + {MakeFloat(0, 255, 0x400000), "0x1.8p+128f"}, + {MakeFloat(1, 255, 0x400000), "-0x1.8p+128f"}, // All 1s in the mantissa. - {MakeFloat(0, 255, 0x7fffff), "0x1.fffffep+128"}, - {MakeFloat(1, 255, 0x7fffff), "-0x1.fffffep+128"}, + {MakeFloat(0, 255, 0x7fffff), "0x1.fffffep+128f"}, + {MakeFloat(1, 255, 0x7fffff), "-0x1.fffffep+128f"}, // Scattered bits, with 0 in top mantissa bit. - {MakeFloat(0, 255, 0x20101f), "0x1.40203ep+128"}, - {MakeFloat(1, 255, 0x20101f), "-0x1.40203ep+128"}, + {MakeFloat(0, 255, 0x20101f), "0x1.40203ep+128f"}, + {MakeFloat(1, 255, 0x20101f), "-0x1.40203ep+128f"}, // Scattered bits, with 1 in top mantissa bit. - {MakeFloat(0, 255, 0x40101f), "0x1.80203ep+128"}, - {MakeFloat(1, 255, 0x40101f), "-0x1.80203ep+128"}})); + {MakeFloat(0, 255, 0x40101f), "0x1.80203ep+128f"}, + {MakeFloat(1, 255, 0x40101f), "-0x1.80203ep+128f"}})); } // namespace } // namespace tint::writer::wgsl
diff --git a/src/tint/writer/wgsl/generator_impl_variable_test.cc b/src/tint/writer/wgsl/generator_impl_variable_test.cc index 80f6259..83af7c2 100644 --- a/src/tint/writer/wgsl/generator_impl_variable_test.cc +++ b/src/tint/writer/wgsl/generator_impl_variable_test.cc
@@ -107,7 +107,7 @@ std::stringstream out; ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error(); - EXPECT_EQ(out.str(), R"(var<private> a : f32 = 1.0;)"); + EXPECT_EQ(out.str(), R"(var<private> a : f32 = 1.0f;)"); } TEST_F(WgslGeneratorImplTest, EmitVariable_Const) { @@ -118,7 +118,7 @@ std::stringstream out; ASSERT_TRUE(gen.EmitVariable(out, v)) << gen.error(); - EXPECT_EQ(out.str(), R"(let a : f32 = 1.0;)"); + EXPECT_EQ(out.str(), R"(let a : f32 = 1.0f;)"); } } // namespace