1 // Copyright (c) 2024 Google LLC
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 "assembly_builder.h"
16 #include "pass_fixture.h"
17 #include "pass_utils.h"
18
19 namespace {
20
21 using namespace spvtools;
22
23 using ModifyMaximalReconvergenceTest = opt::PassTest<::testing::Test>;
24
TEST_F(ModifyMaximalReconvergenceTest,AddNoEntryPoint)25 TEST_F(ModifyMaximalReconvergenceTest, AddNoEntryPoint) {
26 const std::string text = R"(
27 ; CHECK-NOT: OpExtension
28 OpCapability Kernel
29 OpCapability Linkage
30 OpMemoryModel Logical OpenCL
31 )";
32
33 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
34 }
35
TEST_F(ModifyMaximalReconvergenceTest,AddSingleEntryPoint)36 TEST_F(ModifyMaximalReconvergenceTest, AddSingleEntryPoint) {
37 const std::string text = R"(
38 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
39 ; CHECK: OpExecutionMode %main MaximallyReconvergesKHR
40
41 OpCapability Shader
42 OpMemoryModel Logical GLSL450
43 OpEntryPoint GLCompute %main "main"
44 OpExecutionMode %main LocalSize 1 1 1
45 OpName %main "main"
46 %void = OpTypeVoid
47 %void_fn = OpTypeFunction %void
48 %main = OpFunction %void None %void_fn
49 %entry = OpLabel
50 OpReturn
51 OpFunctionEnd
52 )";
53
54 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
55 }
56
TEST_F(ModifyMaximalReconvergenceTest,AddExtensionExists)57 TEST_F(ModifyMaximalReconvergenceTest, AddExtensionExists) {
58 const std::string text = R"(
59 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
60 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
61 ; CHECK: OpExecutionMode %main MaximallyReconvergesKHR
62
63 OpCapability Shader
64 OpExtension "SPV_KHR_maximal_reconvergence"
65 OpMemoryModel Logical GLSL450
66 OpEntryPoint GLCompute %main "main"
67 OpExecutionMode %main LocalSize 1 1 1
68 OpName %main "main"
69 %void = OpTypeVoid
70 %void_fn = OpTypeFunction %void
71 %main = OpFunction %void None %void_fn
72 %entry = OpLabel
73 OpReturn
74 OpFunctionEnd
75 )";
76
77 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
78 }
79
TEST_F(ModifyMaximalReconvergenceTest,AddExecutionModeExists)80 TEST_F(ModifyMaximalReconvergenceTest, AddExecutionModeExists) {
81 const std::string text = R"(
82 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
83 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
84 ; CHECK: OpExecutionMode %main LocalSize 1 1 1
85 ; CHECK-NEXT: OpExecutionMode %main MaximallyReconvergesKHR
86 ; CHECK-NOT: OpExecutionMode %main MaximallyReconvergesKHR
87
88 OpCapability Shader
89 OpExtension "SPV_KHR_maximal_reconvergence"
90 OpMemoryModel Logical GLSL450
91 OpEntryPoint GLCompute %main "main"
92 OpExecutionMode %main LocalSize 1 1 1
93 OpExecutionMode %main MaximallyReconvergesKHR
94 OpName %main "main"
95 %void = OpTypeVoid
96 %void_fn = OpTypeFunction %void
97 %main = OpFunction %void None %void_fn
98 %entry = OpLabel
99 OpReturn
100 OpFunctionEnd
101 )";
102
103 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
104 }
105
TEST_F(ModifyMaximalReconvergenceTest,AddTwoEntryPoints)106 TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPoints) {
107 const std::string text = R"(
108 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
109 ; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
110 ; CHECK: OpExecutionMode %frag MaximallyReconvergesKHR
111
112 OpCapability Shader
113 OpMemoryModel Logical GLSL450
114 OpEntryPoint GLCompute %comp "main"
115 OpEntryPoint Fragment %frag "main"
116 OpExecutionMode %comp LocalSize 1 1 1
117 OpExecutionMode %frag OriginUpperLeft
118 OpName %comp "comp"
119 OpName %frag "frag"
120 %void = OpTypeVoid
121 %void_fn = OpTypeFunction %void
122 %comp = OpFunction %void None %void_fn
123 %entry1 = OpLabel
124 OpReturn
125 OpFunctionEnd
126 %frag = OpFunction %void None %void_fn
127 %entry2 = OpLabel
128 OpReturn
129 OpFunctionEnd
130 )";
131
132 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
133 }
134
TEST_F(ModifyMaximalReconvergenceTest,AddTwoEntryPointsOneFunc)135 TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPointsOneFunc) {
136 const std::string text = R"(
137 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
138 ; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
139 ; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
140
141 OpCapability Shader
142 OpMemoryModel Logical GLSL450
143 OpEntryPoint GLCompute %comp "main1"
144 OpEntryPoint GLCompute %comp "main2"
145 OpExecutionMode %comp LocalSize 1 1 1
146 OpName %comp "comp"
147 %void = OpTypeVoid
148 %void_fn = OpTypeFunction %void
149 %comp = OpFunction %void None %void_fn
150 %entry1 = OpLabel
151 OpReturn
152 OpFunctionEnd
153 )";
154
155 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
156 }
157
TEST_F(ModifyMaximalReconvergenceTest,AddTwoEntryPointsOneExecutionMode)158 TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPointsOneExecutionMode) {
159 const std::string text = R"(
160 ; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
161 ; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
162 ; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
163 ; CHECK: OpExecutionMode %frag MaximallyReconvergesKHR
164 ; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
165
166 OpCapability Shader
167 OpExtension "SPV_KHR_maximal_reconvergence"
168 OpMemoryModel Logical GLSL450
169 OpEntryPoint GLCompute %comp "main"
170 OpEntryPoint Fragment %frag "main"
171 OpExecutionMode %comp LocalSize 1 1 1
172 OpExecutionMode %frag OriginUpperLeft
173 OpExecutionMode %comp MaximallyReconvergesKHR
174 OpName %comp "comp"
175 OpName %frag "frag"
176 %void = OpTypeVoid
177 %void_fn = OpTypeFunction %void
178 %comp = OpFunction %void None %void_fn
179 %entry1 = OpLabel
180 OpReturn
181 OpFunctionEnd
182 %frag = OpFunction %void None %void_fn
183 %entry2 = OpLabel
184 OpReturn
185 OpFunctionEnd
186 )";
187
188 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
189 }
190
TEST_F(ModifyMaximalReconvergenceTest,RemoveNoEntryPoint)191 TEST_F(ModifyMaximalReconvergenceTest, RemoveNoEntryPoint) {
192 const std::string text = R"(OpCapability Kernel
193 OpCapability Linkage
194 OpMemoryModel Logical OpenCL
195 )";
196
197 SinglePassRunAndCheck<opt::ModifyMaximalReconvergence>(text, text, false,
198 true, false);
199 }
200
TEST_F(ModifyMaximalReconvergenceTest,RemoveOnlyExtension)201 TEST_F(ModifyMaximalReconvergenceTest, RemoveOnlyExtension) {
202 const std::string text = R"(
203 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
204 ; CHECK: OpExecutionMode %main LocalSize 1 1 1
205
206 OpCapability Shader
207 OpExtension "SPV_KHR_maximal_reconvergence"
208 OpMemoryModel Logical GLSL450
209 OpEntryPoint GLCompute %main "main"
210 OpExecutionMode %main LocalSize 1 1 1
211 OpName %main "main"
212 %void = OpTypeVoid
213 %void_fn = OpTypeFunction %void
214 %main = OpFunction %void None %void_fn
215 %entry = OpLabel
216 OpReturn
217 OpFunctionEnd
218 )";
219
220 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
221 }
222
TEST_F(ModifyMaximalReconvergenceTest,RemoveSingleEntryPoint)223 TEST_F(ModifyMaximalReconvergenceTest, RemoveSingleEntryPoint) {
224 const std::string text = R"(
225 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
226 ; CHECK: OpExecutionMode %main LocalSize 1 1 1
227 ; CHECK-NOT: OpExecutionMode %main MaximallyReconvergesKHR
228
229 OpCapability Shader
230 OpExtension "SPV_KHR_maximal_reconvergence"
231 OpMemoryModel Logical GLSL450
232 OpEntryPoint GLCompute %main "main"
233 OpExecutionMode %main LocalSize 1 1 1
234 OpExecutionMode %main MaximallyReconvergesKHR
235 OpName %main "main"
236 %void = OpTypeVoid
237 %void_fn = OpTypeFunction %void
238 %main = OpFunction %void None %void_fn
239 %entry = OpLabel
240 OpReturn
241 OpFunctionEnd
242 )";
243
244 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
245 }
246
TEST_F(ModifyMaximalReconvergenceTest,RemoveTwoEntryPointsOneExecutionMode)247 TEST_F(ModifyMaximalReconvergenceTest, RemoveTwoEntryPointsOneExecutionMode) {
248 const std::string text = R"(
249 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
250 ; CHECK: OpExecutionMode %comp LocalSize 1 1 1
251 ; CHECK-NEXT: OpExecutionMode %frag OriginUpperLeft
252 ; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
253
254 OpCapability Shader
255 OpExtension "SPV_KHR_maximal_reconvergence"
256 OpMemoryModel Logical GLSL450
257 OpEntryPoint GLCompute %comp "main"
258 OpEntryPoint Fragment %frag "main"
259 OpExecutionMode %comp LocalSize 1 1 1
260 OpExecutionMode %comp MaximallyReconvergesKHR
261 OpExecutionMode %frag OriginUpperLeft
262 OpName %comp "comp"
263 OpName %frag "frag"
264 %void = OpTypeVoid
265 %void_fn = OpTypeFunction %void
266 %comp = OpFunction %void None %void_fn
267 %entry1 = OpLabel
268 OpReturn
269 OpFunctionEnd
270 %frag = OpFunction %void None %void_fn
271 %entry2 = OpLabel
272 OpReturn
273 OpFunctionEnd
274 )";
275
276 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
277 }
278
TEST_F(ModifyMaximalReconvergenceTest,RemoveTwoEntryPoints)279 TEST_F(ModifyMaximalReconvergenceTest, RemoveTwoEntryPoints) {
280 const std::string text = R"(
281 ; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
282 ; CHECK: OpExecutionMode %comp LocalSize 1 1 1
283 ; CHECK-NEXT: OpExecutionMode %frag OriginUpperLeft
284 ; CHECK-NOT: OpExecutionMode {{%\w}} MaximallyReconvergesKHR
285
286 OpCapability Shader
287 OpExtension "SPV_KHR_maximal_reconvergence"
288 OpMemoryModel Logical GLSL450
289 OpEntryPoint GLCompute %comp "main"
290 OpEntryPoint Fragment %frag "main"
291 OpExecutionMode %comp LocalSize 1 1 1
292 OpExecutionMode %comp MaximallyReconvergesKHR
293 OpExecutionMode %frag OriginUpperLeft
294 OpExecutionMode %frag MaximallyReconvergesKHR
295 OpName %comp "comp"
296 OpName %frag "frag"
297 %void = OpTypeVoid
298 %void_fn = OpTypeFunction %void
299 %comp = OpFunction %void None %void_fn
300 %entry1 = OpLabel
301 OpReturn
302 OpFunctionEnd
303 %frag = OpFunction %void None %void_fn
304 %entry2 = OpLabel
305 OpReturn
306 OpFunctionEnd
307 )";
308
309 SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
310 }
311
312 } // namespace
313