chromium/third_party/dawn/src/tint/lang/wgsl/resolver/alias_analysis_test.cc

// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/lang/wgsl/resolver/resolver.h"
#include "src/tint/lang/wgsl/resolver/resolver_helper_test.h"
#include "src/tint/utils/text/string_stream.h"

#include "gmock/gmock.h"

namespace tint::resolver {
namespace {

usingnamespacetint::core::fluent_types;     // NOLINT
usingnamespacetint::core::number_suffixes;  // NOLINT

struct ResolverAliasAnalysisTest : public resolver::TestHelper, public testing::Test {};

// Base test harness for tests that pass two pointers to a function.
//
// fn target(p1 : ptr<function, i32>, p2 : ptr<function, i32>) {
//   <test statements>
// }
// fn caller() {
//   var v1 : i32;
//   var v2 : i32;
//   target(&v1, aliased ? &v1 : &v2);
// }
struct TwoPointerConfig {};
class TwoPointers : public ResolverTestWithParam<TwoPointerConfig> {};

TEST_P(TwoPointers, ReadRead) {}

TEST_P(TwoPointers, ReadWrite) {}

TEST_P(TwoPointers, WriteRead) {}

TEST_P(TwoPointers, WriteWrite) {}

TEST_P(TwoPointers, ReadWriteThroughChain) {}

TEST_P(TwoPointers, ReadWriteAcrossDifferentFunctions) {}

INSTANTIATE_TEST_SUITE_P();

// Base test harness for tests that pass a pointer to a function that references a module-scope var.
//
// var<private> global_1 : i32;
// var<private> global_2 : i32;
// fn target(p1 : ptr<private, i32>) {
//   <test statements>
// }
// fn caller() {
//   target(aliased ? &global_1 : &global_2);
// }
class OnePointerOneModuleScope : public ResolverTestWithParam<bool> {};

TEST_P(OnePointerOneModuleScope, ReadRead) {}

TEST_P(OnePointerOneModuleScope, ReadWrite) {}

TEST_P(OnePointerOneModuleScope, WriteRead) {}

TEST_P(OnePointerOneModuleScope, WriteWrite) {}

TEST_P(OnePointerOneModuleScope, ReadWriteThroughChain_GlobalViaArg) {}

TEST_P(OnePointerOneModuleScope, ReadWriteThroughChain_Both) {}

TEST_P(OnePointerOneModuleScope, WriteReadThroughChain_GlobalViaArg) {}

TEST_P(OnePointerOneModuleScope, WriteReadThroughChain_Both) {}

TEST_P(OnePointerOneModuleScope, ReadWriteAcrossDifferentFunctions) {}

INSTANTIATE_TEST_SUITE_P();

// Base test harness for tests that use a potentially aliased pointer in a variety of expressions.
//
// fn target(p1 : ptr<function, i32>, p2 : ptr<function, i32>) {
//   *p1 = 42;
//   <test statements>
// }
// fn caller() {
//   var v1 : i32;
//   var v2 : i32;
//   target(&v1, aliased ? &v1 : &v2);
// }
class Use : public ResolverTestWithParam<bool> {};

TEST_P(Use, NoAccess) {}

TEST_P(Use, Write_Increment) {}

TEST_P(Use, Write_Decrement) {}

TEST_P(Use, Write_CompoundAssignment_LHS) {}

TEST_P(Use, Read_CompoundAssignment_RHS) {}

TEST_P(Use, Read_BinaryOp_LHS) {}

TEST_P(Use, Read_BinaryOp_RHS) {}

TEST_P(Use, Read_UnaryMinus) {}

TEST_P(Use, Read_FunctionCallArg) {}

TEST_P(Use, Read_Bitcast) {}

TEST_P(Use, Read_Convert) {}

TEST_P(Use, Read_IndexAccessor) {}

TEST_P(Use, Read_LetInitializer) {}

TEST_P(Use, Read_VarInitializer) {}

TEST_P(Use, Read_ReturnValue) {}

TEST_P(Use, Read_Switch) {}

TEST_P(Use, NoAccess_AddressOf_Deref) {}

INSTANTIATE_TEST_SUITE_P();

// Base test harness for tests that use a potentially aliased pointer in a variety of expressions.
// As above, but using the bool type to test expressions that invoke that load-rule for booleans.
//
// fn target(p1 : ptr<function, bool>, p2 : ptr<function, bool>) {
//   *p1 = true;
//   <test statements>
// }
// fn caller() {
//   var v1 : bool;
//   var v2 : bool;
//   target(&v1, aliased ? &v1 : &v2);
// }
class UseBool : public ResolverTestWithParam<bool> {};

TEST_P(UseBool, Read_IfCond) {}

TEST_P(UseBool, Read_WhileCond) {}

TEST_P(UseBool, Read_ForCond) {}

TEST_P(UseBool, Read_BreakIf) {}

INSTANTIATE_TEST_SUITE_P();

TEST_F(ResolverAliasAnalysisTest, NoAccess_MemberAccessor) {}

TEST_F(ResolverAliasAnalysisTest, Read_MemberAccessor) {}

TEST_F(ResolverAliasAnalysisTest, Write_MemberAccessor) {}

TEST_F(ResolverAliasAnalysisTest, Read_MultiComponentSwizzle) {}

TEST_F(ResolverAliasAnalysisTest, Read_MultiComponentSwizzle_FromPointer) {}

TEST_F(ResolverAliasAnalysisTest, SinglePointerReadWrite) {}

TEST_F(ResolverAliasAnalysisTest, AliasingInsideFunction) {}

TEST_F(ResolverAliasAnalysisTest, NonOverlappingCalls) {}

////////////////////////////////////////////////////////////////////////////////
// Atomics
////////////////////////////////////////////////////////////////////////////////
class AtomicPointers
    : public ResolverTestWithParam<
          std::tuple<wgsl::BuiltinFn, wgsl::BuiltinFn, core::AddressSpace, bool /* aliased */>> {};

TEST_P(AtomicPointers, CallDirect) {}

TEST_P(AtomicPointers, CallThroughChain) {}

TEST_P(AtomicPointers, ReadWriteAcrossDifferentFunctions) {}

std::array kAtomicFns{};

INSTANTIATE_TEST_SUITE_P();

////////////////////////////////////////////////////////////////////////////////
// WorkgroupUniformLoad
////////////////////////////////////////////////////////////////////////////////
enum class WorkgroupUniformLoadAction {};

std::array kWorkgroupUniformLoadActions{};

class WorkgroupUniformLoad
    : public ResolverTestWithParam<
          std::tuple<WorkgroupUniformLoadAction, WorkgroupUniformLoadAction, bool>> {};

TEST_P(WorkgroupUniformLoad, CallDirect) {}

TEST_P(WorkgroupUniformLoad, CallThroughChain) {}

TEST_P(WorkgroupUniformLoad, ReadWriteAcrossDifferentFunctions) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace
}  // namespace tint::resolver