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