1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google Inc.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci#include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h"
18fd4e5da5Sopenharmony_ci#include "source/reduce/reduction_opportunity.h"
19fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h"
20fd4e5da5Sopenharmony_ci
21fd4e5da5Sopenharmony_cinamespace spvtools {
22fd4e5da5Sopenharmony_cinamespace reduce {
23fd4e5da5Sopenharmony_cinamespace {
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ciTEST(OperandToDominatingIdReductionPassTest, BasicCheck) {
26fd4e5da5Sopenharmony_ci  std::string original = R"(
27fd4e5da5Sopenharmony_ci               OpCapability Shader
28fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
29fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
30fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
31fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
32fd4e5da5Sopenharmony_ci               OpSource ESSL 310
33fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
34fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
35fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
36fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
37fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 2
38fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
39fd4e5da5Sopenharmony_ci          %5 = OpLabel
40fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
41fd4e5da5Sopenharmony_ci         %10 = OpVariable %7 Function
42fd4e5da5Sopenharmony_ci         %14 = OpVariable %7 Function
43fd4e5da5Sopenharmony_ci               OpStore %8 %9
44fd4e5da5Sopenharmony_ci         %11 = OpLoad %6 %8
45fd4e5da5Sopenharmony_ci         %12 = OpLoad %6 %8
46fd4e5da5Sopenharmony_ci         %13 = OpIAdd %6 %11 %12
47fd4e5da5Sopenharmony_ci               OpStore %10 %13
48fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %10
49fd4e5da5Sopenharmony_ci               OpStore %14 %15
50fd4e5da5Sopenharmony_ci               OpReturn
51fd4e5da5Sopenharmony_ci               OpFunctionEnd
52fd4e5da5Sopenharmony_ci  )";
53fd4e5da5Sopenharmony_ci
54fd4e5da5Sopenharmony_ci  const auto env = SPV_ENV_UNIVERSAL_1_3;
55fd4e5da5Sopenharmony_ci  const auto consumer = nullptr;
56fd4e5da5Sopenharmony_ci  const auto context =
57fd4e5da5Sopenharmony_ci      BuildModule(env, consumer, original, kReduceAssembleOption);
58fd4e5da5Sopenharmony_ci  const auto ops = OperandToDominatingIdReductionOpportunityFinder()
59fd4e5da5Sopenharmony_ci                       .GetAvailableOpportunities(context.get(), 0);
60fd4e5da5Sopenharmony_ci  ASSERT_EQ(10, ops.size());
61fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[0]->PreconditionHolds());
62fd4e5da5Sopenharmony_ci  ops[0]->TryToApply();
63fd4e5da5Sopenharmony_ci
64fd4e5da5Sopenharmony_ci  std::string after_op_0 = R"(
65fd4e5da5Sopenharmony_ci               OpCapability Shader
66fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
67fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
68fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
69fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
70fd4e5da5Sopenharmony_ci               OpSource ESSL 310
71fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
72fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
73fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
74fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
75fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 2
76fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
77fd4e5da5Sopenharmony_ci          %5 = OpLabel
78fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
79fd4e5da5Sopenharmony_ci         %10 = OpVariable %7 Function
80fd4e5da5Sopenharmony_ci         %14 = OpVariable %7 Function
81fd4e5da5Sopenharmony_ci               OpStore %8 %9
82fd4e5da5Sopenharmony_ci         %11 = OpLoad %6 %8
83fd4e5da5Sopenharmony_ci         %12 = OpLoad %6 %8
84fd4e5da5Sopenharmony_ci         %13 = OpIAdd %6 %11 %12
85fd4e5da5Sopenharmony_ci               OpStore %8 %13 ; %10 -> %8
86fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %10
87fd4e5da5Sopenharmony_ci               OpStore %14 %15
88fd4e5da5Sopenharmony_ci               OpReturn
89fd4e5da5Sopenharmony_ci               OpFunctionEnd
90fd4e5da5Sopenharmony_ci  )";
91fd4e5da5Sopenharmony_ci
92fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_0, context.get());
93fd4e5da5Sopenharmony_ci
94fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[1]->PreconditionHolds());
95fd4e5da5Sopenharmony_ci  ops[1]->TryToApply();
96fd4e5da5Sopenharmony_ci
97fd4e5da5Sopenharmony_ci  std::string after_op_1 = R"(
98fd4e5da5Sopenharmony_ci               OpCapability Shader
99fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
100fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
101fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
102fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
103fd4e5da5Sopenharmony_ci               OpSource ESSL 310
104fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
105fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
106fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
107fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
108fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 2
109fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
110fd4e5da5Sopenharmony_ci          %5 = OpLabel
111fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
112fd4e5da5Sopenharmony_ci         %10 = OpVariable %7 Function
113fd4e5da5Sopenharmony_ci         %14 = OpVariable %7 Function
114fd4e5da5Sopenharmony_ci               OpStore %8 %9
115fd4e5da5Sopenharmony_ci         %11 = OpLoad %6 %8
116fd4e5da5Sopenharmony_ci         %12 = OpLoad %6 %8
117fd4e5da5Sopenharmony_ci         %13 = OpIAdd %6 %11 %12
118fd4e5da5Sopenharmony_ci               OpStore %8 %13 ; %10 -> %8
119fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8 ; %10 -> %8
120fd4e5da5Sopenharmony_ci               OpStore %14 %15
121fd4e5da5Sopenharmony_ci               OpReturn
122fd4e5da5Sopenharmony_ci               OpFunctionEnd
123fd4e5da5Sopenharmony_ci  )";
124fd4e5da5Sopenharmony_ci
125fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_1, context.get());
126fd4e5da5Sopenharmony_ci
127fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[2]->PreconditionHolds());
128fd4e5da5Sopenharmony_ci  ops[2]->TryToApply();
129fd4e5da5Sopenharmony_ci
130fd4e5da5Sopenharmony_ci  std::string after_op_2 = R"(
131fd4e5da5Sopenharmony_ci               OpCapability Shader
132fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
133fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
134fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
135fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
136fd4e5da5Sopenharmony_ci               OpSource ESSL 310
137fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
138fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
139fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
140fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
141fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 2
142fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
143fd4e5da5Sopenharmony_ci          %5 = OpLabel
144fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
145fd4e5da5Sopenharmony_ci         %10 = OpVariable %7 Function
146fd4e5da5Sopenharmony_ci         %14 = OpVariable %7 Function
147fd4e5da5Sopenharmony_ci               OpStore %8 %9
148fd4e5da5Sopenharmony_ci         %11 = OpLoad %6 %8
149fd4e5da5Sopenharmony_ci         %12 = OpLoad %6 %8
150fd4e5da5Sopenharmony_ci         %13 = OpIAdd %6 %11 %12
151fd4e5da5Sopenharmony_ci               OpStore %8 %13 ; %10 -> %8
152fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8 ; %10 -> %8
153fd4e5da5Sopenharmony_ci               OpStore %8 %15 ; %14 -> %8
154fd4e5da5Sopenharmony_ci               OpReturn
155fd4e5da5Sopenharmony_ci               OpFunctionEnd
156fd4e5da5Sopenharmony_ci  )";
157fd4e5da5Sopenharmony_ci
158fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_2, context.get());
159fd4e5da5Sopenharmony_ci
160fd4e5da5Sopenharmony_ci  // The precondition has been disabled by an earlier opportunity's application.
161fd4e5da5Sopenharmony_ci  ASSERT_FALSE(ops[3]->PreconditionHolds());
162fd4e5da5Sopenharmony_ci
163fd4e5da5Sopenharmony_ci  ASSERT_TRUE(ops[4]->PreconditionHolds());
164fd4e5da5Sopenharmony_ci  ops[4]->TryToApply();
165fd4e5da5Sopenharmony_ci
166fd4e5da5Sopenharmony_ci  std::string after_op_4 = R"(
167fd4e5da5Sopenharmony_ci               OpCapability Shader
168fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
169fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
170fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
171fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
172fd4e5da5Sopenharmony_ci               OpSource ESSL 310
173fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
174fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
175fd4e5da5Sopenharmony_ci          %6 = OpTypeInt 32 1
176fd4e5da5Sopenharmony_ci          %7 = OpTypePointer Function %6
177fd4e5da5Sopenharmony_ci          %9 = OpConstant %6 2
178fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
179fd4e5da5Sopenharmony_ci          %5 = OpLabel
180fd4e5da5Sopenharmony_ci          %8 = OpVariable %7 Function
181fd4e5da5Sopenharmony_ci         %10 = OpVariable %7 Function
182fd4e5da5Sopenharmony_ci         %14 = OpVariable %7 Function
183fd4e5da5Sopenharmony_ci               OpStore %8 %9
184fd4e5da5Sopenharmony_ci         %11 = OpLoad %6 %8
185fd4e5da5Sopenharmony_ci         %12 = OpLoad %6 %8
186fd4e5da5Sopenharmony_ci         %13 = OpIAdd %6 %11 %11 ; %12 -> %11
187fd4e5da5Sopenharmony_ci               OpStore %8 %13 ; %10 -> %8
188fd4e5da5Sopenharmony_ci         %15 = OpLoad %6 %8 ; %10 -> %8
189fd4e5da5Sopenharmony_ci               OpStore %8 %15 ; %14 -> %8
190fd4e5da5Sopenharmony_ci               OpReturn
191fd4e5da5Sopenharmony_ci               OpFunctionEnd
192fd4e5da5Sopenharmony_ci  )";
193fd4e5da5Sopenharmony_ci  CheckEqual(env, after_op_4, context.get());
194fd4e5da5Sopenharmony_ci}
195fd4e5da5Sopenharmony_ci
196fd4e5da5Sopenharmony_ci}  // namespace
197fd4e5da5Sopenharmony_ci}  // namespace reduce
198fd4e5da5Sopenharmony_ci}  // namespace spvtools
199