diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc index 6573426953..2bd74cc7b7 100644 --- a/src/tint/resolver/materialize_test.cc +++ b/src/tint/resolver/materialize_test.cc @@ -34,10 +34,44 @@ using i32V = builder::vec<3, i32>; using u32V = builder::vec<3, u32>; using f32M = builder::mat<3, 2, f32>; -//////////////////////////////////////////////////////////////////////////////// -// MaterializeTests -//////////////////////////////////////////////////////////////////////////////// -namespace MaterializeTests { +constexpr double kHighestU32 = static_cast(u32::kHighest); +constexpr double kLowestU32 = static_cast(u32::kLowest); +constexpr double kHighestI32 = static_cast(i32::kHighest); +constexpr double kLowestI32 = static_cast(i32::kLowest); +constexpr double kHighestF32 = static_cast(f32::kHighest); +constexpr double kLowestF32 = static_cast(f32::kLowest); +constexpr double kTooBigF32 = static_cast(3.5e+38); +constexpr double kPiF64 = 3.141592653589793; +constexpr double kPiF32 = 3.1415927410125732; // kPiF64 quantized to f32 + +constexpr double kSubnormalF32 = 0x1.0p-128; + +enum class Expectation { + kMaterialize, + kNoMaterialize, + kInvalidConversion, + kValueCannotBeRepresented, +}; + +static std::ostream& operator<<(std::ostream& o, Expectation m) { + switch (m) { + case Expectation::kMaterialize: + return o << "materialize"; + case Expectation::kNoMaterialize: + return o << "no-materialize"; + case Expectation::kInvalidConversion: + return o << "invalid-conversion"; + case Expectation::kValueCannotBeRepresented: + return o << "value cannot be represented"; + } + return o << ""; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// MaterializeAbstractNumericToConcreteType +// Tests that an abstract-numeric will materialize to the expected concrete type +//////////////////////////////////////////////////////////////////////////////////////////////////// +namespace materialize_abstract_numeric_to_concrete_type { // How should the materialization occur? enum class Method { @@ -188,31 +222,10 @@ static std::ostream& operator<<(std::ostream& o, const Data& c) { return o; } -enum class Expectation { - kMaterialize, - kNoMaterialize, - kInvalidCast, - kValueCannotBeRepresented, -}; - -static std::ostream& operator<<(std::ostream& o, Expectation m) { - switch (m) { - case Expectation::kMaterialize: - return o << "pass"; - case Expectation::kNoMaterialize: - return o << "no-materialize"; - case Expectation::kInvalidCast: - return o << "invalid-cast"; - case Expectation::kValueCannotBeRepresented: - return o << "value too low or high"; - } - return o << ""; -} - -using MaterializeAbstractNumeric = +using MaterializeAbstractNumericToConcreteType = resolver::ResolverTestWithParam>; -TEST_P(MaterializeAbstractNumeric, Test) { +TEST_P(MaterializeAbstractNumericToConcreteType, Test) { // Once F16 is properly supported, we'll need to enable this: // Enable(ast::Extension::kF16); @@ -309,7 +322,7 @@ TEST_P(MaterializeAbstractNumeric, Test) { check_types_and_values(sem); break; } - case Expectation::kInvalidCast: { + case Expectation::kInvalidConversion: { ASSERT_FALSE(r()->Resolve()); std::string expect; switch (method) { @@ -338,170 +351,484 @@ TEST_P(MaterializeAbstractNumeric, Test) { } /// Methods that support scalar materialization -constexpr Method kScalarMethods[] = {Method::kLet, // - Method::kVar, // - Method::kFnArg, // - Method::kBuiltinArg, // - Method::kReturn, // - Method::kArray, // - Method::kStruct, // - Method::kBinaryOp}; +constexpr Method kScalarMethods[] = { + Method::kLet, Method::kVar, 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::kReturn, // - Method::kArray, // - Method::kStruct, // - Method::kBinaryOp}; +constexpr Method kVectorMethods[] = { + Method::kLet, Method::kVar, 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}; +constexpr Method kMatrixMethods[] = { + Method::kLet, Method::kVar, Method::kFnArg, Method::kReturn, + Method::kArray, Method::kStruct, Method::kBinaryOp, +}; /// Methods that support materialization for switch cases -constexpr Method kSwitchMethods[] = {Method::kSwitchCond, // - Method::kSwitchCase, // - Method::kSwitchCondWithAbstractCase, // - Method::kSwitchCaseWithAbstractCase}; - -constexpr double kMaxF32 = static_cast(f32::kHighest); -constexpr double kPiF64 = 3.141592653589793; -constexpr double kPiF32 = 3.1415927410125732; // kPiF64 quantized to f32 - -constexpr double kSubnormalF32 = 0x1.0p-128; +constexpr Method kSwitchMethods[] = { + Method::kSwitchCond, + Method::kSwitchCase, + Method::kSwitchCondWithAbstractCase, + Method::kSwitchCaseWithAbstractCase, +}; INSTANTIATE_TEST_SUITE_P( MaterializeScalar, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kMaterialize), // - testing::ValuesIn(kScalarMethods), // - testing::Values(Types(0_a, 0.0), // - Types(2147483647_a, 2147483647.0), // - Types(-2147483648_a, -2147483648.0), // - Types(0_a, 0.0), // - Types(4294967295_a, 4294967295.0), // - Types(0.0_a, 0.0), // - Types(AFloat(kMaxF32), kMaxF32), // - Types(AFloat(-kMaxF32), -kMaxF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32) // - /* Types(1.0_a), */ // - /* Types(1.0_a), */))); + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(kHighestU32), kHighestU32), // + Types(AInt(kLowestU32), kLowestU32), // + Types(0.0_a, 0.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(1.0_a), */ // + /* Types(1.0_a), */ // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeVector, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kMaterialize), // - testing::ValuesIn(kVectorMethods), // - testing::Values(Types(0_a, 0.0), // - Types(2147483647_a, 2147483647.0), // - Types(-2147483648_a, -2147483648.0), // - Types(0_a, 0.0), // - Types(4294967295_a, 4294967295.0), // - Types(0.0_a, 0.0), // - Types(AFloat(kMaxF32), kMaxF32), // - Types(AFloat(-kMaxF32), -kMaxF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), - -kSubnormalF32) // - /* Types(1.0_a), */ // - /* Types(1.0_a), */))); + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(kHighestU32), kHighestU32), // + Types(AInt(kLowestU32), kLowestU32), // + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(1.0_a), */ // + /* Types(1.0_a), */ // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeMatrix, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kMaterialize), // - testing::ValuesIn(kMatrixMethods), // - testing::Values(Types(0.0_a, 0.0), // - Types(AFloat(kMaxF32), kMaxF32), // - Types(AFloat(-kMaxF32), -kMaxF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), - -kSubnormalF32) // - /* Types(1.0_a), */ // - ))); + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(1.0_a), */ // + }))); -INSTANTIATE_TEST_SUITE_P( - MaterializeSwitch, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kMaterialize), // - testing::ValuesIn(kSwitchMethods), // - testing::Values(Types(0_a, 0.0), // - Types(2147483647_a, 2147483647.0), // - Types(-2147483648_a, -2147483648.0), // - Types(0_a, 0.0), // - Types(4294967295_a, 4294967295.0)))); +INSTANTIATE_TEST_SUITE_P(MaterializeSwitch, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kSwitchMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(kHighestU32), kHighestU32), // + Types(AInt(kLowestU32), kLowestU32), // + }))); // TODO(crbug.com/tint/1504): Enable once we have abstract overloads of builtins / binary ops. INSTANTIATE_TEST_SUITE_P(DISABLED_NoMaterialize, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kNoMaterialize), // - testing::Values(Method::kBuiltinArg, // - Method::kBinaryOp), // - testing::Values(Types(), // - Types(), // - Types(), // - Types(), // - Types()))); -INSTANTIATE_TEST_SUITE_P(InvalidCast, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kInvalidCast), // - testing::ValuesIn(kScalarMethods), // - testing::Values(Types(), // - Types(), // - Types(), // - Types()))); + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kNoMaterialize), + testing::Values(Method::kBuiltinArg, Method::kBinaryOp), + testing::ValuesIn(std::vector{ + Types(), // + Types(), // + Types(), // + Types(), // + Types(), // + }))); +INSTANTIATE_TEST_SUITE_P(InvalidConversion, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kInvalidConversion), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(), // + Types(), // + Types(), // + Types(), // + }))); + +INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, kHighestI32 + 1), // + Types(0_a, kLowestI32 - 1), // + Types(0_a, kHighestU32 + 1), // + Types(0_a, kLowestU32 - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + /* Types(), */ // + /* Types(), */ // + }))); + +INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, kHighestI32 + 1), // + Types(0_a, kLowestI32 - 1), // + Types(0_a, kHighestU32 + 1), // + Types(0_a, kLowestU32 - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + /* Types(), */ // + /* Types(), */ // + }))); + +INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + /* Types(), */ // + /* Types(), */ // + }))); + +} // namespace materialize_abstract_numeric_to_concrete_type + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Tests that in the absence of a 'target type' an abstract-int will materialize to i32, and an +// abstract-float will materialize to f32. +//////////////////////////////////////////////////////////////////////////////////////////////////// +namespace materialize_abstract_numeric_to_default_type { + +// How should the materialization occur? +enum class Method { + // var a = abstract_expr; + kVar, + + // let a = abstract_expr; + kLet, + + // min(abstract_expr, abstract_expr); + kBuiltinArg, + + // array(); + kArrayLength, + + // switch (abstract_expr) { + // case abstract_expr: {} + // default: {} + // } + kSwitch, +}; + +static std::ostream& operator<<(std::ostream& o, Method m) { + switch (m) { + case Method::kVar: + return o << "var"; + case Method::kLet: + return o << "let"; + case Method::kBuiltinArg: + return o << "builtin-arg"; + case Method::kArrayLength: + return o << "array-length"; + case Method::kSwitch: + return o << "switch"; + } + return o << ""; +} + +struct Data { + std::string expected_type_name; + std::string expected_element_type_name; + builder::sem_type_func_ptr expected_sem_ty; + std::string abstract_type_name; + builder::ast_expr_func_ptr abstract_expr; + std::variant materialized_value; + double literal_value; +}; + +template +Data Types(MATERIALIZED_TYPE materialized_value, double literal_value) { + using ExpectedDataType = builder::DataType; + using AbstractDataType = builder::DataType; + using TargetElementDataType = builder::DataType; + return { + ExpectedDataType::Name(), // expected_type_name + TargetElementDataType::Name(), // expected_element_type_name + ExpectedDataType::Sem, // expected_sem_ty + AbstractDataType::Name(), // abstract_type_name + AbstractDataType::Expr, // abstract_expr + materialized_value, + literal_value, + }; +} + +static std::ostream& operator<<(std::ostream& o, const Data& c) { + auto print_value = [&](auto&& v) { o << v; }; + o << "[" << c.expected_type_name << " <- " << c.abstract_type_name << "] ["; + std::visit(print_value, c.materialized_value); + o << " <- " << c.literal_value << "]"; + return o; +} + +using MaterializeAbstractNumericToDefaultType = + resolver::ResolverTestWithParam>; + +TEST_P(MaterializeAbstractNumericToDefaultType, Test) { + // Once F16 is properly supported, we'll need to enable this: + // Enable(ast::Extension::kF16); + + const auto& param = GetParam(); + const auto& expectation = std::get<0>(param); + const auto& method = std::get<1>(param); + const auto& data = std::get<2>(param); + + ast::ExpressionList abstract_exprs; + auto abstract_expr = [&] { + auto* expr = data.abstract_expr(*this, data.literal_value); + abstract_exprs.emplace_back(expr); + return expr; + }; + switch (method) { + case Method::kVar: + WrapInFunction(Decl(Var("a", nullptr, abstract_expr()))); + break; + case Method::kLet: + WrapInFunction(Decl(Let("a", nullptr, abstract_expr()))); + break; + case Method::kBuiltinArg: + WrapInFunction(CallStmt(Call("min", abstract_expr(), abstract_expr()))); + break; + case Method::kArrayLength: + WrapInFunction(Construct(ty.array(ty.i32(), abstract_expr()))); + break; + case Method::kSwitch: + WrapInFunction(Switch(abstract_expr(), + Case(abstract_expr()->As()), + DefaultCase())); + break; + } + + auto check_types_and_values = [&](const sem::Expression* expr) { + auto* expected_sem_ty = data.expected_sem_ty(*this); + + EXPECT_TYPE(expr->Type(), expected_sem_ty); + EXPECT_TYPE(expr->ConstantValue().Type(), expected_sem_ty); + + uint32_t num_elems = 0; + const sem::Type* expected_sem_el_ty = sem::Type::ElementOf(expected_sem_ty, &num_elems); + EXPECT_TYPE(expr->ConstantValue().ElementType(), expected_sem_el_ty); + expr->ConstantValue().WithElements([&](auto&& vec) { + using VEC_TY = std::decay_t; + using EL_TY = typename VEC_TY::value_type; + ASSERT_TRUE(std::holds_alternative(data.materialized_value)); + VEC_TY expected(num_elems, std::get(data.materialized_value)); + EXPECT_EQ(vec, expected); + }); + }; + + switch (expectation) { + case Expectation::kMaterialize: { + ASSERT_TRUE(r()->Resolve()) << r()->error(); + for (auto* expr : abstract_exprs) { + auto* materialize = Sem().Get(expr); + ASSERT_NE(materialize, nullptr); + check_types_and_values(materialize); + } + break; + } + case Expectation::kInvalidConversion: { + ASSERT_FALSE(r()->Resolve()); + std::string expect; + switch (method) { + case Method::kBuiltinArg: + expect = "error: no matching call to min(" + data.abstract_type_name + ", " + + data.abstract_type_name + ")"; + break; + default: + expect = "error: cannot convert value of type '" + data.abstract_type_name + + "' to type '" + data.expected_type_name + "'"; + break; + } + EXPECT_THAT(r()->error(), testing::StartsWith(expect)); + break; + } + case Expectation::kValueCannotBeRepresented: + ASSERT_FALSE(r()->Resolve()); + EXPECT_THAT(r()->error(), testing::HasSubstr("cannot be represented as '" + + data.expected_element_type_name + "'")); + break; + default: + FAIL() << "unhandled expectation: " << expectation; + } +} + +/// Methods that support scalar materialization +constexpr Method kScalarMethods[] = { + Method::kLet, + Method::kVar, + Method::kBuiltinArg, +}; + +/// Methods that support vector materialization +constexpr Method kVectorMethods[] = { + Method::kLet, + Method::kVar, + Method::kBuiltinArg, +}; + +/// Methods that support matrix materialization +constexpr Method kMatrixMethods[] = { + Method::kLet, + Method::kVar, +}; + +/// Methods that support materialization for switch cases +constexpr Method kSwitchMethods[] = { + Method::kSwitch, +}; INSTANTIATE_TEST_SUITE_P( - ScalarValueCannotBeRepresented, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), // - testing::ValuesIn(kScalarMethods), // - testing::Values(Types(0_a, 2147483648.0), // - Types(0_a, -2147483649.0), // - Types(0_a, 4294967296), // - Types(0_a, -1.0), // - Types(0.0_a, 3.5e+38), // - Types(0.0_a, -3.5e+38) // - /* Types(), */ // - /* Types(), */))); + MaterializeScalar, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + Types(0.0_a, 0.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); INSTANTIATE_TEST_SUITE_P( - VectorValueCannotBeRepresented, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), // - testing::ValuesIn(kVectorMethods), // - testing::Values(Types(0_a, 2147483648.0), // - Types(0_a, -2147483649.0), // - Types(0_a, 4294967296), // - Types(0_a, -1.0), // - Types(0.0_a, 3.5e+38), // - Types(0.0_a, -3.5e+38) // - /* Types(), */ // - /* Types(), */))); + MaterializeVector, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); INSTANTIATE_TEST_SUITE_P( - MatrixValueCannotBeRepresented, - MaterializeAbstractNumeric, // - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), // - testing::ValuesIn(kMatrixMethods), // - testing::Values(Types(0.0_a, 3.5e+38), // - Types(0.0_a, -3.5e+38) // - /* Types(), */ // - /* Types(), */))); + MaterializeMatrix, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(kHighestF32), kHighestF32), // + Types(AFloat(kLowestF32), kLowestF32), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); -} // namespace MaterializeTests +INSTANTIATE_TEST_SUITE_P(MaterializeSwitch, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kSwitchMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(AInt(kHighestI32), kHighestI32), // + Types(AInt(kLowestI32), kLowestI32), // + }))); + +INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, kHighestI32 + 1), // + Types(0_a, kLowestI32 - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + }))); + +INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, kHighestI32 + 1), // + Types(0_a, kLowestI32 - 1), // + Types(0_a, kHighestU32 + 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + }))); + +INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + }))); + +INSTANTIATE_TEST_SUITE_P(SwitchValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kSwitchMethods), + testing::ValuesIn(std::vector{ + Types(0_a, kHighestI32 + 1), // + Types(0_a, kLowestI32 - 1), // + }))); + +} // namespace materialize_abstract_numeric_to_default_type } // namespace } // namespace tint::resolver diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index af8f16a9a4..9fdb576c90 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -1145,7 +1145,7 @@ const sem::Expression* Resolver::Materialize(const sem::Expression* expr, auto i32v = [&](uint32_t width) { return builder_->create(i32(), width); }; auto f32v = [&](uint32_t width) { return builder_->create(f32(), width); }; auto f32m = [&](uint32_t columns, uint32_t rows) { - return builder_->create(f32v(columns), rows); + return builder_->create(f32v(rows), columns); }; // Type dispatch based on the expression type