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 //
////////////////////////////////////////////////////////////////////////////////
op ! (bool) -> bool
op ! <N: num> (vec<N, bool>) -> vec<N, bool>
@const op ! (bool) -> bool
@const op ! <N: num> (vec<N, bool>) -> vec<N, bool>
@const op ~ <T: ia_iu32>(T) -> 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>()...); });
}
/// 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
/// 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
@ -973,6 +980,16 @@ ConstEval::ConstantResult ConstEval::OpUnaryMinus(const sem::Type* ty,
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,
utils::VectorRef<const sem::Constant*> args,
const Source& source) {

View File

@ -208,6 +208,15 @@ class ConstEval {
utils::VectorRef<const sem::Constant*> args,
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
////////////////////////////////////////////////////////////////////////////

View File

@ -3151,6 +3151,12 @@ static std::ostream& operator<<(std::ostream& o, const Case& c) {
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
template <typename T, typename U, typename = std::enable_if_t<!IsValue<T>>>
Case C(T input, U expected) {
@ -3284,6 +3290,18 @@ TEST_F(ResolverConstEvalTest, UnaryNegateLowestAbstract) {
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
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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