// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <set>
#include <unordered_set>

#include "source/fuzz/data_descriptor.h"
#include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_copy_object.h"
#include "test/fuzz/fuzz_test_util.h"

namespace spvtools {
namespace fuzz {
namespace {

TEST(TransformationCopyObjectTest, CopyBooleanConstants) {
  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
          %2 = OpTypeVoid
          %6 = OpTypeBool
          %7 = OpConstantTrue %6
          %8 = OpConstantFalse %6
          %3 = OpTypeFunction %2
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  ASSERT_EQ(0, transformation_context.GetFactManager()
                   ->GetIdsForWhichSynonymsAreKnown()
                   .size());

  {
    TransformationCopyObject copy_true(
        7, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100);
    ASSERT_TRUE(copy_true.IsApplicable(context.get(), transformation_context));
    copy_true.Apply(context.get(), &transformation_context);

    std::vector<uint32_t> ids_for_which_synonyms_are_known =
        transformation_context.GetFactManager()
            ->GetIdsForWhichSynonymsAreKnown();
    ASSERT_EQ(2, ids_for_which_synonyms_are_known.size());
    ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
                          ids_for_which_synonyms_are_known.end(),
                          7) != ids_for_which_synonyms_are_known.end());
    ASSERT_EQ(
        2, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
    protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {});
    ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
        MakeDataDescriptor(7, {}), descriptor_100));
  }

  {
    TransformationCopyObject copy_false(
        8, MakeInstructionDescriptor(100, SpvOpReturn, 0), 101);
    ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context));
    copy_false.Apply(context.get(), &transformation_context);
    std::vector<uint32_t> ids_for_which_synonyms_are_known =
        transformation_context.GetFactManager()
            ->GetIdsForWhichSynonymsAreKnown();
    ASSERT_EQ(4, ids_for_which_synonyms_are_known.size());
    ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
                          ids_for_which_synonyms_are_known.end(),
                          8) != ids_for_which_synonyms_are_known.end());
    ASSERT_EQ(
        2, transformation_context.GetFactManager()->GetSynonymsForId(8).size());
    protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {});
    ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
        MakeDataDescriptor(8, {}), descriptor_101));
  }

  {
    TransformationCopyObject copy_false_again(
        101, MakeInstructionDescriptor(5, SpvOpReturn, 0), 102);
    ASSERT_TRUE(
        copy_false_again.IsApplicable(context.get(), transformation_context));
    copy_false_again.Apply(context.get(), &transformation_context);
    std::vector<uint32_t> ids_for_which_synonyms_are_known =
        transformation_context.GetFactManager()
            ->GetIdsForWhichSynonymsAreKnown();
    ASSERT_EQ(5, ids_for_which_synonyms_are_known.size());
    ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
                          ids_for_which_synonyms_are_known.end(),
                          101) != ids_for_which_synonyms_are_known.end());
    ASSERT_EQ(
        3,
        transformation_context.GetFactManager()->GetSynonymsForId(101).size());
    protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {});
    ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
        MakeDataDescriptor(101, {}), descriptor_102));
  }

  {
    TransformationCopyObject copy_true_again(
        7, MakeInstructionDescriptor(102, SpvOpReturn, 0), 103);
    ASSERT_TRUE(
        copy_true_again.IsApplicable(context.get(), transformation_context));
    copy_true_again.Apply(context.get(), &transformation_context);
    std::vector<uint32_t> ids_for_which_synonyms_are_known =
        transformation_context.GetFactManager()
            ->GetIdsForWhichSynonymsAreKnown();
    ASSERT_EQ(6, ids_for_which_synonyms_are_known.size());
    ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(),
                          ids_for_which_synonyms_are_known.end(),
                          7) != ids_for_which_synonyms_are_known.end());
    ASSERT_EQ(
        3, transformation_context.GetFactManager()->GetSynonymsForId(7).size());
    protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {});
    ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
        MakeDataDescriptor(7, {}), descriptor_103));
  }

  std::string after_transformation = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
          %2 = OpTypeVoid
          %6 = OpTypeBool
          %7 = OpConstantTrue %6
          %8 = OpConstantFalse %6
          %3 = OpTypeFunction %2
          %4 = OpFunction %2 None %3
          %5 = OpLabel
        %100 = OpCopyObject %6 %7
        %101 = OpCopyObject %6 %8
        %102 = OpCopyObject %6 %101
        %103 = OpCopyObject %6 %7
               OpReturn
               OpFunctionEnd
  )";

  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}

