tint: Implement const eval of unary not

Bug: tint:1581
Change-Id: If0a74b1f6739725a2284678aab97baf737d96937
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101761
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Antonio Maiorano 2022-09-13 17:32:17 +00:00 committed by Dawn LUCI CQ
parent 8175cff07b
commit 5b3707a2d7
21 changed files with 113 additions and 77 deletions

View File

@ -874,8 +874,8 @@ ctor mat4x4<T: fa_f32_f16>(vec4<T>, vec4<T>, vec4<T>, vec4<T>) -> mat4x4<T>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Unary Operators // // Unary Operators //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
op ! (bool) -> bool @const op ! (bool) -> bool
op ! <N: num> (vec<N, bool>) -> vec<N, bool> @const op ! <N: num> (vec<N, bool>) -> vec<N, bool>
@const op ~ <T: ia_iu32>(T) -> T @const op ~ <T: ia_iu32>(T) -> T
@const op ~ <T: ia_iu32, N: num> (vec<N, T>) -> vec<N, T> @const op ~ <T: ia_iu32, N: num> (vec<N, T>) -> vec<N, T>

View File

@ -117,6 +117,13 @@ auto Dispatch_fa_f32_f16(F&& f, CONSTANTS&&... cs) {
[&](const sem::F16*) { return f(cs->template As<f16>()...); }); [&](const sem::F16*) { return f(cs->template As<f16>()...); });
} }
/// Helper that calls `f` passing in the value of all `cs`.
/// Assumes all `cs` are of the same type.
template <typename F, typename... CONSTANTS>
auto Dispatch_bool(F&& f, CONSTANTS&&... cs) {
return f(cs->template As<bool>()...);
}
/// ZeroTypeDispatch is a helper for calling the function `f`, passing a single zero-value argument /// ZeroTypeDispatch is a helper for calling the function `f`, passing a single zero-value argument
/// of the C++ type that corresponds to the sem::Type `type`. For example, calling /// of the C++ type that corresponds to the sem::Type `type`. For example, calling
/// `ZeroTypeDispatch()` with a type of `sem::I32*` will call the function f with a single argument /// `ZeroTypeDispatch()` with a type of `sem::I32*` will call the function f with a single argument
@ -973,6 +980,16 @@ ConstEval::ConstantResult ConstEval::OpUnaryMinus(const sem::Type* ty,
return TransformElements(builder, ty, transform, args[0]); return TransformElements(builder, ty, transform, args[0]);
} }
ConstEval::ConstantResult ConstEval::OpNot(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source&) {
auto transform = [&](const sem::Constant* c) {
auto create = [&](auto i) { return CreateElement(builder, c->Type(), decltype(i)(!i)); };
return Dispatch_bool(create, c);
};
return TransformElements(builder, ty, transform, args[0]);
}
ConstEval::ConstantResult ConstEval::OpPlus(const sem::Type* ty, ConstEval::ConstantResult ConstEval::OpPlus(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args, utils::VectorRef<const sem::Constant*> args,
const Source& source) { const Source& source) {

View File

@ -208,6 +208,15 @@ class ConstEval {
utils::VectorRef<const sem::Constant*> args, utils::VectorRef<const sem::Constant*> args,
const Source& source); const Source& source);
/// Unary not operator '!'
/// @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
ConstantResult OpNot(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source& source);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Binary Operators // Binary Operators
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View File

@ -3151,6 +3151,12 @@ static std::ostream& operator<<(std::ostream& o, const Case& c) {
return o; return o;
} }
/// Creates a Case with Values of any type
template <typename T, typename U>
Case C(Value<T> input, Value<U> expected) {
return Case{std::move(input), std::move(expected)};
}
/// Convenience overload to creates a Case with just scalars /// Convenience overload to creates a Case with just scalars
template <typename T, typename U, typename = std::enable_if_t<!IsValue<T>>> template <typename T, typename U, typename = std::enable_if_t<!IsValue<T>>>
Case C(T input, U expected) { Case C(T input, U expected) {
@ -3284,6 +3290,18 @@ TEST_F(ResolverConstEvalTest, UnaryNegateLowestAbstract) {
EXPECT_EQ(sem->ConstantValue()->As<AInt>(), 9223372036854775808_a); EXPECT_EQ(sem->ConstantValue()->As<AInt>(), 9223372036854775808_a);
} }
INSTANTIATE_TEST_SUITE_P(Not,
ResolverConstEvalUnaryOpTest,
testing::Combine(testing::Values(ast::UnaryOp::kNot),
testing::ValuesIn({
C(true, false),
C(false, true),
C(Vec(true, true), Vec(false, false)),
C(Vec(true, false), Vec(false, true)),
C(Vec(false, true), Vec(true, false)),
C(Vec(false, false), Vec(true, true)),
})));
} // namespace unary_op } // namespace unary_op
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -13261,7 +13261,7 @@ constexpr OverloadInfo kOverloads[] = {
/* parameters */ &kParameters[858], /* parameters */ &kParameters[858],
/* return matcher indices */ &kMatcherIndices[16], /* return matcher indices */ &kMatcherIndices[16],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr, /* const eval */ &ConstEval::OpNot,
}, },
{ {
/* [425] */ /* [425] */
@ -13273,7 +13273,7 @@ constexpr OverloadInfo kOverloads[] = {
/* parameters */ &kParameters[859], /* parameters */ &kParameters[859],
/* return matcher indices */ &kMatcherIndices[39], /* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline), /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr, /* const eval */ &ConstEval::OpNot,
}, },
{ {
/* [426] */ /* [426] */

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 20 ; Bound: 19
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -16,7 +16,7 @@
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%10 = OpConstantNull %int %10 = OpConstantNull %int
%bool = OpTypeBool %bool = OpTypeBool
%17 = OpConstantNull %bool %true = OpConstantTrue %bool
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
OpReturn OpReturn
@ -29,12 +29,11 @@
OpLoopMerge %12 %13 None OpLoopMerge %12 %13 None
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
%15 = OpLogicalNot %bool %17 OpSelectionMerge %17 None
OpSelectionMerge %18 None OpBranchConditional %true %18 %17
OpBranchConditional %15 %19 %18
%19 = OpLabel
OpBranch %12
%18 = OpLabel %18 = OpLabel
OpBranch %12
%17 = OpLabel
OpBranch %13 OpBranch %13
%13 = OpLabel %13 = OpLabel
OpBranch %11 OpBranch %11

View File

@ -6,7 +6,7 @@ void unused_entry_point() {
void f() { void f() {
int i = 0; int i = 0;
[loop] while (true) { [loop] while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -6,7 +6,7 @@ void unused_entry_point() {
void f() { void f() {
int i = 0; int i = 0;
[loop] while (true) { [loop] while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -7,7 +7,7 @@ void unused_entry_point() {
void f() { void f() {
int i = 0; int i = 0;
while (true) { while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -17,7 +17,7 @@ struct tint_array {
void f() { void f() {
int i = 0; int i = 0;
while (true) { while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 23 ; Bound: 22
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -16,7 +16,7 @@
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%10 = OpConstantNull %int %10 = OpConstantNull %int
%bool = OpTypeBool %bool = OpTypeBool
%17 = OpConstantNull %bool %true = OpConstantTrue %bool
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
@ -30,17 +30,16 @@
OpLoopMerge %12 %13 None OpLoopMerge %12 %13 None
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
%15 = OpLogicalNot %bool %17 OpSelectionMerge %17 None
OpSelectionMerge %18 None OpBranchConditional %true %18 %17
OpBranchConditional %15 %19 %18
%19 = OpLabel
OpBranch %12
%18 = OpLabel %18 = OpLabel
OpBranch %12
%17 = OpLabel
OpBranch %13 OpBranch %13
%13 = OpLabel %13 = OpLabel
%20 = OpLoad %int %i %19 = OpLoad %int %i
%22 = OpIAdd %int %20 %int_1 %21 = OpIAdd %int %19 %int_1
OpStore %i %22 OpStore %i %21
OpBranch %11 OpBranch %11
%12 = OpLabel %12 = OpLabel
OpReturn OpReturn

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 23 ; Bound: 22
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -16,7 +16,7 @@
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%10 = OpConstantNull %int %10 = OpConstantNull %int
%bool = OpTypeBool %bool = OpTypeBool
%17 = OpConstantNull %bool %true = OpConstantTrue %bool
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
@ -30,17 +30,16 @@
OpLoopMerge %12 %13 None OpLoopMerge %12 %13 None
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
%15 = OpLogicalNot %bool %17 OpSelectionMerge %17 None
OpSelectionMerge %18 None OpBranchConditional %true %18 %17
OpBranchConditional %15 %19 %18
%19 = OpLabel
OpBranch %12
%18 = OpLabel %18 = OpLabel
OpBranch %12
%17 = OpLabel
OpBranch %13 OpBranch %13
%13 = OpLabel %13 = OpLabel
%20 = OpLoad %int %i %19 = OpLoad %int %i
%22 = OpIAdd %int %20 %int_1 %21 = OpIAdd %int %19 %int_1
OpStore %i %22 OpStore %i %21
OpBranch %11 OpBranch %11
%12 = OpLabel %12 = OpLabel
OpReturn OpReturn

View File

@ -11,7 +11,7 @@ void f() {
{ {
int i = 0; int i = 0;
[loop] while (true) { [loop] while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -11,7 +11,7 @@ void f() {
{ {
int i = 0; int i = 0;
[loop] while (true) { [loop] while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -12,7 +12,7 @@ void f() {
{ {
int i = 0; int i = 0;
while (true) { while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -9,7 +9,7 @@ void f() {
{ {
int i = 0; int i = 0;
while (true) { while (true) {
if (!(false)) { if (true) {
break; break;
} }
{ {

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 23 ; Bound: 22
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -16,7 +16,7 @@
%8 = OpConstantNull %int %8 = OpConstantNull %int
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%bool = OpTypeBool %bool = OpTypeBool
%17 = OpConstantNull %bool %true = OpConstantTrue %bool
%int_1 = OpConstant %int 1 %int_1 = OpConstant %int 1
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
@ -31,17 +31,16 @@
OpLoopMerge %12 %13 None OpLoopMerge %12 %13 None
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
%15 = OpLogicalNot %bool %17 OpSelectionMerge %17 None
OpSelectionMerge %18 None OpBranchConditional %true %18 %17
OpBranchConditional %15 %19 %18
%19 = OpLabel
OpBranch %12
%18 = OpLabel %18 = OpLabel
OpBranch %12
%17 = OpLabel
OpBranch %13 OpBranch %13
%13 = OpLabel %13 = OpLabel
%20 = OpLoad %int %i %19 = OpLoad %int %i
%22 = OpIAdd %int %20 %int_1 %21 = OpIAdd %int %19 %int_1
OpStore %i %22 OpStore %i %21
OpBranch %11 OpBranch %11
%12 = OpLabel %12 = OpLabel
OpReturn OpReturn

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 16 ; Bound: 15
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -12,7 +12,7 @@
%void = OpTypeVoid %void = OpTypeVoid
%1 = OpTypeFunction %void %1 = OpTypeFunction %void
%bool = OpTypeBool %bool = OpTypeBool
%13 = OpConstantNull %bool %true = OpConstantTrue %bool
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
OpReturn OpReturn
@ -24,12 +24,11 @@
OpLoopMerge %8 %9 None OpLoopMerge %8 %9 None
OpBranch %10 OpBranch %10
%10 = OpLabel %10 = OpLabel
%11 = OpLogicalNot %bool %13 OpSelectionMerge %13 None
OpSelectionMerge %14 None OpBranchConditional %true %14 %13
OpBranchConditional %11 %15 %14
%15 = OpLabel
OpBranch %8
%14 = OpLabel %14 = OpLabel
OpBranch %8
%13 = OpLabel
OpBranch %9 OpBranch %9
%9 = OpLabel %9 = OpLabel
OpBranch %7 OpBranch %7

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 21 ; Bound: 20
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -17,7 +17,7 @@
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%11 = OpConstantNull %int %11 = OpConstantNull %int
%bool = OpTypeBool %bool = OpTypeBool
%18 = OpConstantNull %bool %true = OpConstantTrue %bool
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
OpReturn OpReturn
@ -31,12 +31,11 @@
OpLoopMerge %13 %14 None OpLoopMerge %13 %14 None
OpBranch %15 OpBranch %15
%15 = OpLabel %15 = OpLabel
%16 = OpLogicalNot %bool %18 OpSelectionMerge %18 None
OpSelectionMerge %19 None OpBranchConditional %true %19 %18
OpBranchConditional %16 %20 %19
%20 = OpLabel
OpBranch %13
%19 = OpLabel %19 = OpLabel
OpBranch %13
%18 = OpLabel
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
OpBranch %12 OpBranch %12

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 20 ; Bound: 19
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -16,7 +16,7 @@
%8 = OpConstantNull %int %8 = OpConstantNull %int
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%bool = OpTypeBool %bool = OpTypeBool
%17 = OpConstantNull %bool %true = OpConstantTrue %bool
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
OpReturn OpReturn
@ -30,12 +30,11 @@
OpLoopMerge %12 %13 None OpLoopMerge %12 %13 None
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
%15 = OpLogicalNot %bool %17 OpSelectionMerge %17 None
OpSelectionMerge %18 None OpBranchConditional %true %18 %17
OpBranchConditional %15 %19 %18
%19 = OpLabel
OpBranch %12
%18 = OpLabel %18 = OpLabel
OpBranch %12
%17 = OpLabel
OpBranch %13 OpBranch %13
%13 = OpLabel %13 = OpLabel
OpBranch %11 OpBranch %11

View File

@ -1,7 +1,7 @@
; SPIR-V ; SPIR-V
; Version: 1.3 ; Version: 1.3
; Generator: Google Tint Compiler; 0 ; Generator: Google Tint Compiler; 0
; Bound: 21 ; Bound: 20
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
@ -17,7 +17,7 @@
%_ptr_Function_int = OpTypePointer Function %int %_ptr_Function_int = OpTypePointer Function %int
%11 = OpConstantNull %int %11 = OpConstantNull %int
%bool = OpTypeBool %bool = OpTypeBool
%18 = OpConstantNull %bool %true = OpConstantTrue %bool
%unused_entry_point = OpFunction %void None %1 %unused_entry_point = OpFunction %void None %1
%4 = OpLabel %4 = OpLabel
OpReturn OpReturn
@ -31,12 +31,11 @@
OpLoopMerge %13 %14 None OpLoopMerge %13 %14 None
OpBranch %15 OpBranch %15
%15 = OpLabel %15 = OpLabel
%16 = OpLogicalNot %bool %18 OpSelectionMerge %18 None
OpSelectionMerge %19 None OpBranchConditional %true %19 %18
OpBranchConditional %16 %20 %19
%20 = OpLabel
OpBranch %13
%19 = OpLabel %19 = OpLabel
OpBranch %13
%18 = OpLabel
OpBranch %14 OpBranch %14
%14 = OpLabel %14 = OpLabel
OpBranch %12 OpBranch %12