1 // Copyright (c) 2018 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 "gmock/gmock.h"
17 #include "pass_fixture.h"
18 #include "pass_utils.h"
19 
20 namespace {
21 
22 using namespace spvtools;
23 
24 using UpgradeMemoryModelTest = opt::PassTest<::testing::Test>;
25 
26 #ifdef SPIRV_EFFCEE
TEST_F(UpgradeMemoryModelTest,InvalidMemoryModelOpenCL)27 TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelOpenCL) {
28   const std::string text = R"(
29 ; CHECK: OpMemoryModel Logical OpenCL
30 OpCapability Kernel
31 OpCapability Linkage
32 OpMemoryModel Logical OpenCL
33 )";
34 
35   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
36 }
37 
TEST_F(UpgradeMemoryModelTest,InvalidMemoryModelVulkanKHR)38 TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelVulkanKHR) {
39   const std::string text = R"(
40 ; CHECK: OpMemoryModel Logical VulkanKHR
41 OpCapability Shader
42 OpCapability Linkage
43 OpCapability VulkanMemoryModelKHR
44 OpExtension "SPV_KHR_vulkan_memory_model"
45 OpMemoryModel Logical VulkanKHR
46 )";
47 
48   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
49 }
50 
TEST_F(UpgradeMemoryModelTest,JustMemoryModel)51 TEST_F(UpgradeMemoryModelTest, JustMemoryModel) {
52   const std::string text = R"(
53 ; CHECK: OpCapability VulkanMemoryModelKHR
54 ; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
55 ; CHECK: OpMemoryModel Logical VulkanKHR
56 OpCapability Shader
57 OpCapability Linkage
58 OpMemoryModel Logical GLSL450
59 )";
60 
61   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
62 }
63 
TEST_F(UpgradeMemoryModelTest,RemoveDecorations)64 TEST_F(UpgradeMemoryModelTest, RemoveDecorations) {
65   const std::string text = R"(
66 ; CHECK-NOT: OpDecorate
67 OpCapability Shader
68 OpCapability Linkage
69 OpMemoryModel Logical GLSL450
70 OpDecorate %var Volatile
71 OpDecorate %var Coherent
72 %int = OpTypeInt 32 0
73 %ptr_int_Uniform = OpTypePointer Uniform %int
74 %var = OpVariable %ptr_int_Uniform Uniform
75 )";
76 
77   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
78 }
79 
TEST_F(UpgradeMemoryModelTest,WorkgroupVariable)80 TEST_F(UpgradeMemoryModelTest, WorkgroupVariable) {
81   const std::string text = R"(
82 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
83 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
84 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
85 OpCapability Shader
86 OpCapability Linkage
87 OpMemoryModel Logical GLSL450
88 %void = OpTypeVoid
89 %int = OpTypeInt 32 0
90 %ptr_int_Workgroup = OpTypePointer Workgroup %int
91 %var = OpVariable %ptr_int_Workgroup Workgroup
92 %func_ty = OpTypeFunction %void
93 %func = OpFunction %void None %func_ty
94 %1 = OpLabel
95 %ld = OpLoad %int %var
96 %st = OpStore %var %ld
97 OpReturn
98 OpFunctionEnd
99 )";
100 
101   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
102 }
103 
TEST_F(UpgradeMemoryModelTest,WorkgroupFunctionParameter)104 TEST_F(UpgradeMemoryModelTest, WorkgroupFunctionParameter) {
105   const std::string text = R"(
106 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
107 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
108 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
109 OpCapability Shader
110 OpCapability Linkage
111 OpMemoryModel Logical GLSL450
112 %void = OpTypeVoid
113 %int = OpTypeInt 32 0
114 %ptr_int_Workgroup = OpTypePointer Workgroup %int
115 %func_ty = OpTypeFunction %void %ptr_int_Workgroup
116 %func = OpFunction %void None %func_ty
117 %param = OpFunctionParameter %ptr_int_Workgroup
118 %1 = OpLabel
119 %ld = OpLoad %int %param
120 %st = OpStore %param %ld
121 OpReturn
122 OpFunctionEnd
123 )";
124 
125   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
126 }
127 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariable)128 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariable) {
129   const std::string text = R"(
130 ; CHECK-NOT: OpDecorate
131 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
132 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
133 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
134 OpCapability Shader
135 OpCapability Linkage
136 OpMemoryModel Logical GLSL450
137 OpDecorate %var Coherent
138 OpDecorate %var Volatile
139 %void = OpTypeVoid
140 %int = OpTypeInt 32 0
141 %ptr_int_Uniform = OpTypePointer Uniform %int
142 %var = OpVariable %ptr_int_Uniform Uniform
143 %func_ty = OpTypeFunction %void
144 %func = OpFunction %void None %func_ty
145 %1 = OpLabel
146 %ld = OpLoad %int %var
147 OpStore %var %ld
148 OpReturn
149 OpFunctionEnd
150 )";
151 
152   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
153 }
154 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameter)155 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameter) {
156   const std::string text = R"(
157 ; CHECK-NOT: OpDecorate
158 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
159 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
160 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
161 OpCapability Shader
162 OpCapability Linkage
163 OpMemoryModel Logical GLSL450
164 OpDecorate %param Coherent
165 OpDecorate %param Volatile
166 %void = OpTypeVoid
167 %int = OpTypeInt 32 0
168 %ptr_int_Uniform = OpTypePointer Uniform %int
169 %func_ty = OpTypeFunction %void %ptr_int_Uniform
170 %func = OpFunction %void None %func_ty
171 %param = OpFunctionParameter %ptr_int_Uniform
172 %1 = OpLabel
173 %ld = OpLoad %int %param
174 OpStore %param %ld
175 OpReturn
176 OpFunctionEnd
177 )";
178 
179   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
180 }
181 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableOnlyVolatile)182 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableOnlyVolatile) {
183   const std::string text = R"(
184 ; CHECK-NOT: OpDecorate
185 ; CHECK-NOT: OpConstant
186 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
187 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile
188 OpCapability Shader
189 OpCapability Linkage
190 OpMemoryModel Logical GLSL450
191 OpDecorate %var Volatile
192 %void = OpTypeVoid
193 %int = OpTypeInt 32 0
194 %ptr_int_Uniform = OpTypePointer Uniform %int
195 %var = OpVariable %ptr_int_Uniform Uniform
196 %func_ty = OpTypeFunction %void
197 %func = OpFunction %void None %func_ty
198 %1 = OpLabel
199 %ld = OpLoad %int %var
200 OpStore %var %ld
201 OpReturn
202 OpFunctionEnd
203 )";
204 
205   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
206 }
207 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableCopied)208 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableCopied) {
209   const std::string text = R"(
210 ; CHECK-NOT: OpDecorate
211 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
212 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
213 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
214 OpCapability Shader
215 OpCapability Linkage
216 OpMemoryModel Logical GLSL450
217 OpDecorate %var Coherent
218 OpDecorate %var Volatile
219 %void = OpTypeVoid
220 %int = OpTypeInt 32 0
221 %ptr_int_Uniform = OpTypePointer Uniform %int
222 %var = OpVariable %ptr_int_Uniform Uniform
223 %func_ty = OpTypeFunction %void
224 %func = OpFunction %void None %func_ty
225 %1 = OpLabel
226 %copy = OpCopyObject %ptr_int_Uniform %var
227 %ld = OpLoad %int %copy
228 OpStore %copy %ld
229 OpReturn
230 OpFunctionEnd
231 )";
232 
233   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
234 }
235 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameterCopied)236 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterCopied) {
237   const std::string text = R"(
238 ; CHECK-NOT: OpDecorate
239 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
240 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
241 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
242 OpCapability Shader
243 OpCapability Linkage
244 OpMemoryModel Logical GLSL450
245 OpDecorate %param Coherent
246 OpDecorate %param Volatile
247 %void = OpTypeVoid
248 %int = OpTypeInt 32 0
249 %ptr_int_Uniform = OpTypePointer Uniform %int
250 %func_ty = OpTypeFunction %void %ptr_int_Uniform
251 %func = OpFunction %void None %func_ty
252 %param = OpFunctionParameter %ptr_int_Uniform
253 %1 = OpLabel
254 %copy = OpCopyObject %ptr_int_Uniform %param
255 %ld = OpLoad %int %copy
256 %copy2 = OpCopyObject %ptr_int_Uniform %param
257 OpStore %copy2 %ld
258 OpReturn
259 OpFunctionEnd
260 )";
261 
262   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
263 }
264 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableAccessChain)265 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableAccessChain) {
266   const std::string text = R"(
267 ; CHECK-NOT: OpDecorate
268 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
269 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
270 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
271 OpCapability Shader
272 OpCapability Linkage
273 OpMemoryModel Logical GLSL450
274 OpDecorate %var Coherent
275 OpDecorate %var Volatile
276 %void = OpTypeVoid
277 %int = OpTypeInt 32 0
278 %int0 = OpConstant %int 0
279 %int3 = OpConstant %int 3
280 %int_array_3 = OpTypeArray %int %int3
281 %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
282 %ptr_int_Uniform = OpTypePointer Uniform %int
283 %var = OpVariable %ptr_intarray_Uniform Uniform
284 %func_ty = OpTypeFunction %void
285 %func = OpFunction %void None %func_ty
286 %1 = OpLabel
287 %gep = OpAccessChain %ptr_int_Uniform %var %int0
288 %ld = OpLoad %int %gep
289 OpStore %gep %ld
290 OpReturn
291 OpFunctionEnd
292 )";
293 
294   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
295 }
296 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameterAccessChain)297 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterAccessChain) {
298   const std::string text = R"(
299 ; CHECK-NOT: OpDecorate
300 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
301 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
302 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
303 OpCapability Shader
304 OpCapability Linkage
305 OpMemoryModel Logical GLSL450
306 OpDecorate %param Coherent
307 OpDecorate %param Volatile
308 %void = OpTypeVoid
309 %int = OpTypeInt 32 0
310 %int0 = OpConstant %int 0
311 %int3 = OpConstant %int 3
312 %int_array_3 = OpTypeArray %int %int3
313 %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
314 %ptr_int_Uniform = OpTypePointer Uniform %int
315 %func_ty = OpTypeFunction %void %ptr_intarray_Uniform
316 %func = OpFunction %void None %func_ty
317 %param = OpFunctionParameter %ptr_intarray_Uniform
318 %1 = OpLabel
319 %ld_gep = OpAccessChain %ptr_int_Uniform %param %int0
320 %ld = OpLoad %int %ld_gep
321 %st_gep = OpAccessChain %ptr_int_Uniform %param %int0
322 OpStore %st_gep %ld
323 OpReturn
324 OpFunctionEnd
325 )";
326 
327   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
328 }
329 
TEST_F(UpgradeMemoryModelTest,VariablePointerSelect)330 TEST_F(UpgradeMemoryModelTest, VariablePointerSelect) {
331   const std::string text = R"(
332 ; CHECK-NOT: OpDecorate
333 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
334 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
335 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
336 OpCapability Shader
337 OpCapability Linkage
338 OpCapability VariablePointers
339 OpExtension "SPV_KHR_variable_pointers"
340 OpMemoryModel Logical GLSL450
341 OpDecorate %var Coherent
342 OpDecorate %var Volatile
343 %void = OpTypeVoid
344 %int = OpTypeInt 32 0
345 %bool = OpTypeBool
346 %true = OpConstantTrue %bool
347 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
348 %null = OpConstantNull %ptr_int_StorageBuffer
349 %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
350 %func_ty = OpTypeFunction %void
351 %func = OpFunction %void None %func_ty
352 %1 = OpLabel
353 %select = OpSelect %ptr_int_StorageBuffer %true %var %null
354 %ld = OpLoad %int %select
355 OpStore %var %ld
356 OpReturn
357 OpFunctionEnd
358 )";
359 
360   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
361 }
362 
TEST_F(UpgradeMemoryModelTest,VariablePointerSelectConservative)363 TEST_F(UpgradeMemoryModelTest, VariablePointerSelectConservative) {
364   const std::string text = R"(
365 ; CHECK-NOT: OpDecorate
366 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
367 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
368 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
369 OpCapability Shader
370 OpCapability Linkage
371 OpCapability VariablePointers
372 OpExtension "SPV_KHR_variable_pointers"
373 OpMemoryModel Logical GLSL450
374 OpDecorate %var1 Coherent
375 OpDecorate %var2 Volatile
376 %void = OpTypeVoid
377 %int = OpTypeInt 32 0
378 %bool = OpTypeBool
379 %true = OpConstantTrue %bool
380 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
381 %var1 = OpVariable %ptr_int_StorageBuffer StorageBuffer
382 %var2 = OpVariable %ptr_int_StorageBuffer StorageBuffer
383 %func_ty = OpTypeFunction %void
384 %func = OpFunction %void None %func_ty
385 %1 = OpLabel
386 %select = OpSelect %ptr_int_StorageBuffer %true %var1 %var2
387 %ld = OpLoad %int %select
388 OpStore %select %ld
389 OpReturn
390 OpFunctionEnd
391 )";
392 
393   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
394 }
395 
TEST_F(UpgradeMemoryModelTest,VariablePointerIncrement)396 TEST_F(UpgradeMemoryModelTest, VariablePointerIncrement) {
397   const std::string text = R"(
398 ; CHECK-NOT: OpDecorate {{%\w+}} Coherent
399 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
400 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
401 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
402 OpCapability Shader
403 OpCapability Linkage
404 OpCapability VariablePointers
405 OpExtension "SPV_KHR_variable_pointers"
406 OpMemoryModel Logical GLSL450
407 OpDecorate %param Coherent
408 OpDecorate %param ArrayStride 4
409 %void = OpTypeVoid
410 %bool = OpTypeBool
411 %int = OpTypeInt 32 0
412 %int0 = OpConstant %int 0
413 %int1 = OpConstant %int 1
414 %int10 = OpConstant %int 10
415 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
416 %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer
417 %func = OpFunction %void None %func_ty
418 %param = OpFunctionParameter %ptr_int_StorageBuffer
419 %1 = OpLabel
420 OpBranch %2
421 %2 = OpLabel
422 %phi = OpPhi %ptr_int_StorageBuffer %param %1 %ptr_next %2
423 %iv = OpPhi %int %int0 %1 %inc %2
424 %inc = OpIAdd %int %iv %int1
425 %ptr_next = OpPtrAccessChain %ptr_int_StorageBuffer %phi %int1
426 %cmp = OpIEqual %bool %iv %int10
427 OpLoopMerge %3 %2 None
428 OpBranchConditional %cmp %3 %2
429 %3 = OpLabel
430 %ld = OpLoad %int %phi
431 OpStore %phi %ld
432 OpReturn
433 OpFunctionEnd
434 )";
435 
436   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
437 }
438 
TEST_F(UpgradeMemoryModelTest,CoherentStructElement)439 TEST_F(UpgradeMemoryModelTest, CoherentStructElement) {
440   const std::string text = R"(
441 ; CHECK-NOT: OpMemberDecorate
442 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
443 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
444 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
445 OpCapability Shader
446 OpCapability Linkage
447 OpExtension "SPV_KHR_storage_buffer_storage_class"
448 OpMemoryModel Logical GLSL450
449 OpMemberDecorate %struct 0 Coherent
450 %void = OpTypeVoid
451 %int = OpTypeInt 32 0
452 %int0 = OpConstant %int 0
453 %struct = OpTypeStruct %int
454 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
455 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
456 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
457 %func = OpFunction %void None %func_ty
458 %param = OpFunctionParameter %ptr_struct_StorageBuffer
459 %1 = OpLabel
460 %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
461 %ld = OpLoad %int %gep
462 OpStore %gep %ld
463 OpReturn
464 OpFunctionEnd
465 )";
466 
467   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
468 }
469 
TEST_F(UpgradeMemoryModelTest,CoherentElementFullStructAccess)470 TEST_F(UpgradeMemoryModelTest, CoherentElementFullStructAccess) {
471   const std::string text = R"(
472 ; CHECK-NOT: OpMemberDecorate
473 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
474 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
475 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
476 OpCapability Shader
477 OpCapability Linkage
478 OpExtension "SPV_KHR_storage_buffer_storage_class"
479 OpMemoryModel Logical GLSL450
480 OpMemberDecorate %struct 0 Coherent
481 %void = OpTypeVoid
482 %int = OpTypeInt 32 0
483 %struct = OpTypeStruct %int
484 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
485 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
486 %func = OpFunction %void None %func_ty
487 %param = OpFunctionParameter %ptr_struct_StorageBuffer
488 %1 = OpLabel
489 %ld = OpLoad %struct %param
490 OpStore %param %ld
491 OpReturn
492 OpFunctionEnd
493 )";
494 
495   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
496 }
497 
TEST_F(UpgradeMemoryModelTest,CoherentElementNotAccessed)498 TEST_F(UpgradeMemoryModelTest, CoherentElementNotAccessed) {
499   const std::string text = R"(
500 ; CHECK-NOT: OpMemberDecorate
501 ; CHECK-NOT: MakePointerAvailableKHR
502 ; CHECK-NOT: NonPrivatePointerKHR
503 ; CHECK-NOT: MakePointerVisibleKHR
504 OpCapability Shader
505 OpCapability Linkage
506 OpExtension "SPV_KHR_storage_buffer_storage_class"
507 OpMemoryModel Logical GLSL450
508 OpMemberDecorate %struct 1 Coherent
509 %void = OpTypeVoid
510 %int = OpTypeInt 32 0
511 %int0 = OpConstant %int 0
512 %struct = OpTypeStruct %int %int
513 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
514 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
515 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
516 %func = OpFunction %void None %func_ty
517 %param = OpFunctionParameter %ptr_struct_StorageBuffer
518 %1 = OpLabel
519 %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
520 %ld = OpLoad %int %gep
521 OpStore %gep %ld
522 OpReturn
523 OpFunctionEnd
524 )";
525 
526   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
527 }
528 
TEST_F(UpgradeMemoryModelTest,MultiIndexAccessCoherent)529 TEST_F(UpgradeMemoryModelTest, MultiIndexAccessCoherent) {
530   const std::string text = R"(
531 ; CHECK-NOT: OpMemberDecorate
532 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
533 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
534 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
535 OpCapability Shader
536 OpCapability Linkage
537 OpExtension "SPV_KHR_storage_buffer_storage_class"
538 OpMemoryModel Logical GLSL450
539 OpMemberDecorate %inner 1 Coherent
540 %void = OpTypeVoid
541 %int = OpTypeInt 32 0
542 %int0 = OpConstant %int 0
543 %int1 = OpConstant %int 1
544 %inner = OpTypeStruct %int %int
545 %middle = OpTypeStruct %inner
546 %outer = OpTypeStruct %middle %middle
547 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
548 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
549 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
550 %func = OpFunction %void None %func_ty
551 %param = OpFunctionParameter %ptr_outer_StorageBuffer
552 %1 = OpLabel
553 %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int1
554 %ld = OpLoad %int %ld_gep
555 %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int1
556 OpStore %st_gep %ld
557 OpReturn
558 OpFunctionEnd
559 )";
560 
561   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
562 }
563 
TEST_F(UpgradeMemoryModelTest,MultiIndexAccessNonCoherent)564 TEST_F(UpgradeMemoryModelTest, MultiIndexAccessNonCoherent) {
565   const std::string text = R"(
566 ; CHECK-NOT: OpMemberDecorate
567 ; CHECK-NOT: MakePointerAvailableKHR
568 ; CHECK-NOT: NonPrivatePointerKHR
569 ; CHECK-NOT: MakePointerVisibleKHR
570 OpCapability Shader
571 OpCapability Linkage
572 OpExtension "SPV_KHR_storage_buffer_storage_class"
573 OpMemoryModel Logical GLSL450
574 OpMemberDecorate %inner 1 Coherent
575 %void = OpTypeVoid
576 %int = OpTypeInt 32 0
577 %int0 = OpConstant %int 0
578 %int1 = OpConstant %int 1
579 %inner = OpTypeStruct %int %int
580 %middle = OpTypeStruct %inner
581 %outer = OpTypeStruct %middle %middle
582 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
583 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
584 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
585 %func = OpFunction %void None %func_ty
586 %param = OpFunctionParameter %ptr_outer_StorageBuffer
587 %1 = OpLabel
588 %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int0
589 %ld = OpLoad %int %ld_gep
590 %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int0
591 OpStore %st_gep %ld
592 OpReturn
593 OpFunctionEnd
594 )";
595 
596   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
597 }
598 
TEST_F(UpgradeMemoryModelTest,ConsecutiveAccessChainCoherent)599 TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainCoherent) {
600   const std::string text = R"(
601 ; CHECK-NOT: OpMemberDecorate
602 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
603 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
604 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
605 OpCapability Shader
606 OpCapability Linkage
607 OpExtension "SPV_KHR_storage_buffer_storage_class"
608 OpMemoryModel Logical GLSL450
609 OpMemberDecorate %inner 1 Coherent
610 %void = OpTypeVoid
611 %int = OpTypeInt 32 0
612 %int0 = OpConstant %int 0
613 %int1 = OpConstant %int 1
614 %inner = OpTypeStruct %int %int
615 %middle = OpTypeStruct %inner
616 %outer = OpTypeStruct %middle %middle
617 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
618 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
619 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
620 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
621 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
622 %func = OpFunction %void None %func_ty
623 %param = OpFunctionParameter %ptr_outer_StorageBuffer
624 %1 = OpLabel
625 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
626 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
627 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
628 %ld = OpLoad %int %ld_gep3
629 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
630 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
631 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
632 OpStore %st_gep3 %ld
633 OpReturn
634 OpFunctionEnd
635 )";
636 
637   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
638 }
639 
TEST_F(UpgradeMemoryModelTest,ConsecutiveAccessChainNonCoherent)640 TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainNonCoherent) {
641   const std::string text = R"(
642 ; CHECK-NOT: OpMemberDecorate
643 ; CHECK-NOT: MakePointerAvailableKHR
644 ; CHECK-NOT: NonPrivatePointerKHR
645 ; CHECK-NOT: MakePointerVisibleKHR
646 OpCapability Shader
647 OpCapability Linkage
648 OpExtension "SPV_KHR_storage_buffer_storage_class"
649 OpMemoryModel Logical GLSL450
650 OpMemberDecorate %inner 1 Coherent
651 %void = OpTypeVoid
652 %int = OpTypeInt 32 0
653 %int0 = OpConstant %int 0
654 %int1 = OpConstant %int 1
655 %inner = OpTypeStruct %int %int
656 %middle = OpTypeStruct %inner
657 %outer = OpTypeStruct %middle %middle
658 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
659 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
660 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
661 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
662 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
663 %func = OpFunction %void None %func_ty
664 %param = OpFunctionParameter %ptr_outer_StorageBuffer
665 %1 = OpLabel
666 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
667 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
668 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int0
669 %ld = OpLoad %int %ld_gep3
670 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
671 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
672 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int0
673 OpStore %st_gep3 %ld
674 OpReturn
675 OpFunctionEnd
676 )";
677 
678   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
679 }
680 
TEST_F(UpgradeMemoryModelTest,CoherentStructElementAccess)681 TEST_F(UpgradeMemoryModelTest, CoherentStructElementAccess) {
682   const std::string text = R"(
683 ; CHECK-NOT: OpMemberDecorate
684 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
685 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
686 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
687 OpCapability Shader
688 OpCapability Linkage
689 OpExtension "SPV_KHR_storage_buffer_storage_class"
690 OpMemoryModel Logical GLSL450
691 OpMemberDecorate %middle 0 Coherent
692 %void = OpTypeVoid
693 %int = OpTypeInt 32 0
694 %int0 = OpConstant %int 0
695 %int1 = OpConstant %int 1
696 %inner = OpTypeStruct %int %int
697 %middle = OpTypeStruct %inner
698 %outer = OpTypeStruct %middle %middle
699 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
700 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
701 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
702 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
703 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
704 %func = OpFunction %void None %func_ty
705 %param = OpFunctionParameter %ptr_outer_StorageBuffer
706 %1 = OpLabel
707 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
708 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
709 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
710 %ld = OpLoad %int %ld_gep3
711 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
712 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
713 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
714 OpStore %st_gep3 %ld
715 OpReturn
716 OpFunctionEnd
717 )";
718 
719   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
720 }
721 
TEST_F(UpgradeMemoryModelTest,NonCoherentLoadCoherentStore)722 TEST_F(UpgradeMemoryModelTest, NonCoherentLoadCoherentStore) {
723   const std::string text = R"(
724 ; CHECK-NOT: OpMemberDecorate
725 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
726 ; CHECK-NOT: MakePointerAvailableKHR
727 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerVisibleKHR|NonPrivatePointerKHR [[scope]]
728 OpCapability Shader
729 OpCapability Linkage
730 OpExtension "SPV_KHR_storage_buffer_storage_class"
731 OpMemoryModel Logical GLSL450
732 OpMemberDecorate %outer 1 Coherent
733 %void = OpTypeVoid
734 %int = OpTypeInt 32 0
735 %int0 = OpConstant %int 0
736 %int1 = OpConstant %int 1
737 %inner = OpTypeStruct %int %int
738 %middle = OpTypeStruct %inner
739 %outer = OpTypeStruct %middle %middle
740 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
741 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
742 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
743 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
744 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
745 %func = OpFunction %void None %func_ty
746 %param = OpFunctionParameter %ptr_outer_StorageBuffer
747 %1 = OpLabel
748 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
749 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
750 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
751 %ld = OpLoad %int %ld_gep3
752 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
753 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
754 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
755 OpStore %st_gep3 %ld
756 OpReturn
757 OpFunctionEnd
758 )";
759 
760   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
761 }
762 
TEST_F(UpgradeMemoryModelTest,CopyMemory)763 TEST_F(UpgradeMemoryModelTest, CopyMemory) {
764   const std::string text = R"(
765 ; CHECK-NOT: OpDecorate
766 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
767 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|MakePointerVisibleKHR|NonPrivatePointerKHR [[queuefamily]]
768 ; CHECK-NOT: [[queuefamily]]
769 OpCapability Shader
770 OpCapability Linkage
771 OpExtension "SPV_KHR_storage_buffer_storage_class"
772 OpMemoryModel Logical GLSL450
773 OpDecorate %in_var Coherent
774 OpDecorate %out_var Volatile
775 %void = OpTypeVoid
776 %int = OpTypeInt 32 0
777 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
778 %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
779 %out_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
780 %func_ty = OpTypeFunction %void
781 %func = OpFunction %void None %func_ty
782 %1 = OpLabel
783 OpCopyMemory %out_var %in_var
784 OpReturn
785 OpFunctionEnd
786 )";
787 
788   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
789 }
790 
TEST_F(UpgradeMemoryModelTest,CopyMemorySized)791 TEST_F(UpgradeMemoryModelTest, CopyMemorySized) {
792   const std::string text = R"(
793 ; CHECK-NOT: OpDecorate
794 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
795 ; CHECK: OpCopyMemorySized {{%\w+}} {{%\w+}} {{%\w+}} Volatile|MakePointerAvailableKHR|NonPrivatePointerKHR [[queuefamily]]
796 ; CHECK-NOT: [[queuefamily]]
797 OpCapability Shader
798 OpCapability Linkage
799 OpCapability Addresses
800 OpExtension "SPV_KHR_storage_buffer_storage_class"
801 OpMemoryModel Logical GLSL450
802 OpDecorate %out_param Coherent
803 OpDecorate %in_param Volatile
804 %void = OpTypeVoid
805 %int = OpTypeInt 32 0
806 %int4 = OpConstant %int 4
807 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
808 %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer %ptr_int_StorageBuffer
809 %func = OpFunction %void None %func_ty
810 %in_param = OpFunctionParameter %ptr_int_StorageBuffer
811 %out_param = OpFunctionParameter %ptr_int_StorageBuffer
812 %1 = OpLabel
813 OpCopyMemorySized %out_param %in_param %int4
814 OpReturn
815 OpFunctionEnd
816 )";
817 
818   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
819 }
820 
TEST_F(UpgradeMemoryModelTest,CopyMemoryTwoScopes)821 TEST_F(UpgradeMemoryModelTest, CopyMemoryTwoScopes) {
822   const std::string text = R"(
823 ; CHECK-NOT: OpDecorate
824 ; CHECK-DAG: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
825 ; CHECK-DAG: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
826 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailableKHR|MakePointerVisibleKHR|NonPrivatePointerKHR [[queuefamily]] [[workgroup]]
827 OpCapability Shader
828 OpCapability Linkage
829 OpExtension "SPV_KHR_storage_buffer_storage_class"
830 OpMemoryModel Logical GLSL450
831 OpDecorate %in_var Coherent
832 OpDecorate %out_var Coherent
833 %void = OpTypeVoid
834 %int = OpTypeInt 32 0
835 %ptr_int_Workgroup = OpTypePointer Workgroup %int
836 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
837 %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
838 %out_var = OpVariable %ptr_int_Workgroup Workgroup
839 %func_ty = OpTypeFunction %void
840 %func = OpFunction %void None %func_ty
841 %1 = OpLabel
842 OpCopyMemory %out_var %in_var
843 OpReturn
844 OpFunctionEnd
845 )";
846 
847   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
848 }
849 
TEST_F(UpgradeMemoryModelTest,VolatileImageRead)850 TEST_F(UpgradeMemoryModelTest, VolatileImageRead) {
851   const std::string text = R"(
852 ; CHECK-NOT: OpDecorate
853 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
854 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
855 OpCapability Shader
856 OpCapability Linkage
857 OpCapability StorageImageReadWithoutFormat
858 OpExtension "SPV_KHR_storage_buffer_storage_class"
859 OpMemoryModel Logical GLSL450
860 OpDecorate %var Volatile
861 %void = OpTypeVoid
862 %int = OpTypeInt 32 0
863 %v2int = OpTypeVector %int 2
864 %float = OpTypeFloat 32
865 %int0 = OpConstant %int 0
866 %v2int_0 = OpConstantComposite %v2int %int0 %int0
867 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
868 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
869 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
870 %func_ty = OpTypeFunction %void
871 %func = OpFunction %void None %func_ty
872 %1 = OpLabel
873 %ld = OpLoad %image %var
874 %rd = OpImageRead %float %ld %v2int_0
875 OpReturn
876 OpFunctionEnd
877 )";
878 
879   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
880 }
881 
TEST_F(UpgradeMemoryModelTest,CoherentImageRead)882 TEST_F(UpgradeMemoryModelTest, CoherentImageRead) {
883   const std::string text = R"(
884 ; CHECK-NOT: OpDecorate
885 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
886 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
887 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
888 OpCapability Shader
889 OpCapability Linkage
890 OpCapability StorageImageReadWithoutFormat
891 OpExtension "SPV_KHR_storage_buffer_storage_class"
892 OpMemoryModel Logical GLSL450
893 OpDecorate %var Coherent
894 %void = OpTypeVoid
895 %int = OpTypeInt 32 0
896 %v2int = OpTypeVector %int 2
897 %float = OpTypeFloat 32
898 %int0 = OpConstant %int 0
899 %v2int_0 = OpConstantComposite %v2int %int0 %int0
900 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
901 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
902 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
903 %func_ty = OpTypeFunction %void
904 %func = OpFunction %void None %func_ty
905 %1 = OpLabel
906 %ld = OpLoad %image %var
907 %rd = OpImageRead %float %ld %v2int_0
908 OpReturn
909 OpFunctionEnd
910 )";
911 
912   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
913 }
914 
TEST_F(UpgradeMemoryModelTest,CoherentImageReadExtractedFromSampledImage)915 TEST_F(UpgradeMemoryModelTest, CoherentImageReadExtractedFromSampledImage) {
916   const std::string text = R"(
917 ; CHECK-NOT: OpDecorate
918 ; CHECK: [[image:%\w+]] = OpTypeImage
919 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
920 ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
921 ; CHECK-NOT: NonPrivatePointerKHR
922 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
923 OpCapability Shader
924 OpCapability Linkage
925 OpCapability StorageImageReadWithoutFormat
926 OpExtension "SPV_KHR_storage_buffer_storage_class"
927 OpMemoryModel Logical GLSL450
928 OpDecorate %var Coherent
929 %void = OpTypeVoid
930 %int = OpTypeInt 32 0
931 %v2int = OpTypeVector %int 2
932 %float = OpTypeFloat 32
933 %int0 = OpConstant %int 0
934 %v2int_0 = OpConstantComposite %v2int %int0 %int0
935 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
936 %sampled_image = OpTypeSampledImage %image
937 %sampler = OpTypeSampler
938 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
939 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
940 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
941 %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
942 %func_ty = OpTypeFunction %void
943 %func = OpFunction %void None %func_ty
944 %1 = OpLabel
945 %ld = OpLoad %image %var
946 %ld_sampler = OpLoad %sampler %sampler_var
947 %sample = OpSampledImage %sampled_image %ld %ld_sampler
948 %extract = OpImage %image %sample
949 %rd = OpImageRead %float %extract %v2int_0
950 OpReturn
951 OpFunctionEnd
952 )";
953 
954   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
955 }
956 
TEST_F(UpgradeMemoryModelTest,VolatileImageWrite)957 TEST_F(UpgradeMemoryModelTest, VolatileImageWrite) {
958   const std::string text = R"(
959 ; CHECK-NOT: OpDecorate
960 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
961 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
962 OpCapability Shader
963 OpCapability Linkage
964 OpCapability StorageImageWriteWithoutFormat
965 OpExtension "SPV_KHR_storage_buffer_storage_class"
966 OpMemoryModel Logical GLSL450
967 OpDecorate %param Volatile
968 %void = OpTypeVoid
969 %int = OpTypeInt 32 0
970 %v2int = OpTypeVector %int 2
971 %float = OpTypeFloat 32
972 %float0 = OpConstant %float 0
973 %v2int_null = OpConstantNull %v2int
974 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
975 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
976 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
977 %func = OpFunction %void None %func_ty
978 %param = OpFunctionParameter %ptr_image_StorageBuffer
979 %1 = OpLabel
980 %ld = OpLoad %image %param
981 OpImageWrite %ld %v2int_null %float0
982 OpReturn
983 OpFunctionEnd
984 )";
985 
986   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
987 }
988 
TEST_F(UpgradeMemoryModelTest,CoherentImageWrite)989 TEST_F(UpgradeMemoryModelTest, CoherentImageWrite) {
990   const std::string text = R"(
991 ; CHECK-NOT: OpDecorate
992 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
993 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR
994 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
995 OpCapability Shader
996 OpCapability Linkage
997 OpCapability StorageImageWriteWithoutFormat
998 OpExtension "SPV_KHR_storage_buffer_storage_class"
999 OpMemoryModel Logical GLSL450
1000 OpDecorate %param Coherent
1001 %void = OpTypeVoid
1002 %int = OpTypeInt 32 0
1003 %v2int = OpTypeVector %int 2
1004 %float = OpTypeFloat 32
1005 %float0 = OpConstant %float 0
1006 %v2int_null = OpConstantNull %v2int
1007 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1008 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1009 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
1010 %func = OpFunction %void None %func_ty
1011 %param = OpFunctionParameter %ptr_image_StorageBuffer
1012 %1 = OpLabel
1013 %ld = OpLoad %image %param
1014 OpImageWrite %ld %v2int_null %float0
1015 OpReturn
1016 OpFunctionEnd
1017 )";
1018 
1019   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1020 }
1021 
TEST_F(UpgradeMemoryModelTest,CoherentImageWriteExtractFromSampledImage)1022 TEST_F(UpgradeMemoryModelTest, CoherentImageWriteExtractFromSampledImage) {
1023   const std::string text = R"(
1024 ; CHECK-NOT: OpDecorate
1025 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1026 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR
1027 ; CHECK-NOT: NonPrivatePointerKHR
1028 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisibleKHR|NonPrivateTexelKHR [[scope]]
1029 OpCapability Shader
1030 OpCapability Linkage
1031 OpCapability StorageImageWriteWithoutFormat
1032 OpExtension "SPV_KHR_storage_buffer_storage_class"
1033 OpMemoryModel Logical GLSL450
1034 OpDecorate %param Coherent
1035 %void = OpTypeVoid
1036 %int = OpTypeInt 32 0
1037 %v2int = OpTypeVector %int 2
1038 %float = OpTypeFloat 32
1039 %float0 = OpConstant %float 0
1040 %v2int_null = OpConstantNull %v2int
1041 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1042 %sampled_image = OpTypeSampledImage %image
1043 %sampler = OpTypeSampler
1044 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1045 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
1046 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer %ptr_sampler_StorageBuffer
1047 %func = OpFunction %void None %func_ty
1048 %param = OpFunctionParameter %ptr_image_StorageBuffer
1049 %sampler_param = OpFunctionParameter %ptr_sampler_StorageBuffer
1050 %1 = OpLabel
1051 %ld = OpLoad %image %param
1052 %ld_sampler = OpLoad %sampler %sampler_param
1053 %sample = OpSampledImage %sampled_image %ld %ld_sampler
1054 %extract = OpImage %image %sample
1055 OpImageWrite %extract %v2int_null %float0
1056 OpReturn
1057 OpFunctionEnd
1058 )";
1059 
1060   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1061 }
1062 
TEST_F(UpgradeMemoryModelTest,VolatileImageSparseRead)1063 TEST_F(UpgradeMemoryModelTest, VolatileImageSparseRead) {
1064   const std::string text = R"(
1065 ; CHECK-NOT: OpDecorate
1066 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
1067 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexelKHR
1068 OpCapability Shader
1069 OpCapability Linkage
1070 OpCapability StorageImageReadWithoutFormat
1071 OpCapability SparseResidency
1072 OpExtension "SPV_KHR_storage_buffer_storage_class"
1073 OpMemoryModel Logical GLSL450
1074 OpDecorate %var Volatile
1075 %void = OpTypeVoid
1076 %int = OpTypeInt 32 0
1077 %v2int = OpTypeVector %int 2
1078 %float = OpTypeFloat 32
1079 %int0 = OpConstant %int 0
1080 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1081 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
1082 %struct = OpTypeStruct %int %float
1083 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1084 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1085 %func_ty = OpTypeFunction %void
1086 %func = OpFunction %void None %func_ty
1087 %1 = OpLabel
1088 %ld = OpLoad %image %var
1089 %rd = OpImageSparseRead %struct %ld %v2int_0
1090 OpReturn
1091 OpFunctionEnd
1092 )";
1093 
1094   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1095 }
1096 
TEST_F(UpgradeMemoryModelTest,CoherentImageSparseRead)1097 TEST_F(UpgradeMemoryModelTest, CoherentImageSparseRead) {
1098   const std::string text = R"(
1099 ; CHECK-NOT: OpDecorate
1100 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1101 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
1102 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
1103 OpCapability Shader
1104 OpCapability Linkage
1105 OpCapability StorageImageReadWithoutFormat
1106 OpCapability SparseResidency
1107 OpExtension "SPV_KHR_storage_buffer_storage_class"
1108 OpMemoryModel Logical GLSL450
1109 OpDecorate %var Coherent
1110 %void = OpTypeVoid
1111 %int = OpTypeInt 32 0
1112 %v2int = OpTypeVector %int 2
1113 %float = OpTypeFloat 32
1114 %int0 = OpConstant %int 0
1115 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1116 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
1117 %struct = OpTypeStruct %int %float
1118 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1119 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1120 %func_ty = OpTypeFunction %void
1121 %func = OpFunction %void None %func_ty
1122 %1 = OpLabel
1123 %ld = OpLoad %image %var
1124 %rd = OpImageSparseRead %struct %ld %v2int_0
1125 OpReturn
1126 OpFunctionEnd
1127 )";
1128 
1129   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1130 }
1131 
TEST_F(UpgradeMemoryModelTest,CoherentImageSparseReadExtractedFromSampledImage)1132 TEST_F(UpgradeMemoryModelTest,
1133        CoherentImageSparseReadExtractedFromSampledImage) {
1134   const std::string text = R"(
1135 ; CHECK-NOT: OpDecorate
1136 ; CHECK: [[image:%\w+]] = OpTypeImage
1137 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1138 ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerAvailableKHR|NonPrivatePointerKHR [[scope]]
1139 ; CHECK-NOT: NonPrivatePointerKHR
1140 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailableKHR|NonPrivateTexelKHR [[scope]]
1141 OpCapability Shader
1142 OpCapability Linkage
1143 OpCapability StorageImageReadWithoutFormat
1144 OpCapability SparseResidency
1145 OpExtension "SPV_KHR_storage_buffer_storage_class"
1146 OpMemoryModel Logical GLSL450
1147 OpDecorate %var Coherent
1148 %void = OpTypeVoid
1149 %int = OpTypeInt 32 0
1150 %v2int = OpTypeVector %int 2
1151 %float = OpTypeFloat 32
1152 %int0 = OpConstant %int 0
1153 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1154 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1155 %struct = OpTypeStruct %int %float
1156 %sampled_image = OpTypeSampledImage %image
1157 %sampler = OpTypeSampler
1158 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1159 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
1160 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1161 %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
1162 %func_ty = OpTypeFunction %void
1163 %func = OpFunction %void None %func_ty
1164 %1 = OpLabel
1165 %ld = OpLoad %image %var
1166 %ld_sampler = OpLoad %sampler %sampler_var
1167 %sample = OpSampledImage %sampled_image %ld %ld_sampler
1168 %extract = OpImage %image %sample
1169 %rd = OpImageSparseRead %struct %extract %v2int_0
1170 OpReturn
1171 OpFunctionEnd
1172 )";
1173 
1174   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1175 }
1176 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierNoChange)1177 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierNoChange) {
1178   const std::string text = R"(
1179 ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
1180 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1181 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[none]]
1182 OpCapability Tessellation
1183 OpMemoryModel Logical GLSL450
1184 OpEntryPoint TessellationControl %func "func"
1185 %void = OpTypeVoid
1186 %int = OpTypeInt 32 0
1187 %none = OpConstant %int 0
1188 %workgroup = OpConstant %int 2
1189 %func_ty = OpTypeFunction %void
1190 %func = OpFunction %void None %func_ty
1191 %1 = OpLabel
1192 OpControlBarrier %workgroup %workgroup %none
1193 OpReturn
1194 OpFunctionEnd
1195 )";
1196 
1197   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1198 }
1199 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutput)1200 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutput) {
1201   const std::string text = R"(
1202 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1203 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1204 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1205 OpCapability Tessellation
1206 OpMemoryModel Logical GLSL450
1207 OpEntryPoint TessellationControl %func "func" %var
1208 %void = OpTypeVoid
1209 %int = OpTypeInt 32 0
1210 %none = OpConstant %int 0
1211 %workgroup = OpConstant %int 2
1212 %ptr_int_Output = OpTypePointer Output %int
1213 %var = OpVariable %ptr_int_Output Output
1214 %func_ty = OpTypeFunction %void
1215 %func = OpFunction %void None %func_ty
1216 %1 = OpLabel
1217 %ld = OpLoad %int %var
1218 OpControlBarrier %workgroup %workgroup %none
1219 OpStore %var %ld
1220 OpReturn
1221 OpFunctionEnd
1222 )";
1223 
1224   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1225 }
1226 
TEST_F(UpgradeMemoryModelTest,TessellationMemoryBarrierNoChange)1227 TEST_F(UpgradeMemoryModelTest, TessellationMemoryBarrierNoChange) {
1228   const std::string text = R"(
1229 ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
1230 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1231 ; CHECK: OpMemoryBarrier [[workgroup]] [[none]]
1232 OpCapability Tessellation
1233 OpMemoryModel Logical GLSL450
1234 OpEntryPoint TessellationControl %func "func" %var
1235 %void = OpTypeVoid
1236 %int = OpTypeInt 32 0
1237 %none = OpConstant %int 0
1238 %workgroup = OpConstant %int 2
1239 %ptr_int_Output = OpTypePointer Output %int
1240 %var = OpVariable %ptr_int_Output Output
1241 %func_ty = OpTypeFunction %void
1242 %func = OpFunction %void None %func_ty
1243 %1 = OpLabel
1244 %ld = OpLoad %int %var
1245 OpMemoryBarrier %workgroup %none
1246 OpStore %var %ld
1247 OpReturn
1248 OpFunctionEnd
1249 )";
1250 
1251   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1252 }
1253 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutputSubFunction)1254 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutputSubFunction) {
1255   const std::string text = R"(
1256 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1257 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1258 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1259 OpCapability Tessellation
1260 OpMemoryModel Logical GLSL450
1261 OpEntryPoint TessellationControl %func "func" %var
1262 %void = OpTypeVoid
1263 %int = OpTypeInt 32 0
1264 %none = OpConstant %int 0
1265 %workgroup = OpConstant %int 2
1266 %ptr_int_Output = OpTypePointer Output %int
1267 %var = OpVariable %ptr_int_Output Output
1268 %func_ty = OpTypeFunction %void
1269 %func = OpFunction %void None %func_ty
1270 %1 = OpLabel
1271 %call = OpFunctionCall %void %sub_func
1272 OpReturn
1273 OpFunctionEnd
1274 %sub_func = OpFunction %void None %func_ty
1275 %2 = OpLabel
1276 %ld = OpLoad %int %var
1277 OpControlBarrier %workgroup %workgroup %none
1278 OpStore %var %ld
1279 OpReturn
1280 OpFunctionEnd
1281 )";
1282 
1283   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1284 }
1285 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutputDifferentFunctions)1286 TEST_F(UpgradeMemoryModelTest,
1287        TessellationControlBarrierAddOutputDifferentFunctions) {
1288   const std::string text = R"(
1289 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1290 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1291 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1292 OpCapability Tessellation
1293 OpMemoryModel Logical GLSL450
1294 OpEntryPoint TessellationControl %func "func" %var
1295 %void = OpTypeVoid
1296 %int = OpTypeInt 32 0
1297 %none = OpConstant %int 0
1298 %workgroup = OpConstant %int 2
1299 %ptr_int_Output = OpTypePointer Output %int
1300 %var = OpVariable %ptr_int_Output Output
1301 %func_ty = OpTypeFunction %void
1302 %ld_func_ty = OpTypeFunction %int
1303 %st_func_ty = OpTypeFunction %void %int
1304 %func = OpFunction %void None %func_ty
1305 %1 = OpLabel
1306 %call_ld = OpFunctionCall %int %ld_func
1307 %call_barrier = OpFunctionCall %void %barrier_func
1308 %call_st = OpFunctionCall %void %st_func %call_ld
1309 OpReturn
1310 OpFunctionEnd
1311 %ld_func = OpFunction %int None %ld_func_ty
1312 %2 = OpLabel
1313 %ld = OpLoad %int %var
1314 OpReturnValue %ld
1315 OpFunctionEnd
1316 %barrier_func = OpFunction %void None %func_ty
1317 %3 = OpLabel
1318 OpControlBarrier %workgroup %workgroup %none
1319 OpReturn
1320 OpFunctionEnd
1321 %st_func = OpFunction %void None %st_func_ty
1322 %param = OpFunctionParameter %int
1323 %4 = OpLabel
1324 OpStore %var %param
1325 OpReturn
1326 OpFunctionEnd
1327 )";
1328 
1329   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1330 }
1331 
TEST_F(UpgradeMemoryModelTest,ChangeControlBarrierMemoryScope)1332 TEST_F(UpgradeMemoryModelTest, ChangeControlBarrierMemoryScope) {
1333   std::string text = R"(
1334 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1335 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
1336 ; CHECK: OpControlBarrier [[workgroup]] [[queuefamily]]
1337 OpCapability Shader
1338 OpMemoryModel Logical GLSL450
1339 OpEntryPoint GLCompute %func "func"
1340 %void = OpTypeVoid
1341 %int = OpTypeInt 32 0
1342 %none = OpConstant %int 0
1343 %device = OpConstant %int 1
1344 %workgroup = OpConstant %int 2
1345 %func_ty = OpTypeFunction %void
1346 %func = OpFunction %void None %func_ty
1347 %1 = OpLabel
1348 OpControlBarrier %workgroup %device %none
1349 OpReturn
1350 OpFunctionEnd
1351 )";
1352 
1353   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1354 }
1355 
TEST_F(UpgradeMemoryModelTest,ChangeMemoryBarrierMemoryScope)1356 TEST_F(UpgradeMemoryModelTest, ChangeMemoryBarrierMemoryScope) {
1357   std::string text = R"(
1358 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
1359 ; CHECK: OpMemoryBarrier [[queuefamily]]
1360 OpCapability Shader
1361 OpMemoryModel Logical GLSL450
1362 OpEntryPoint GLCompute %func "func"
1363 %void = OpTypeVoid
1364 %int = OpTypeInt 32 0
1365 %none = OpConstant %int 0
1366 %device = OpConstant %int 1
1367 %func_ty = OpTypeFunction %void
1368 %func = OpFunction %void None %func_ty
1369 %1 = OpLabel
1370 OpMemoryBarrier %device %none
1371 OpReturn
1372 OpFunctionEnd
1373 )";
1374 
1375   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1376 }
1377 
TEST_F(UpgradeMemoryModelTest,ChangeAtomicMemoryScope)1378 TEST_F(UpgradeMemoryModelTest, ChangeAtomicMemoryScope) {
1379   std::string text = R"(
1380 ; CHECK: [[int:%\w+]] = OpTypeInt
1381 ; CHECK: [[var:%\w+]] = OpVariable
1382 ; CHECK: [[qf:%\w+]] = OpConstant [[int]] 5
1383 ; CHECK: OpAtomicLoad [[int]] [[var]] [[qf]]
1384 ; CHECK: OpAtomicStore [[var]] [[qf]]
1385 ; CHECK: OpAtomicExchange [[int]] [[var]] [[qf]]
1386 ; CHECK: OpAtomicCompareExchange [[int]] [[var]] [[qf]]
1387 ; CHECK: OpAtomicIIncrement [[int]] [[var]] [[qf]]
1388 ; CHECK: OpAtomicIDecrement [[int]] [[var]] [[qf]]
1389 ; CHECK: OpAtomicIAdd [[int]] [[var]] [[qf]]
1390 ; CHECK: OpAtomicISub [[int]] [[var]] [[qf]]
1391 ; CHECK: OpAtomicSMin [[int]] [[var]] [[qf]]
1392 ; CHECK: OpAtomicSMax [[int]] [[var]] [[qf]]
1393 ; CHECK: OpAtomicUMin [[int]] [[var]] [[qf]]
1394 ; CHECK: OpAtomicUMax [[int]] [[var]] [[qf]]
1395 ; CHECK: OpAtomicAnd [[int]] [[var]] [[qf]]
1396 ; CHECK: OpAtomicOr [[int]] [[var]] [[qf]]
1397 ; CHECK: OpAtomicXor [[int]] [[var]] [[qf]]
1398 OpCapability Shader
1399 OpExtension "SPV_KHR_storage_buffer_storage_class"
1400 OpMemoryModel Logical GLSL450
1401 OpEntryPoint GLCompute %func "func"
1402 %void = OpTypeVoid
1403 %int = OpTypeInt 32 0
1404 %none = OpConstant %int 0
1405 %device = OpConstant %int 1
1406 %func_ty = OpTypeFunction %void
1407 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
1408 %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
1409 %func = OpFunction %void None %func_ty
1410 %1 = OpLabel
1411 %ld = OpAtomicLoad %int %var %device %none
1412 OpAtomicStore %var %device %none %ld
1413 %ex = OpAtomicExchange %int %var %device %none %ld
1414 %cmp_ex = OpAtomicCompareExchange %int %var %device %none %none %ld %ld
1415 %inc = OpAtomicIIncrement %int %var %device %none
1416 %dec = OpAtomicIDecrement %int %var %device %none
1417 %add = OpAtomicIAdd %int %var %device %none %ld
1418 %sub = OpAtomicISub %int %var %device %none %ld
1419 %smin = OpAtomicSMin %int %var %device %none %ld
1420 %smax = OpAtomicSMax %int %var %device %none %ld
1421 %umin = OpAtomicUMin %int %var %device %none %ld
1422 %umax = OpAtomicUMax %int %var %device %none %ld
1423 %and = OpAtomicAnd %int %var %device %none %ld
1424 %or = OpAtomicOr %int %var %device %none %ld
1425 %xor = OpAtomicXor %int %var %device %none %ld
1426 OpReturn
1427 OpFunctionEnd
1428 )";
1429 
1430   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1431 }
1432 
1433 #endif
1434 
1435 }  // namespace
1436