// Copyright (c) 2018 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 "opt/simplification_pass.h"

#include "assembly_builder.h"
#include "gmock/gmock.h"
#include "pass_fixture.h"

namespace spvtools {
namespace opt {
namespace {

using SimplificationTest = PassTest<::testing::Test>;

#ifdef SPIRV_EFFCEE
TEST_F(SimplificationTest, StraightLineTest) {
  // Testing that folding rules are combined in simple straight line code.
  const std::string text = R"(OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %i %o
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 430
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %main "main"
               OpName %i "i"
               OpName %o "o"
               OpDecorate %i Flat
               OpDecorate %i Location 0
               OpDecorate %o Location 0
       %void = OpTypeVoid
          %8 = OpTypeFunction %void
        %int = OpTypeInt 32 1
      %v4int = OpTypeVector %int 4
      %int_0 = OpConstant %int 0
         %13 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
      %int_1 = OpConstant %int 1
%_ptr_Input_v4int = OpTypePointer Input %v4int
          %i = OpVariable %_ptr_Input_v4int Input
%_ptr_Output_int = OpTypePointer Output %int
          %o = OpVariable %_ptr_Output_int Output
       %main = OpFunction %void None %8
         %21 = OpLabel
         %31 = OpCompositeInsert %v4int %int_1 %13 0
; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad
         %23 = OpLoad %v4int %i
         %33 = OpCompositeInsert %v4int %int_0 %23 0
         %35 = OpCompositeExtract %int %31 0
; CHECK: [[extract:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 1
         %37 = OpCompositeExtract %int %33 1
; CHECK: [[add:%[a-zA-Z_\d]+]] = OpIAdd %int %int_1 [[extract]]
         %29 = OpIAdd %int %35 %37
               OpStore %o %29
               OpReturn
               OpFunctionEnd
)";

  SinglePassRunAndMatch<SimplificationPass>(text, false);
}

TEST_F(SimplificationTest, AcrossBasicBlocks) {
  // Testing that folding rules are combined across basic blocks.
  const std::string text = R"(OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %i %o
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 430
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %main "main"
               OpName %i "i"
               OpName %o "o"
               OpDecorate %i Flat
               OpDecorate %i Location 0
               OpDecorate %o Location 0
       %void = OpTypeVoid
          %8 = OpTypeFunction %void
        %int = OpTypeInt 32 1
      %v4int = OpTypeVector %int 4
      %int_0 = OpConstant %int 0
%_ptr_Input_v4int = OpTypePointer Input %v4int
          %i = OpVariable %_ptr_Input_v4int Input
       %uint = OpTypeInt 32 0
     %uint_0 = OpConstant %uint 0
%_ptr_Input_int = OpTypePointer Input %int
     %int_10 = OpConstant %int 10
       %bool = OpTypeBool
      %int_1 = OpConstant %int 1
%_ptr_Output_int = OpTypePointer Output %int
          %o = OpVariable %_ptr_Output_int Output
       %main = OpFunction %void None %8
         %24 = OpLabel
; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad %v4int %i
         %25 = OpLoad %v4int %i
         %41 = OpCompositeInsert %v4int %int_0 %25 0
         %27 = OpAccessChain %_ptr_Input_int %i %uint_0
         %28 = OpLoad %int %27
         %29 = OpSGreaterThan %bool %28 %int_10
               OpSelectionMerge %30 None
               OpBranchConditional %29 %31 %32
         %31 = OpLabel
         %43 = OpCopyObject %v4int %25
               OpBranch %30
         %32 = OpLabel
         %45 = OpCopyObject %v4int %25
               OpBranch %30
         %30 = OpLabel
         %50 = OpPhi %v4int %43 %31 %45 %32
; CHECK: [[extract1:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 0
         %47 = OpCompositeExtract %int %50 0
; CHECK: [[extract2:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 1
         %49 = OpCompositeExtract %int %41 1
; CHECK: [[add:%[a-zA-Z_\d]+]] = OpIAdd %int [[extract1]] [[extract2]]
         %39 = OpIAdd %int %47 %49
               OpStore %o %39
               OpReturn
               OpFunctionEnd

)";

  SinglePassRunAndMatch<SimplificationPass>(text, false);
}

TEST_F(SimplificationTest, ThroughLoops) {
  // Testing that folding rules are applied multiple times to instructions
  // to be able to propagate across loop iterations.
  const std::string text = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %main "main" %o %i
               OpExecutionMode %main OriginUpperLeft
               OpSource GLSL 430
               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
               OpSourceExtension "GL_GOOGLE_include_directive"
               OpName %main "main"
               OpName %o "o"
               OpName %i "i"
               OpDecorate %o Location 0
               OpDecorate %i Flat
               OpDecorate %i Location 0
       %void = OpTypeVoid
          %8 = OpTypeFunction %void
        %int = OpTypeInt 32 1
      %v4int = OpTypeVector %int 4
      %int_0 = OpConstant %int 0
; CHECK: [[constant:%[a-zA-Z_\d]+]] = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
         %13 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
       %bool = OpTypeBool
%_ptr_Output_int = OpTypePointer Output %int
          %o = OpVariable %_ptr_Output_int Output
%_ptr_Input_v4int = OpTypePointer Input %v4int
          %i = OpVariable %_ptr_Input_v4int Input
         %68 = OpUndef %v4int
       %main = OpFunction %void None %8
         %23 = OpLabel
; CHECK: [[load:%[a-zA-Z_\d]+]] = OpLoad %v4int %i
       %load = OpLoad %v4int %i
               OpBranch %24
         %24 = OpLabel
         %67 = OpPhi %v4int %load %23 %64 %26
; CHECK: OpLoopMerge [[merge_lab:%[a-zA-Z_\d]+]]
               OpLoopMerge %25 %26 None
               OpBranch %27
         %27 = OpLabel
         %48 = OpCompositeExtract %int %67 0
         %30 = OpIEqual %bool %48 %int_0
               OpBranchConditional %30 %31 %25
         %31 = OpLabel
         %50 = OpCompositeExtract %int %67 0
         %54 = OpCompositeExtract %int %67 1
         %58 = OpCompositeExtract %int %67 2
         %62 = OpCompositeExtract %int %67 3
	 %64 = OpCompositeConstruct %v4int %50 %54 %58 %62
               OpBranch %26
         %26 = OpLabel
               OpBranch %24
         %25 = OpLabel
; CHECK: [[merge_lab]] = OpLabel
; CHECK: [[extract:%[a-zA-Z_\d]+]] = OpCompositeExtract %int [[load]] 0
         %66 = OpCompositeExtract %int %67 0
; CHECK-NEXT: OpStore %o [[extract]]
               OpStore %o %66
               OpReturn
               OpFunctionEnd
)";

  SinglePassRunAndMatch<SimplificationPass>(text, false);
}

#endif

}  // namespace
}  // namespace opt
}  // namespace spvtools
