mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-15 08:06:19 +00:00
Implement const eval of abs
This CL adds const-eval for the `abs` builtin. Bug: tint:1581 Change-Id: I6ee25c07620990f72a6962441aec62ae7665653e Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/108340 Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
5ae03c266a
commit
b3518d8b4d
@@ -404,8 +404,8 @@ match storage
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#builtin-functions
|
||||
fn abs<T: fiu32_f16>(T) -> T
|
||||
fn abs<N: num, T: fiu32_f16>(vec<N, T>) -> vec<N, T>
|
||||
@const fn abs<T: fia_fiu32_f16>(T) -> T
|
||||
@const fn abs<N: num, T: fia_fiu32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn acos<T: f32_f16>(T) -> T
|
||||
fn acos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn acosh<T: f32_f16>(T) -> T
|
||||
|
||||
@@ -61,12 +61,10 @@ inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, ModuleScopeUsage) {
|
||||
GlobalConst("c", ty.f32(), Call(Source{{12, 34}}, "abs", 1._f));
|
||||
GlobalConst("c", ty.f32(), Call(Source{{12, 34}}, "dpdy", 1._f));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
// TODO(crbug.com/tint/1581): Once 'abs' is implemented as @const, this will no longer be an
|
||||
// error.
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
|
||||
|
||||
@@ -1570,6 +1570,31 @@ ConstEval::Result ConstEval::OpShiftLeft(const sem::Type* ty,
|
||||
return r;
|
||||
}
|
||||
|
||||
ConstEval::Result ConstEval::abs(const sem::Type* ty,
|
||||
utils::VectorRef<const sem::Constant*> args,
|
||||
const Source&) {
|
||||
auto transform = [&](const sem::Constant* c0) {
|
||||
auto create = [&](auto e) {
|
||||
using NumberT = decltype(e);
|
||||
NumberT result;
|
||||
if constexpr (IsUnsignedIntegral<NumberT>) {
|
||||
result = e;
|
||||
} else if constexpr (IsSignedIntegral<NumberT>) {
|
||||
if (e == NumberT::Lowest()) {
|
||||
result = e;
|
||||
} else {
|
||||
result = NumberT{std::abs(e)};
|
||||
}
|
||||
} else {
|
||||
result = NumberT{std::abs(e)};
|
||||
}
|
||||
return CreateElement(builder, c0->Type(), result);
|
||||
};
|
||||
return Dispatch_fia_fiu32_f16(create, c0);
|
||||
};
|
||||
return TransformElements(builder, ty, transform, args[0]);
|
||||
}
|
||||
|
||||
ConstEval::Result ConstEval::all(const sem::Type* ty,
|
||||
utils::VectorRef<const sem::Constant*> args,
|
||||
const Source&) {
|
||||
|
||||
@@ -377,6 +377,15 @@ class ConstEval {
|
||||
// Builtins
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// abs builtin
|
||||
/// @param ty the expression type
|
||||
/// @param args the input arguments
|
||||
/// @param source the source location of the conversion
|
||||
/// @return the result value, or null if the value cannot be calculated
|
||||
Result abs(const sem::Type* ty,
|
||||
utils::VectorRef<const sem::Constant*> args,
|
||||
const Source& source);
|
||||
|
||||
/// all builtin
|
||||
/// @param ty the expression type
|
||||
/// @param args the input arguments
|
||||
|
||||
@@ -146,6 +146,53 @@ INSTANTIATE_TEST_SUITE_P( //
|
||||
C({1.0_a, 0_a}, kPiOver2<AFloat>),
|
||||
})));
|
||||
|
||||
template <typename T, bool finite_only>
|
||||
std::vector<Case> AbsCases() {
|
||||
std::vector<Case> cases = {
|
||||
C({T(0)}, T(0)),
|
||||
C({T(2.0)}, T(2.0)),
|
||||
C({T::Highest()}, T::Highest()),
|
||||
|
||||
// Vector tests
|
||||
C({Vec(T(2.0), T::Highest())}, Vec(T(2.0), T::Highest())),
|
||||
};
|
||||
|
||||
ConcatIntoIf<IsSignedIntegral<T>>(
|
||||
cases,
|
||||
std::vector<Case>{
|
||||
C({Negate(T(0))}, T(0)),
|
||||
C({Negate(T(2.0))}, T(2.0)),
|
||||
// If e is signed and is the largest negative, the result is e
|
||||
C({T::Lowest()}, T::Lowest()),
|
||||
|
||||
// 1 more then min i32
|
||||
C({Negate(T(2147483647))}, T(2147483647)),
|
||||
|
||||
C({Vec(T(0), Negate(T(0)))}, Vec(T(0), T(0))),
|
||||
C({Vec(Negate(T(2.0)), T(2.0), T::Highest())}, Vec(T(2.0), T(2.0), T::Highest())),
|
||||
});
|
||||
|
||||
ConcatIntoIf<!finite_only>(cases, std::vector<Case>{
|
||||
C({Negate(T::Inf())}, T::Inf()),
|
||||
C({T::Inf()}, T::Inf()),
|
||||
C({T::NaN()}, T::NaN()),
|
||||
C({Vec(Negate(T::Inf()), T::Inf(), T::NaN())},
|
||||
Vec(T::Inf(), T::Inf(), T::NaN())),
|
||||
});
|
||||
|
||||
return cases;
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P( //
|
||||
Abs,
|
||||
ResolverConstEvalBuiltinTest,
|
||||
testing::Combine(testing::Values(sem::BuiltinType::kAbs),
|
||||
testing::ValuesIn(Concat(AbsCases<AInt, false>(), //
|
||||
AbsCases<i32, false>(),
|
||||
AbsCases<u32, false>(),
|
||||
AbsCases<AFloat, true>(),
|
||||
AbsCases<f32, false>(),
|
||||
AbsCases<f16, false>()))));
|
||||
|
||||
static std::vector<Case> AllCases() {
|
||||
return {
|
||||
C({Val(true)}, Val(true)),
|
||||
|
||||
@@ -12945,24 +12945,24 @@ constexpr OverloadInfo kOverloads[] = {
|
||||
/* num parameters */ 1,
|
||||
/* num template types */ 1,
|
||||
/* num template numbers */ 0,
|
||||
/* template types */ &kTemplateTypes[25],
|
||||
/* template types */ &kTemplateTypes[28],
|
||||
/* template numbers */ &kTemplateNumbers[10],
|
||||
/* parameters */ &kParameters[1018],
|
||||
/* return matcher indices */ &kMatcherIndices[1],
|
||||
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
|
||||
/* const eval */ nullptr,
|
||||
/* const eval */ &ConstEval::abs,
|
||||
},
|
||||
{
|
||||
/* [385] */
|
||||
/* num parameters */ 1,
|
||||
/* num template types */ 1,
|
||||
/* num template numbers */ 1,
|
||||
/* template types */ &kTemplateTypes[25],
|
||||
/* template types */ &kTemplateTypes[28],
|
||||
/* template numbers */ &kTemplateNumbers[6],
|
||||
/* parameters */ &kParameters[853],
|
||||
/* return matcher indices */ &kMatcherIndices[30],
|
||||
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
|
||||
/* const eval */ nullptr,
|
||||
/* const eval */ &ConstEval::abs,
|
||||
},
|
||||
{
|
||||
/* [386] */
|
||||
@@ -14013,8 +14013,8 @@ constexpr OverloadInfo kOverloads[] = {
|
||||
constexpr IntrinsicInfo kBuiltins[] = {
|
||||
{
|
||||
/* [0] */
|
||||
/* fn abs<T : fiu32_f16>(T) -> T */
|
||||
/* fn abs<N : num, T : fiu32_f16>(vec<N, T>) -> vec<N, T> */
|
||||
/* fn abs<T : fia_fiu32_f16>(T) -> T */
|
||||
/* fn abs<N : num, T : fia_fiu32_f16>(vec<N, T>) -> vec<N, T> */
|
||||
/* num overloads */ 2,
|
||||
/* overloads */ &kOverloads[384],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user