TEST(TransformationCopyObjectTest, CheckIllegalCases) {
  // The following SPIR-V comes from this GLSL, pushed through spirv-opt
  // and then doctored a bit.
  //
  // #version 310 es
  //
  // precision highp float;
  //
  // struct S {
  //   int a;
  //   float b;
  // };
  //
  // layout(set = 0, binding = 2) uniform block {
  //   S s;
  //   lowp float f;
  //   int ii;
  // } ubuf;
  //
  // layout(location = 0) out vec4 color;
  //
  // void main() {
  //   float c = 0.0;
  //   lowp float d = 0.0;
  //   S localS = ubuf.s;
  //   for (int i = 0; i < ubuf.s.a; i++) {
  //     switch (ubuf.ii) {
  //       case 0:
  //         c += 0.1;
  //         d += 0.2;
  //       case 1:
  //         c += 0.1;
  //         if (c > d) {
  //           d += 0.2;
  //         } else {
  //           d += c;
  //         }
  //         break;
  //       default:
  //         i += 1;
  //         localS.b += d;
  //     }
  //   }
  //   color = vec4(c, d, localS.b, 1.0);
  // }

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main" %80
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %12 "S"
               OpMemberName %12 0 "a"
               OpMemberName %12 1 "b"
               OpName %15 "S"
               OpMemberName %15 0 "a"
               OpMemberName %15 1 "b"
               OpName %16 "block"
               OpMemberName %16 0 "s"
               OpMemberName %16 1 "f"
               OpMemberName %16 2 "ii"
               OpName %18 "ubuf"
               OpName %80 "color"
               OpMemberDecorate %12 0 RelaxedPrecision
               OpMemberDecorate %15 0 RelaxedPrecision
               OpMemberDecorate %15 0 Offset 0
               OpMemberDecorate %15 1 Offset 4
               OpMemberDecorate %16 0 Offset 0
               OpMemberDecorate %16 1 RelaxedPrecision
               OpMemberDecorate %16 1 Offset 16
               OpMemberDecorate %16 2 RelaxedPrecision
               OpMemberDecorate %16 2 Offset 20
               OpDecorate %16 Block
               OpDecorate %18 DescriptorSet 0
               OpDecorate %18 Binding 2
               OpDecorate %38 RelaxedPrecision
               OpDecorate %43 RelaxedPrecision
               OpDecorate %53 RelaxedPrecision
               OpDecorate %62 RelaxedPrecision
               OpDecorate %69 RelaxedPrecision
               OpDecorate %77 RelaxedPrecision
               OpDecorate %80 Location 0
               OpDecorate %101 RelaxedPrecision
               OpDecorate %102 RelaxedPrecision
               OpDecorate %96 RelaxedPrecision
               OpDecorate %108 RelaxedPrecision
               OpDecorate %107 RelaxedPrecision
               OpDecorate %98 RelaxedPrecision
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeFloat 32
          %9 = OpConstant %6 0
         %11 = OpTypeInt 32 1
         %12 = OpTypeStruct %11 %6
         %15 = OpTypeStruct %11 %6
         %16 = OpTypeStruct %15 %6 %11
         %17 = OpTypePointer Uniform %16
         %18 = OpVariable %17 Uniform
         %19 = OpConstant %11 0
         %20 = OpTypePointer Uniform %15
         %27 = OpConstant %11 1
         %36 = OpTypePointer Uniform %11
         %39 = OpTypeBool
         %41 = OpConstant %11 2
         %48 = OpConstant %6 0.100000001
         %51 = OpConstant %6 0.200000003
         %78 = OpTypeVector %6 4
         %79 = OpTypePointer Output %78
         %80 = OpVariable %79 Output
         %85 = OpConstant %6 1
         %95 = OpUndef %12
        %112 = OpTypePointer Uniform %6
        %113 = OpTypeInt 32 0
        %114 = OpConstant %113 1
        %179 = OpTypePointer Function %39
          %4 = OpFunction %2 None %3
          %5 = OpLabel
        %180 = OpVariable %179 Function
        %181 = OpVariable %179 Function
        %182 = OpVariable %179 Function
         %21 = OpAccessChain %20 %18 %19
        %115 = OpAccessChain %112 %21 %114
        %116 = OpLoad %6 %115
         %90 = OpCompositeInsert %12 %116 %95 1
               OpBranch %30
         %30 = OpLabel
         %99 = OpPhi %12 %90 %5 %109 %47
         %98 = OpPhi %6 %9 %5 %107 %47
         %97 = OpPhi %6 %9 %5 %105 %47
         %96 = OpPhi %11 %19 %5 %77 %47
         %37 = OpAccessChain %36 %18 %19 %19
         %38 = OpLoad %11 %37
         %40 = OpSLessThan %39 %96 %38
               OpLoopMerge %32 %47 None
               OpBranchConditional %40 %31 %32
         %31 = OpLabel
         %42 = OpAccessChain %36 %18 %41
         %43 = OpLoad %11 %42
               OpSelectionMerge %45 None
               OpSwitch %43 %46 0 %44 1 %45
         %46 = OpLabel
         %69 = OpIAdd %11 %96 %27
         %72 = OpCompositeExtract %6 %99 1
         %73 = OpFAdd %6 %72 %98
         %93 = OpCompositeInsert %12 %73 %99 1
               OpBranch %47
         %44 = OpLabel
         %50 = OpFAdd %6 %97 %48
         %53 = OpFAdd %6 %98 %51
               OpBranch %45
         %45 = OpLabel
        %101 = OpPhi %6 %98 %31 %53 %44
        %100 = OpPhi %6 %97 %31 %50 %44
         %55 = OpFAdd %6 %100 %48
         %58 = OpFOrdGreaterThan %39 %55 %101
               OpSelectionMerge %60 None
               OpBranchConditional %58 %59 %63
         %59 = OpLabel
         %62 = OpFAdd %6 %101 %51
               OpBranch %60
         %63 = OpLabel
         %66 = OpFAdd %6 %101 %55
               OpBranch %60
         %60 = OpLabel
        %108 = OpPhi %6 %62 %59 %66 %63
               OpBranch %47
         %47 = OpLabel
        %109 = OpPhi %12 %93 %46 %99 %60
        %107 = OpPhi %6 %98 %46 %108 %60
        %105 = OpPhi %6 %97 %46 %55 %60
        %102 = OpPhi %11 %69 %46 %96 %60
         %77 = OpIAdd %11 %102 %27
               OpBranch %30
         %32 = OpLabel
         %84 = OpCompositeExtract %6 %99 1
         %86 = OpCompositeConstruct %78 %97 %98 %84 %85
               OpStore %80 %86
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  // Inapplicable because %18 is decorated.
  ASSERT_FALSE(TransformationCopyObject(
                   18, MakeInstructionDescriptor(21, SpvOpAccessChain, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because %77 is decorated.
  ASSERT_FALSE(TransformationCopyObject(
                   77, MakeInstructionDescriptor(77, SpvOpBranch, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because %80 is decorated.
  ASSERT_FALSE(TransformationCopyObject(
                   80, MakeInstructionDescriptor(77, SpvOpIAdd, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because %84 is not available at the requested point
  ASSERT_FALSE(
      TransformationCopyObject(
          84, MakeInstructionDescriptor(32, SpvOpCompositeExtract, 0), 200)
          .IsApplicable(context.get(), transformation_context));

  // Fine because %84 is available at the requested point
  ASSERT_TRUE(
      TransformationCopyObject(
          84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 200)
          .IsApplicable(context.get(), transformation_context));

  // Inapplicable because id %9 is already in use
  ASSERT_FALSE(
      TransformationCopyObject(
          84, MakeInstructionDescriptor(32, SpvOpCompositeConstruct, 0), 9)
          .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the requested point does not exist
  ASSERT_FALSE(TransformationCopyObject(
                   84, MakeInstructionDescriptor(86, SpvOpReturn, 2), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because %9 is not in a function
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(9, SpvOpTypeInt, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the insert point is right before, or inside, a chunk
  // of OpPhis
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(30, SpvOpPhi, 0), 200)
                   .IsApplicable(context.get(), transformation_context));
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(99, SpvOpPhi, 1), 200)
                   .IsApplicable(context.get(), transformation_context));

  // OK, because the insert point is just after a chunk of OpPhis.
  ASSERT_TRUE(TransformationCopyObject(
                  9, MakeInstructionDescriptor(96, SpvOpAccessChain, 0), 200)
                  .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the insert point is right after an OpSelectionMerge
  ASSERT_FALSE(
      TransformationCopyObject(
          9, MakeInstructionDescriptor(58, SpvOpBranchConditional, 0), 200)
          .IsApplicable(context.get(), transformation_context));

  // OK, because the insert point is right before the OpSelectionMerge
  ASSERT_TRUE(TransformationCopyObject(
                  9, MakeInstructionDescriptor(58, SpvOpSelectionMerge, 0), 200)
                  .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the insert point is right after an OpSelectionMerge
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(43, SpvOpSwitch, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // OK, because the insert point is right before the OpSelectionMerge
  ASSERT_TRUE(TransformationCopyObject(
                  9, MakeInstructionDescriptor(43, SpvOpSelectionMerge, 0), 200)
                  .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the insert point is right after an OpLoopMerge
  ASSERT_FALSE(
      TransformationCopyObject(
          9, MakeInstructionDescriptor(40, SpvOpBranchConditional, 0), 200)
          .IsApplicable(context.get(), transformation_context));

  // OK, because the insert point is right before the OpLoopMerge
  ASSERT_TRUE(TransformationCopyObject(
                  9, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200)
                  .IsApplicable(context.get(), transformation_context));

  // Inapplicable because id %300 does not exist
  ASSERT_FALSE(TransformationCopyObject(
                   300, MakeInstructionDescriptor(40, SpvOpLoopMerge, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // Inapplicable because the following instruction is OpVariable
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(180, SpvOpVariable, 0), 200)
                   .IsApplicable(context.get(), transformation_context));
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(181, SpvOpVariable, 0), 200)
                   .IsApplicable(context.get(), transformation_context));
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(182, SpvOpVariable, 0), 200)
                   .IsApplicable(context.get(), transformation_context));

  // OK, because this is just past the group of OpVariable instructions.
  ASSERT_TRUE(TransformationCopyObject(
                  9, MakeInstructionDescriptor(182, SpvOpAccessChain, 0), 200)
                  .IsApplicable(context.get(), transformation_context));
}

TEST(TransformationCopyObjectTest, MiscellaneousCopies) {
  // The following SPIR-V comes from this GLSL:
  //
  // #version 310 es
  //
  // precision highp float;
  //
  // float g;
  //
  // vec4 h;
  //
  // void main() {
  //   int a;
  //   int b;
  //   b = int(g);
  //   h.x = float(a);
  // }

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "b"
               OpName %11 "g"
               OpName %16 "h"
               OpName %17 "a"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %9 = OpTypeFloat 32
         %10 = OpTypePointer Private %9
         %11 = OpVariable %10 Private
         %14 = OpTypeVector %9 4
         %15 = OpTypePointer Private %14
         %16 = OpVariable %15 Private
         %20 = OpTypeInt 32 0
         %21 = OpConstant %20 0
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
         %17 = OpVariable %7 Function
         %12 = OpLoad %9 %11
         %13 = OpConvertFToS %6 %12
               OpStore %8 %13
         %18 = OpLoad %6 %17
         %19 = OpConvertSToF %9 %18
         %22 = OpAccessChain %10 %16 %21
               OpStore %22 %19
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  std::vector<TransformationCopyObject> transformations = {
      TransformationCopyObject(19, MakeInstructionDescriptor(22, SpvOpStore, 0),
                               100),
      TransformationCopyObject(
          22, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 101),
      TransformationCopyObject(
          12, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 102),
      TransformationCopyObject(
          11, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 103),
      TransformationCopyObject(
          16, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 104),
      TransformationCopyObject(
          8, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 105),
      TransformationCopyObject(
          17, MakeInstructionDescriptor(22, SpvOpCopyObject, 0), 106)};

  for (auto& transformation : transformations) {
    ASSERT_TRUE(
        transformation.IsApplicable(context.get(), transformation_context));
    transformation.Apply(context.get(), &transformation_context);
  }

  ASSERT_TRUE(IsValid(env, context.get()));

  std::string after_transformation = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
               OpName %4 "main"
               OpName %8 "b"
               OpName %11 "g"
               OpName %16 "h"
               OpName %17 "a"
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %9 = OpTypeFloat 32
         %10 = OpTypePointer Private %9
         %11 = OpVariable %10 Private
         %14 = OpTypeVector %9 4
         %15 = OpTypePointer Private %14
         %16 = OpVariable %15 Private
         %20 = OpTypeInt 32 0
         %21 = OpConstant %20 0
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
         %17 = OpVariable %7 Function
         %12 = OpLoad %9 %11
         %13 = OpConvertFToS %6 %12
               OpStore %8 %13
         %18 = OpLoad %6 %17
         %19 = OpConvertSToF %9 %18
         %22 = OpAccessChain %10 %16 %21
        %106 = OpCopyObject %7 %17
        %105 = OpCopyObject %7 %8
        %104 = OpCopyObject %15 %16
        %103 = OpCopyObject %10 %11
        %102 = OpCopyObject %9 %12
        %101 = OpCopyObject %10 %22
        %100 = OpCopyObject %9 %19
               OpStore %22 %19
               OpReturn
               OpFunctionEnd
  )";

  ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}

TEST(TransformationCopyObjectTest, DoNotCopyNullOrUndefPointers) {
  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %8 = OpConstantNull %7
          %9 = OpUndef %7
          %4 = OpFunction %2 None %3
          %5 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  // Illegal to copy null.
  ASSERT_FALSE(TransformationCopyObject(
                   8, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
                   .IsApplicable(context.get(), transformation_context));

  // Illegal to copy an OpUndef of pointer type.
  ASSERT_FALSE(TransformationCopyObject(
                   9, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100)
                   .IsApplicable(context.get(), transformation_context));
}

TEST(TransformationCopyObjectTest, PropagateIrrelevantPointeeFact) {
  // Checks that if a pointer is known to have an irrelevant value, the same
  // holds after the pointer is copied.

  std::string shader = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 310
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
          %8 = OpVariable %7 Function
          %9 = OpVariable %7 Function
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  ASSERT_TRUE(IsValid(env, context.get()));

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(8);

  TransformationCopyObject transformation1(
      8, MakeInstructionDescriptor(9, SpvOpReturn, 0), 100);
  TransformationCopyObject transformation2(
      9, MakeInstructionDescriptor(9, SpvOpReturn, 0), 101);
  TransformationCopyObject transformation3(
      100, MakeInstructionDescriptor(9, SpvOpReturn, 0), 102);

  ASSERT_TRUE(
      transformation1.IsApplicable(context.get(), transformation_context));
  transformation1.Apply(context.get(), &transformation_context);
  ASSERT_TRUE(
      transformation2.IsApplicable(context.get(), transformation_context));
  transformation2.Apply(context.get(), &transformation_context);
  ASSERT_TRUE(
      transformation3.IsApplicable(context.get(), transformation_context));
  transformation3.Apply(context.get(), &transformation_context);

  ASSERT_TRUE(
      transformation_context.GetFactManager()->PointeeValueIsIrrelevant(8));
  ASSERT_TRUE(
      transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100));
  ASSERT_TRUE(
      transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102));
  ASSERT_FALSE(
      transformation_context.GetFactManager()->PointeeValueIsIrrelevant(9));
  ASSERT_FALSE(
      transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
}

TEST(TransformationCopyObject, DoNotCopyOpSampledImage) {
  // This checks that we do not try to copy the result id of an OpSampledImage
  // instruction.
  std::string shader = R"(
               OpCapability Shader
               OpCapability SampledBuffer
               OpCapability ImageBuffer
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %2 "main" %40 %41
               OpExecutionMode %2 OriginUpperLeft
               OpSource GLSL 450
               OpDecorate %40 DescriptorSet 0
               OpDecorate %40 Binding 69
               OpDecorate %41 DescriptorSet 0
               OpDecorate %41 Binding 1
         %54 = OpTypeFloat 32
         %76 = OpTypeVector %54 4
         %55 = OpConstant %54 0
         %56 = OpTypeVector %54 3
         %94 = OpTypeVector %54 2
        %112 = OpConstantComposite %94 %55 %55
         %57 = OpConstantComposite %56 %55 %55 %55
         %15 = OpTypeImage %54 2D 2 0 0 1 Unknown
        %114 = OpTypePointer UniformConstant %15
         %38 = OpTypeSampler
        %125 = OpTypePointer UniformConstant %38
        %132 = OpTypeVoid
        %133 = OpTypeFunction %132
         %45 = OpTypeSampledImage %15
         %40 = OpVariable %114 UniformConstant
         %41 = OpVariable %125 UniformConstant
          %2 = OpFunction %132 None %133
        %164 = OpLabel
        %184 = OpLoad %15 %40
        %213 = OpLoad %38 %41
        %216 = OpSampledImage %45 %184 %213
        %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55
               OpReturn
               OpFunctionEnd
  )";

  const auto env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = nullptr;
  const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);

  FactManager fact_manager;
  spvtools::ValidatorOptions validator_options;
  TransformationContext transformation_context(&fact_manager,
                                               validator_options);

  ASSERT_FALSE(
      TransformationCopyObject(
          216, MakeInstructionDescriptor(217, SpvOpImageSampleImplicitLod, 0),
          500)
          .IsApplicable(context.get(), transformation_context));
}

}  // namespace
}  // namespace fuzz
}  // namespace spvtools
