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 
TEST_F(UpgradeMemoryModelTest,InvalidMemoryModelOpenCL)26 TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelOpenCL) {
27   const std::string text = R"(
28 ; CHECK: OpMemoryModel Logical OpenCL
29 OpCapability Kernel
30 OpCapability Linkage
31 OpMemoryModel Logical OpenCL
32 )";
33 
34   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
35 }
36 
TEST_F(UpgradeMemoryModelTest,InvalidMemoryModelVulkan)37 TEST_F(UpgradeMemoryModelTest, InvalidMemoryModelVulkan) {
38   const std::string text = R"(
39 ; CHECK: OpMemoryModel Logical Vulkan
40 OpCapability Shader
41 OpCapability Linkage
42 OpCapability VulkanMemoryModel
43 OpExtension "SPV_KHR_vulkan_memory_model"
44 OpMemoryModel Logical Vulkan
45 )";
46 
47   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
48 }
49 
TEST_F(UpgradeMemoryModelTest,JustMemoryModel)50 TEST_F(UpgradeMemoryModelTest, JustMemoryModel) {
51   const std::string text = R"(
52 ; CHECK: OpCapability VulkanMemoryModel
53 ; CHECK: OpExtension "SPV_KHR_vulkan_memory_model"
54 ; CHECK: OpMemoryModel Logical Vulkan
55 OpCapability Shader
56 OpCapability Linkage
57 OpMemoryModel Logical GLSL450
58 )";
59 
60   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
61 }
62 
TEST_F(UpgradeMemoryModelTest,RemoveDecorations)63 TEST_F(UpgradeMemoryModelTest, RemoveDecorations) {
64   const std::string text = R"(
65 ; CHECK-NOT: OpDecorate
66 OpCapability Shader
67 OpCapability Linkage
68 OpMemoryModel Logical GLSL450
69 OpDecorate %var Volatile
70 OpDecorate %var Coherent
71 %int = OpTypeInt 32 0
72 %ptr_int_Uniform = OpTypePointer Uniform %int
73 %var = OpVariable %ptr_int_Uniform Uniform
74 )";
75 
76   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
77 }
78 
TEST_F(UpgradeMemoryModelTest,WorkgroupVariable)79 TEST_F(UpgradeMemoryModelTest, WorkgroupVariable) {
80   const std::string text = R"(
81 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
82 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
83 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
84 OpCapability Shader
85 OpCapability Linkage
86 OpMemoryModel Logical GLSL450
87 %void = OpTypeVoid
88 %int = OpTypeInt 32 0
89 %ptr_int_Workgroup = OpTypePointer Workgroup %int
90 %var = OpVariable %ptr_int_Workgroup Workgroup
91 %func_ty = OpTypeFunction %void
92 %func = OpFunction %void None %func_ty
93 %1 = OpLabel
94 %ld = OpLoad %int %var
95 OpStore %var %ld
96 OpReturn
97 OpFunctionEnd
98 )";
99 
100   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
101 }
102 
TEST_F(UpgradeMemoryModelTest,WorkgroupFunctionParameter)103 TEST_F(UpgradeMemoryModelTest, WorkgroupFunctionParameter) {
104   const std::string text = R"(
105 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 2
106 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
107 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
108 OpCapability Shader
109 OpCapability Linkage
110 OpMemoryModel Logical GLSL450
111 %void = OpTypeVoid
112 %int = OpTypeInt 32 0
113 %ptr_int_Workgroup = OpTypePointer Workgroup %int
114 %func_ty = OpTypeFunction %void %ptr_int_Workgroup
115 %func = OpFunction %void None %func_ty
116 %param = OpFunctionParameter %ptr_int_Workgroup
117 %1 = OpLabel
118 %ld = OpLoad %int %param
119 OpStore %param %ld
120 OpReturn
121 OpFunctionEnd
122 )";
123 
124   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
125 }
126 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariable)127 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariable) {
128   const std::string text = R"(
129 ; CHECK-NOT: OpDecorate
130 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
131 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
132 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
133 OpCapability Shader
134 OpCapability Linkage
135 OpMemoryModel Logical GLSL450
136 OpDecorate %var Coherent
137 OpDecorate %var Volatile
138 %void = OpTypeVoid
139 %int = OpTypeInt 32 0
140 %ptr_int_Uniform = OpTypePointer Uniform %int
141 %var = OpVariable %ptr_int_Uniform Uniform
142 %func_ty = OpTypeFunction %void
143 %func = OpFunction %void None %func_ty
144 %1 = OpLabel
145 %ld = OpLoad %int %var
146 OpStore %var %ld
147 OpReturn
148 OpFunctionEnd
149 )";
150 
151   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
152 }
153 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameter)154 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameter) {
155   const std::string text = R"(
156 ; CHECK-NOT: OpDecorate
157 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
158 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
159 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
160 OpCapability Shader
161 OpCapability Linkage
162 OpMemoryModel Logical GLSL450
163 OpDecorate %param Coherent
164 OpDecorate %param Volatile
165 %void = OpTypeVoid
166 %int = OpTypeInt 32 0
167 %ptr_int_Uniform = OpTypePointer Uniform %int
168 %func_ty = OpTypeFunction %void %ptr_int_Uniform
169 %func = OpFunction %void None %func_ty
170 %param = OpFunctionParameter %ptr_int_Uniform
171 %1 = OpLabel
172 %ld = OpLoad %int %param
173 OpStore %param %ld
174 OpReturn
175 OpFunctionEnd
176 )";
177 
178   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
179 }
180 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableOnlyVolatile)181 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableOnlyVolatile) {
182   const std::string text = R"(
183 ; CHECK-NOT: OpDecorate
184 ; CHECK-NOT: OpConstant
185 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
186 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile
187 OpCapability Shader
188 OpCapability Linkage
189 OpMemoryModel Logical GLSL450
190 OpDecorate %var Volatile
191 %void = OpTypeVoid
192 %int = OpTypeInt 32 0
193 %ptr_int_Uniform = OpTypePointer Uniform %int
194 %var = OpVariable %ptr_int_Uniform Uniform
195 %func_ty = OpTypeFunction %void
196 %func = OpFunction %void None %func_ty
197 %1 = OpLabel
198 %ld = OpLoad %int %var
199 OpStore %var %ld
200 OpReturn
201 OpFunctionEnd
202 )";
203 
204   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
205 }
206 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableCopied)207 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableCopied) {
208   const std::string text = R"(
209 ; CHECK-NOT: OpDecorate
210 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
211 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
212 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
213 OpCapability Shader
214 OpCapability Linkage
215 OpMemoryModel Logical GLSL450
216 OpDecorate %var Coherent
217 OpDecorate %var Volatile
218 %void = OpTypeVoid
219 %int = OpTypeInt 32 0
220 %ptr_int_Uniform = OpTypePointer Uniform %int
221 %var = OpVariable %ptr_int_Uniform Uniform
222 %func_ty = OpTypeFunction %void
223 %func = OpFunction %void None %func_ty
224 %1 = OpLabel
225 %copy = OpCopyObject %ptr_int_Uniform %var
226 %ld = OpLoad %int %copy
227 OpStore %copy %ld
228 OpReturn
229 OpFunctionEnd
230 )";
231 
232   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
233 }
234 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameterCopied)235 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterCopied) {
236   const std::string text = R"(
237 ; CHECK-NOT: OpDecorate
238 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
239 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
240 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
241 OpCapability Shader
242 OpCapability Linkage
243 OpMemoryModel Logical GLSL450
244 OpDecorate %param Coherent
245 OpDecorate %param Volatile
246 %void = OpTypeVoid
247 %int = OpTypeInt 32 0
248 %ptr_int_Uniform = OpTypePointer Uniform %int
249 %func_ty = OpTypeFunction %void %ptr_int_Uniform
250 %func = OpFunction %void None %func_ty
251 %param = OpFunctionParameter %ptr_int_Uniform
252 %1 = OpLabel
253 %copy = OpCopyObject %ptr_int_Uniform %param
254 %ld = OpLoad %int %copy
255 %copy2 = OpCopyObject %ptr_int_Uniform %param
256 OpStore %copy2 %ld
257 OpReturn
258 OpFunctionEnd
259 )";
260 
261   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
262 }
263 
TEST_F(UpgradeMemoryModelTest,SimpleUniformVariableAccessChain)264 TEST_F(UpgradeMemoryModelTest, SimpleUniformVariableAccessChain) {
265   const std::string text = R"(
266 ; CHECK-NOT: OpDecorate
267 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
268 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
269 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
270 OpCapability Shader
271 OpCapability Linkage
272 OpMemoryModel Logical GLSL450
273 OpDecorate %var Coherent
274 OpDecorate %var Volatile
275 %void = OpTypeVoid
276 %int = OpTypeInt 32 0
277 %int0 = OpConstant %int 0
278 %int3 = OpConstant %int 3
279 %int_array_3 = OpTypeArray %int %int3
280 %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
281 %ptr_int_Uniform = OpTypePointer Uniform %int
282 %var = OpVariable %ptr_intarray_Uniform Uniform
283 %func_ty = OpTypeFunction %void
284 %func = OpFunction %void None %func_ty
285 %1 = OpLabel
286 %gep = OpAccessChain %ptr_int_Uniform %var %int0
287 %ld = OpLoad %int %gep
288 OpStore %gep %ld
289 OpReturn
290 OpFunctionEnd
291 )";
292 
293   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
294 }
295 
TEST_F(UpgradeMemoryModelTest,SimpleUniformFunctionParameterAccessChain)296 TEST_F(UpgradeMemoryModelTest, SimpleUniformFunctionParameterAccessChain) {
297   const std::string text = R"(
298 ; CHECK-NOT: OpDecorate
299 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
300 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
301 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
302 OpCapability Shader
303 OpCapability Linkage
304 OpMemoryModel Logical GLSL450
305 OpDecorate %param Coherent
306 OpDecorate %param Volatile
307 %void = OpTypeVoid
308 %int = OpTypeInt 32 0
309 %int0 = OpConstant %int 0
310 %int3 = OpConstant %int 3
311 %int_array_3 = OpTypeArray %int %int3
312 %ptr_intarray_Uniform = OpTypePointer Uniform %int_array_3
313 %ptr_int_Uniform = OpTypePointer Uniform %int
314 %func_ty = OpTypeFunction %void %ptr_intarray_Uniform
315 %func = OpFunction %void None %func_ty
316 %param = OpFunctionParameter %ptr_intarray_Uniform
317 %1 = OpLabel
318 %ld_gep = OpAccessChain %ptr_int_Uniform %param %int0
319 %ld = OpLoad %int %ld_gep
320 %st_gep = OpAccessChain %ptr_int_Uniform %param %int0
321 OpStore %st_gep %ld
322 OpReturn
323 OpFunctionEnd
324 )";
325 
326   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
327 }
328 
TEST_F(UpgradeMemoryModelTest,VariablePointerSelect)329 TEST_F(UpgradeMemoryModelTest, VariablePointerSelect) {
330   const std::string text = R"(
331 ; CHECK-NOT: OpDecorate
332 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
333 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
334 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
335 OpCapability Shader
336 OpCapability Linkage
337 OpCapability VariablePointers
338 OpExtension "SPV_KHR_variable_pointers"
339 OpMemoryModel Logical GLSL450
340 OpDecorate %var Coherent
341 OpDecorate %var Volatile
342 %void = OpTypeVoid
343 %int = OpTypeInt 32 0
344 %bool = OpTypeBool
345 %true = OpConstantTrue %bool
346 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
347 %null = OpConstantNull %ptr_int_StorageBuffer
348 %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
349 %func_ty = OpTypeFunction %void
350 %func = OpFunction %void None %func_ty
351 %1 = OpLabel
352 %select = OpSelect %ptr_int_StorageBuffer %true %var %null
353 %ld = OpLoad %int %select
354 OpStore %var %ld
355 OpReturn
356 OpFunctionEnd
357 )";
358 
359   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
360 }
361 
TEST_F(UpgradeMemoryModelTest,VariablePointerSelectConservative)362 TEST_F(UpgradeMemoryModelTest, VariablePointerSelectConservative) {
363   const std::string text = R"(
364 ; CHECK-NOT: OpDecorate
365 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
366 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[scope]]
367 ; CHECK: OpStore {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[scope]]
368 OpCapability Shader
369 OpCapability Linkage
370 OpCapability VariablePointers
371 OpExtension "SPV_KHR_variable_pointers"
372 OpMemoryModel Logical GLSL450
373 OpDecorate %var1 Coherent
374 OpDecorate %var2 Volatile
375 %void = OpTypeVoid
376 %int = OpTypeInt 32 0
377 %bool = OpTypeBool
378 %true = OpConstantTrue %bool
379 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
380 %var1 = OpVariable %ptr_int_StorageBuffer StorageBuffer
381 %var2 = OpVariable %ptr_int_StorageBuffer StorageBuffer
382 %func_ty = OpTypeFunction %void
383 %func = OpFunction %void None %func_ty
384 %1 = OpLabel
385 %select = OpSelect %ptr_int_StorageBuffer %true %var1 %var2
386 %ld = OpLoad %int %select
387 OpStore %select %ld
388 OpReturn
389 OpFunctionEnd
390 )";
391 
392   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
393 }
394 
TEST_F(UpgradeMemoryModelTest,VariablePointerIncrement)395 TEST_F(UpgradeMemoryModelTest, VariablePointerIncrement) {
396   const std::string text = R"(
397 ; CHECK-NOT: OpDecorate {{%\w+}} Coherent
398 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
399 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
400 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
401 OpCapability Shader
402 OpCapability Linkage
403 OpCapability VariablePointers
404 OpExtension "SPV_KHR_variable_pointers"
405 OpMemoryModel Logical GLSL450
406 OpDecorate %param Coherent
407 OpDecorate %ptr_int_StorageBuffer ArrayStride 4
408 %void = OpTypeVoid
409 %bool = OpTypeBool
410 %int = OpTypeInt 32 0
411 %int0 = OpConstant %int 0
412 %int1 = OpConstant %int 1
413 %int10 = OpConstant %int 10
414 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
415 %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer
416 %func = OpFunction %void None %func_ty
417 %param = OpFunctionParameter %ptr_int_StorageBuffer
418 %1 = OpLabel
419 OpBranch %2
420 %2 = OpLabel
421 %phi = OpPhi %ptr_int_StorageBuffer %param %1 %ptr_next %2
422 %iv = OpPhi %int %int0 %1 %inc %2
423 %inc = OpIAdd %int %iv %int1
424 %ptr_next = OpPtrAccessChain %ptr_int_StorageBuffer %phi %int1
425 %cmp = OpIEqual %bool %iv %int10
426 OpLoopMerge %3 %2 None
427 OpBranchConditional %cmp %3 %2
428 %3 = OpLabel
429 %ld = OpLoad %int %phi
430 OpStore %phi %ld
431 OpReturn
432 OpFunctionEnd
433 )";
434 
435   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
436 }
437 
TEST_F(UpgradeMemoryModelTest,CoherentStructElement)438 TEST_F(UpgradeMemoryModelTest, CoherentStructElement) {
439   const std::string text = R"(
440 ; CHECK-NOT: OpMemberDecorate
441 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
442 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
443 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
444 OpCapability Shader
445 OpCapability Linkage
446 OpExtension "SPV_KHR_storage_buffer_storage_class"
447 OpMemoryModel Logical GLSL450
448 OpMemberDecorate %struct 0 Coherent
449 %void = OpTypeVoid
450 %int = OpTypeInt 32 0
451 %int0 = OpConstant %int 0
452 %struct = OpTypeStruct %int
453 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
454 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
455 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
456 %func = OpFunction %void None %func_ty
457 %param = OpFunctionParameter %ptr_struct_StorageBuffer
458 %1 = OpLabel
459 %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
460 %ld = OpLoad %int %gep
461 OpStore %gep %ld
462 OpReturn
463 OpFunctionEnd
464 )";
465 
466   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
467 }
468 
TEST_F(UpgradeMemoryModelTest,CoherentElementFullStructAccess)469 TEST_F(UpgradeMemoryModelTest, CoherentElementFullStructAccess) {
470   const std::string text = R"(
471 ; CHECK-NOT: OpMemberDecorate
472 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
473 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
474 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
475 OpCapability Shader
476 OpCapability Linkage
477 OpExtension "SPV_KHR_storage_buffer_storage_class"
478 OpMemoryModel Logical GLSL450
479 OpMemberDecorate %struct 0 Coherent
480 %void = OpTypeVoid
481 %int = OpTypeInt 32 0
482 %struct = OpTypeStruct %int
483 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
484 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
485 %func = OpFunction %void None %func_ty
486 %param = OpFunctionParameter %ptr_struct_StorageBuffer
487 %1 = OpLabel
488 %ld = OpLoad %struct %param
489 OpStore %param %ld
490 OpReturn
491 OpFunctionEnd
492 )";
493 
494   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
495 }
496 
TEST_F(UpgradeMemoryModelTest,CoherentElementNotAccessed)497 TEST_F(UpgradeMemoryModelTest, CoherentElementNotAccessed) {
498   const std::string text = R"(
499 ; CHECK-NOT: OpMemberDecorate
500 ; CHECK-NOT: MakePointerAvailable
501 ; CHECK-NOT: NonPrivatePointer
502 ; CHECK-NOT: MakePointerVisible
503 OpCapability Shader
504 OpCapability Linkage
505 OpExtension "SPV_KHR_storage_buffer_storage_class"
506 OpMemoryModel Logical GLSL450
507 OpMemberDecorate %struct 1 Coherent
508 %void = OpTypeVoid
509 %int = OpTypeInt 32 0
510 %int0 = OpConstant %int 0
511 %struct = OpTypeStruct %int %int
512 %ptr_struct_StorageBuffer = OpTypePointer StorageBuffer %struct
513 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
514 %func_ty = OpTypeFunction %void %ptr_struct_StorageBuffer
515 %func = OpFunction %void None %func_ty
516 %param = OpFunctionParameter %ptr_struct_StorageBuffer
517 %1 = OpLabel
518 %gep = OpAccessChain %ptr_int_StorageBuffer %param %int0
519 %ld = OpLoad %int %gep
520 OpStore %gep %ld
521 OpReturn
522 OpFunctionEnd
523 )";
524 
525   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
526 }
527 
TEST_F(UpgradeMemoryModelTest,MultiIndexAccessCoherent)528 TEST_F(UpgradeMemoryModelTest, MultiIndexAccessCoherent) {
529   const std::string text = R"(
530 ; CHECK-NOT: OpMemberDecorate
531 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
532 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
533 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
534 OpCapability Shader
535 OpCapability Linkage
536 OpExtension "SPV_KHR_storage_buffer_storage_class"
537 OpMemoryModel Logical GLSL450
538 OpMemberDecorate %inner 1 Coherent
539 %void = OpTypeVoid
540 %int = OpTypeInt 32 0
541 %int0 = OpConstant %int 0
542 %int1 = OpConstant %int 1
543 %inner = OpTypeStruct %int %int
544 %middle = OpTypeStruct %inner
545 %outer = OpTypeStruct %middle %middle
546 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
547 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
548 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
549 %func = OpFunction %void None %func_ty
550 %param = OpFunctionParameter %ptr_outer_StorageBuffer
551 %1 = OpLabel
552 %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int1
553 %ld = OpLoad %int %ld_gep
554 %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int1
555 OpStore %st_gep %ld
556 OpReturn
557 OpFunctionEnd
558 )";
559 
560   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
561 }
562 
TEST_F(UpgradeMemoryModelTest,MultiIndexAccessNonCoherent)563 TEST_F(UpgradeMemoryModelTest, MultiIndexAccessNonCoherent) {
564   const std::string text = R"(
565 ; CHECK-NOT: OpMemberDecorate
566 ; CHECK-NOT: MakePointerAvailable
567 ; CHECK-NOT: NonPrivatePointer
568 ; CHECK-NOT: MakePointerVisible
569 OpCapability Shader
570 OpCapability Linkage
571 OpExtension "SPV_KHR_storage_buffer_storage_class"
572 OpMemoryModel Logical GLSL450
573 OpMemberDecorate %inner 1 Coherent
574 %void = OpTypeVoid
575 %int = OpTypeInt 32 0
576 %int0 = OpConstant %int 0
577 %int1 = OpConstant %int 1
578 %inner = OpTypeStruct %int %int
579 %middle = OpTypeStruct %inner
580 %outer = OpTypeStruct %middle %middle
581 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
582 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
583 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
584 %func = OpFunction %void None %func_ty
585 %param = OpFunctionParameter %ptr_outer_StorageBuffer
586 %1 = OpLabel
587 %ld_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int0 %int0 %int0
588 %ld = OpLoad %int %ld_gep
589 %st_gep = OpInBoundsAccessChain %ptr_int_StorageBuffer %param %int1 %int0 %int0
590 OpStore %st_gep %ld
591 OpReturn
592 OpFunctionEnd
593 )";
594 
595   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
596 }
597 
TEST_F(UpgradeMemoryModelTest,ConsecutiveAccessChainCoherent)598 TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainCoherent) {
599   const std::string text = R"(
600 ; CHECK-NOT: OpMemberDecorate
601 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
602 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
603 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
604 OpCapability Shader
605 OpCapability Linkage
606 OpExtension "SPV_KHR_storage_buffer_storage_class"
607 OpMemoryModel Logical GLSL450
608 OpMemberDecorate %inner 1 Coherent
609 %void = OpTypeVoid
610 %int = OpTypeInt 32 0
611 %int0 = OpConstant %int 0
612 %int1 = OpConstant %int 1
613 %inner = OpTypeStruct %int %int
614 %middle = OpTypeStruct %inner
615 %outer = OpTypeStruct %middle %middle
616 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
617 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
618 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
619 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
620 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
621 %func = OpFunction %void None %func_ty
622 %param = OpFunctionParameter %ptr_outer_StorageBuffer
623 %1 = OpLabel
624 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
625 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
626 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
627 %ld = OpLoad %int %ld_gep3
628 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
629 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
630 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
631 OpStore %st_gep3 %ld
632 OpReturn
633 OpFunctionEnd
634 )";
635 
636   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
637 }
638 
TEST_F(UpgradeMemoryModelTest,ConsecutiveAccessChainNonCoherent)639 TEST_F(UpgradeMemoryModelTest, ConsecutiveAccessChainNonCoherent) {
640   const std::string text = R"(
641 ; CHECK-NOT: OpMemberDecorate
642 ; CHECK-NOT: MakePointerAvailable
643 ; CHECK-NOT: NonPrivatePointer
644 ; CHECK-NOT: MakePointerVisible
645 OpCapability Shader
646 OpCapability Linkage
647 OpExtension "SPV_KHR_storage_buffer_storage_class"
648 OpMemoryModel Logical GLSL450
649 OpMemberDecorate %inner 1 Coherent
650 %void = OpTypeVoid
651 %int = OpTypeInt 32 0
652 %int0 = OpConstant %int 0
653 %int1 = OpConstant %int 1
654 %inner = OpTypeStruct %int %int
655 %middle = OpTypeStruct %inner
656 %outer = OpTypeStruct %middle %middle
657 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
658 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
659 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
660 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
661 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
662 %func = OpFunction %void None %func_ty
663 %param = OpFunctionParameter %ptr_outer_StorageBuffer
664 %1 = OpLabel
665 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
666 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
667 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int0
668 %ld = OpLoad %int %ld_gep3
669 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
670 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
671 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int0
672 OpStore %st_gep3 %ld
673 OpReturn
674 OpFunctionEnd
675 )";
676 
677   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
678 }
679 
TEST_F(UpgradeMemoryModelTest,CoherentStructElementAccess)680 TEST_F(UpgradeMemoryModelTest, CoherentStructElementAccess) {
681   const std::string text = R"(
682 ; CHECK-NOT: OpMemberDecorate
683 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
684 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
685 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
686 OpCapability Shader
687 OpCapability Linkage
688 OpExtension "SPV_KHR_storage_buffer_storage_class"
689 OpMemoryModel Logical GLSL450
690 OpMemberDecorate %middle 0 Coherent
691 %void = OpTypeVoid
692 %int = OpTypeInt 32 0
693 %int0 = OpConstant %int 0
694 %int1 = OpConstant %int 1
695 %inner = OpTypeStruct %int %int
696 %middle = OpTypeStruct %inner
697 %outer = OpTypeStruct %middle %middle
698 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
699 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
700 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
701 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
702 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
703 %func = OpFunction %void None %func_ty
704 %param = OpFunctionParameter %ptr_outer_StorageBuffer
705 %1 = OpLabel
706 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
707 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
708 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
709 %ld = OpLoad %int %ld_gep3
710 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
711 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
712 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
713 OpStore %st_gep3 %ld
714 OpReturn
715 OpFunctionEnd
716 )";
717 
718   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
719 }
720 
TEST_F(UpgradeMemoryModelTest,NonCoherentLoadCoherentStore)721 TEST_F(UpgradeMemoryModelTest, NonCoherentLoadCoherentStore) {
722   const std::string text = R"(
723 ; CHECK-NOT: OpMemberDecorate
724 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
725 ; CHECK-NOT: MakePointerVisible
726 ; CHECK: OpStore {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]]
727 OpCapability Shader
728 OpCapability Linkage
729 OpExtension "SPV_KHR_storage_buffer_storage_class"
730 OpMemoryModel Logical GLSL450
731 OpMemberDecorate %outer 1 Coherent
732 %void = OpTypeVoid
733 %int = OpTypeInt 32 0
734 %int0 = OpConstant %int 0
735 %int1 = OpConstant %int 1
736 %inner = OpTypeStruct %int %int
737 %middle = OpTypeStruct %inner
738 %outer = OpTypeStruct %middle %middle
739 %ptr_outer_StorageBuffer = OpTypePointer StorageBuffer %outer
740 %ptr_middle_StorageBuffer = OpTypePointer StorageBuffer %middle
741 %ptr_inner_StorageBuffer = OpTypePointer StorageBuffer %inner
742 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
743 %func_ty = OpTypeFunction %void %ptr_outer_StorageBuffer
744 %func = OpFunction %void None %func_ty
745 %param = OpFunctionParameter %ptr_outer_StorageBuffer
746 %1 = OpLabel
747 %ld_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int0
748 %ld_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %ld_gep1 %int0
749 %ld_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %ld_gep2 %int1
750 %ld = OpLoad %int %ld_gep3
751 %st_gep1 = OpInBoundsAccessChain %ptr_middle_StorageBuffer %param %int1
752 %st_gep2 = OpInBoundsAccessChain %ptr_inner_StorageBuffer %st_gep1 %int0
753 %st_gep3 = OpInBoundsAccessChain %ptr_int_StorageBuffer %st_gep2 %int1
754 OpStore %st_gep3 %ld
755 OpReturn
756 OpFunctionEnd
757 )";
758 
759   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
760 }
761 
TEST_F(UpgradeMemoryModelTest,CopyMemory)762 TEST_F(UpgradeMemoryModelTest, CopyMemory) {
763   const std::string text = R"(
764 ; CHECK-NOT: OpDecorate
765 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
766 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|MakePointerVisible|NonPrivatePointer [[queuefamily]]
767 ; CHECK-NOT: [[queuefamily]]
768 OpCapability Shader
769 OpCapability Linkage
770 OpExtension "SPV_KHR_storage_buffer_storage_class"
771 OpMemoryModel Logical GLSL450
772 OpDecorate %in_var Coherent
773 OpDecorate %out_var Volatile
774 %void = OpTypeVoid
775 %int = OpTypeInt 32 0
776 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
777 %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
778 %out_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
779 %func_ty = OpTypeFunction %void
780 %func = OpFunction %void None %func_ty
781 %1 = OpLabel
782 OpCopyMemory %out_var %in_var
783 OpReturn
784 OpFunctionEnd
785 )";
786 
787   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
788 }
789 
TEST_F(UpgradeMemoryModelTest,CopyMemorySized)790 TEST_F(UpgradeMemoryModelTest, CopyMemorySized) {
791   const std::string text = R"(
792 ; CHECK-NOT: OpDecorate
793 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
794 ; CHECK: OpCopyMemorySized {{%\w+}} {{%\w+}} {{%\w+}} Volatile|MakePointerAvailable|NonPrivatePointer [[queuefamily]]
795 ; CHECK-NOT: [[queuefamily]]
796 OpCapability Shader
797 OpCapability Linkage
798 OpCapability Addresses
799 OpExtension "SPV_KHR_storage_buffer_storage_class"
800 OpMemoryModel Logical GLSL450
801 OpDecorate %out_param Coherent
802 OpDecorate %in_param Volatile
803 %void = OpTypeVoid
804 %int = OpTypeInt 32 0
805 %int4 = OpConstant %int 4
806 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
807 %func_ty = OpTypeFunction %void %ptr_int_StorageBuffer %ptr_int_StorageBuffer
808 %func = OpFunction %void None %func_ty
809 %in_param = OpFunctionParameter %ptr_int_StorageBuffer
810 %out_param = OpFunctionParameter %ptr_int_StorageBuffer
811 %1 = OpLabel
812 OpCopyMemorySized %out_param %in_param %int4
813 OpReturn
814 OpFunctionEnd
815 )";
816 
817   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
818 }
819 
TEST_F(UpgradeMemoryModelTest,CopyMemoryTwoScopes)820 TEST_F(UpgradeMemoryModelTest, CopyMemoryTwoScopes) {
821   const std::string text = R"(
822 ; CHECK-NOT: OpDecorate
823 ; CHECK-DAG: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
824 ; CHECK-DAG: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
825 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|MakePointerVisible|NonPrivatePointer [[workgroup]] [[queuefamily]]
826 OpCapability Shader
827 OpCapability Linkage
828 OpExtension "SPV_KHR_storage_buffer_storage_class"
829 OpMemoryModel Logical GLSL450
830 OpDecorate %in_var Coherent
831 OpDecorate %out_var Coherent
832 %void = OpTypeVoid
833 %int = OpTypeInt 32 0
834 %ptr_int_Workgroup = OpTypePointer Workgroup %int
835 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
836 %in_var = OpVariable %ptr_int_StorageBuffer StorageBuffer
837 %out_var = OpVariable %ptr_int_Workgroup Workgroup
838 %func_ty = OpTypeFunction %void
839 %func = OpFunction %void None %func_ty
840 %1 = OpLabel
841 OpCopyMemory %out_var %in_var
842 OpReturn
843 OpFunctionEnd
844 )";
845 
846   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
847 }
848 
TEST_F(UpgradeMemoryModelTest,VolatileImageRead)849 TEST_F(UpgradeMemoryModelTest, VolatileImageRead) {
850   const std::string text = R"(
851 ; CHECK-NOT: OpDecorate
852 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
853 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
854 OpCapability Shader
855 OpCapability Linkage
856 OpCapability StorageImageReadWithoutFormat
857 OpExtension "SPV_KHR_storage_buffer_storage_class"
858 OpMemoryModel Logical GLSL450
859 OpDecorate %var Volatile
860 %void = OpTypeVoid
861 %int = OpTypeInt 32 0
862 %v2int = OpTypeVector %int 2
863 %float = OpTypeFloat 32
864 %int0 = OpConstant %int 0
865 %v2int_0 = OpConstantComposite %v2int %int0 %int0
866 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
867 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
868 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
869 %func_ty = OpTypeFunction %void
870 %func = OpFunction %void None %func_ty
871 %1 = OpLabel
872 %ld = OpLoad %image %var
873 %rd = OpImageRead %float %ld %v2int_0
874 OpReturn
875 OpFunctionEnd
876 )";
877 
878   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
879 }
880 
TEST_F(UpgradeMemoryModelTest,CoherentImageRead)881 TEST_F(UpgradeMemoryModelTest, CoherentImageRead) {
882   const std::string text = R"(
883 ; CHECK-NOT: OpDecorate
884 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
885 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
886 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
887 OpCapability Shader
888 OpCapability Linkage
889 OpCapability StorageImageReadWithoutFormat
890 OpExtension "SPV_KHR_storage_buffer_storage_class"
891 OpMemoryModel Logical GLSL450
892 OpDecorate %var Coherent
893 %void = OpTypeVoid
894 %int = OpTypeInt 32 0
895 %v2int = OpTypeVector %int 2
896 %float = OpTypeFloat 32
897 %int0 = OpConstant %int 0
898 %v2int_0 = OpConstantComposite %v2int %int0 %int0
899 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
900 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
901 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
902 %func_ty = OpTypeFunction %void
903 %func = OpFunction %void None %func_ty
904 %1 = OpLabel
905 %ld = OpLoad %image %var
906 %rd = OpImageRead %float %ld %v2int_0
907 OpReturn
908 OpFunctionEnd
909 )";
910 
911   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
912 }
913 
TEST_F(UpgradeMemoryModelTest,CoherentImageReadExtractedFromSampledImage)914 TEST_F(UpgradeMemoryModelTest, CoherentImageReadExtractedFromSampledImage) {
915   const std::string text = R"(
916 ; CHECK-NOT: OpDecorate
917 ; CHECK: [[image:%\w+]] = OpTypeImage
918 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
919 ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
920 ; CHECK-NOT: NonPrivatePointer
921 ; CHECK: OpImageRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
922 OpCapability Shader
923 OpCapability Linkage
924 OpCapability StorageImageReadWithoutFormat
925 OpExtension "SPV_KHR_storage_buffer_storage_class"
926 OpMemoryModel Logical GLSL450
927 OpDecorate %var Coherent
928 %void = OpTypeVoid
929 %int = OpTypeInt 32 0
930 %v2int = OpTypeVector %int 2
931 %float = OpTypeFloat 32
932 %int0 = OpConstant %int 0
933 %v2int_0 = OpConstantComposite %v2int %int0 %int0
934 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
935 %sampled_image = OpTypeSampledImage %image
936 %sampler = OpTypeSampler
937 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
938 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
939 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
940 %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
941 %func_ty = OpTypeFunction %void
942 %func = OpFunction %void None %func_ty
943 %1 = OpLabel
944 %ld = OpLoad %image %var
945 %ld_sampler = OpLoad %sampler %sampler_var
946 %sample = OpSampledImage %sampled_image %ld %ld_sampler
947 %extract = OpImage %image %sample
948 %rd = OpImageRead %float %extract %v2int_0
949 OpReturn
950 OpFunctionEnd
951 )";
952 
953   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
954 }
955 
TEST_F(UpgradeMemoryModelTest,VolatileImageWrite)956 TEST_F(UpgradeMemoryModelTest, VolatileImageWrite) {
957   const std::string text = R"(
958 ; CHECK-NOT: OpDecorate
959 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
960 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
961 OpCapability Shader
962 OpCapability Linkage
963 OpCapability StorageImageWriteWithoutFormat
964 OpExtension "SPV_KHR_storage_buffer_storage_class"
965 OpMemoryModel Logical GLSL450
966 OpDecorate %param Volatile
967 %void = OpTypeVoid
968 %int = OpTypeInt 32 0
969 %v2int = OpTypeVector %int 2
970 %float = OpTypeFloat 32
971 %float0 = OpConstant %float 0
972 %v2int_null = OpConstantNull %v2int
973 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
974 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
975 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
976 %func = OpFunction %void None %func_ty
977 %param = OpFunctionParameter %ptr_image_StorageBuffer
978 %1 = OpLabel
979 %ld = OpLoad %image %param
980 OpImageWrite %ld %v2int_null %float0
981 OpReturn
982 OpFunctionEnd
983 )";
984 
985   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
986 }
987 
TEST_F(UpgradeMemoryModelTest,CoherentImageWrite)988 TEST_F(UpgradeMemoryModelTest, CoherentImageWrite) {
989   const std::string text = R"(
990 ; CHECK-NOT: OpDecorate
991 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
992 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
993 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
994 OpCapability Shader
995 OpCapability Linkage
996 OpCapability StorageImageWriteWithoutFormat
997 OpExtension "SPV_KHR_storage_buffer_storage_class"
998 OpMemoryModel Logical GLSL450
999 OpDecorate %param Coherent
1000 %void = OpTypeVoid
1001 %int = OpTypeInt 32 0
1002 %v2int = OpTypeVector %int 2
1003 %float = OpTypeFloat 32
1004 %float0 = OpConstant %float 0
1005 %v2int_null = OpConstantNull %v2int
1006 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1007 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1008 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer
1009 %func = OpFunction %void None %func_ty
1010 %param = OpFunctionParameter %ptr_image_StorageBuffer
1011 %1 = OpLabel
1012 %ld = OpLoad %image %param
1013 OpImageWrite %ld %v2int_null %float0
1014 OpReturn
1015 OpFunctionEnd
1016 )";
1017 
1018   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1019 }
1020 
TEST_F(UpgradeMemoryModelTest,CoherentImageWriteExtractFromSampledImage)1021 TEST_F(UpgradeMemoryModelTest, CoherentImageWriteExtractFromSampledImage) {
1022   const std::string text = R"(
1023 ; CHECK-NOT: OpDecorate
1024 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1025 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer
1026 ; CHECK-NOT: NonPrivatePointer
1027 ; CHECK: OpImageWrite {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelAvailable|NonPrivateTexel [[scope]]
1028 OpCapability Shader
1029 OpCapability Linkage
1030 OpCapability StorageImageWriteWithoutFormat
1031 OpExtension "SPV_KHR_storage_buffer_storage_class"
1032 OpMemoryModel Logical GLSL450
1033 OpDecorate %param Coherent
1034 %void = OpTypeVoid
1035 %int = OpTypeInt 32 0
1036 %v2int = OpTypeVector %int 2
1037 %float = OpTypeFloat 32
1038 %float0 = OpConstant %float 0
1039 %v2int_null = OpConstantNull %v2int
1040 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1041 %sampled_image = OpTypeSampledImage %image
1042 %sampler = OpTypeSampler
1043 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1044 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
1045 %func_ty = OpTypeFunction %void %ptr_image_StorageBuffer %ptr_sampler_StorageBuffer
1046 %func = OpFunction %void None %func_ty
1047 %param = OpFunctionParameter %ptr_image_StorageBuffer
1048 %sampler_param = OpFunctionParameter %ptr_sampler_StorageBuffer
1049 %1 = OpLabel
1050 %ld = OpLoad %image %param
1051 %ld_sampler = OpLoad %sampler %sampler_param
1052 %sample = OpSampledImage %sampled_image %ld %ld_sampler
1053 %extract = OpImage %image %sample
1054 OpImageWrite %extract %v2int_null %float0
1055 OpReturn
1056 OpFunctionEnd
1057 )";
1058 
1059   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1060 }
1061 
TEST_F(UpgradeMemoryModelTest,VolatileImageSparseRead)1062 TEST_F(UpgradeMemoryModelTest, VolatileImageSparseRead) {
1063   const std::string text = R"(
1064 ; CHECK-NOT: OpDecorate
1065 ; CHECK: OpLoad {{%\w+}} {{%\w+}} Volatile
1066 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} VolatileTexel
1067 OpCapability Shader
1068 OpCapability Linkage
1069 OpCapability StorageImageReadWithoutFormat
1070 OpCapability SparseResidency
1071 OpExtension "SPV_KHR_storage_buffer_storage_class"
1072 OpMemoryModel Logical GLSL450
1073 OpDecorate %var Volatile
1074 %void = OpTypeVoid
1075 %int = OpTypeInt 32 0
1076 %v2int = OpTypeVector %int 2
1077 %float = OpTypeFloat 32
1078 %int0 = OpConstant %int 0
1079 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1080 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
1081 %struct = OpTypeStruct %int %float
1082 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1083 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1084 %func_ty = OpTypeFunction %void
1085 %func = OpFunction %void None %func_ty
1086 %1 = OpLabel
1087 %ld = OpLoad %image %var
1088 %rd = OpImageSparseRead %struct %ld %v2int_0
1089 OpReturn
1090 OpFunctionEnd
1091 )";
1092 
1093   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1094 }
1095 
TEST_F(UpgradeMemoryModelTest,CoherentImageSparseRead)1096 TEST_F(UpgradeMemoryModelTest, CoherentImageSparseRead) {
1097   const std::string text = R"(
1098 ; CHECK-NOT: OpDecorate
1099 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1100 ; CHECK: OpLoad {{%\w+}} {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
1101 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
1102 OpCapability Shader
1103 OpCapability Linkage
1104 OpCapability StorageImageReadWithoutFormat
1105 OpCapability SparseResidency
1106 OpExtension "SPV_KHR_storage_buffer_storage_class"
1107 OpMemoryModel Logical GLSL450
1108 OpDecorate %var Coherent
1109 %void = OpTypeVoid
1110 %int = OpTypeInt 32 0
1111 %v2int = OpTypeVector %int 2
1112 %float = OpTypeFloat 32
1113 %int0 = OpConstant %int 0
1114 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1115 %image = OpTypeImage %float 2D 0 0 0 2 Unknown
1116 %struct = OpTypeStruct %int %float
1117 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1118 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1119 %func_ty = OpTypeFunction %void
1120 %func = OpFunction %void None %func_ty
1121 %1 = OpLabel
1122 %ld = OpLoad %image %var
1123 %rd = OpImageSparseRead %struct %ld %v2int_0
1124 OpReturn
1125 OpFunctionEnd
1126 )";
1127 
1128   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1129 }
1130 
TEST_F(UpgradeMemoryModelTest,CoherentImageSparseReadExtractedFromSampledImage)1131 TEST_F(UpgradeMemoryModelTest,
1132        CoherentImageSparseReadExtractedFromSampledImage) {
1133   const std::string text = R"(
1134 ; CHECK-NOT: OpDecorate
1135 ; CHECK: [[image:%\w+]] = OpTypeImage
1136 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1137 ; CHECK: OpLoad [[image]] {{%\w+}} MakePointerVisible|NonPrivatePointer [[scope]]
1138 ; CHECK-NOT: NonPrivatePointer
1139 ; CHECK: OpImageSparseRead {{%\w+}} {{%\w+}} {{%\w+}} MakeTexelVisible|NonPrivateTexel [[scope]]
1140 OpCapability Shader
1141 OpCapability Linkage
1142 OpCapability StorageImageReadWithoutFormat
1143 OpCapability SparseResidency
1144 OpExtension "SPV_KHR_storage_buffer_storage_class"
1145 OpMemoryModel Logical GLSL450
1146 OpDecorate %var Coherent
1147 %void = OpTypeVoid
1148 %int = OpTypeInt 32 0
1149 %v2int = OpTypeVector %int 2
1150 %float = OpTypeFloat 32
1151 %int0 = OpConstant %int 0
1152 %v2int_0 = OpConstantComposite %v2int %int0 %int0
1153 %image = OpTypeImage %float 2D 0 0 0 0 Unknown
1154 %struct = OpTypeStruct %int %float
1155 %sampled_image = OpTypeSampledImage %image
1156 %sampler = OpTypeSampler
1157 %ptr_image_StorageBuffer = OpTypePointer StorageBuffer %image
1158 %ptr_sampler_StorageBuffer = OpTypePointer StorageBuffer %sampler
1159 %var = OpVariable %ptr_image_StorageBuffer StorageBuffer
1160 %sampler_var = OpVariable %ptr_sampler_StorageBuffer StorageBuffer
1161 %func_ty = OpTypeFunction %void
1162 %func = OpFunction %void None %func_ty
1163 %1 = OpLabel
1164 %ld = OpLoad %image %var
1165 %ld_sampler = OpLoad %sampler %sampler_var
1166 %sample = OpSampledImage %sampled_image %ld %ld_sampler
1167 %extract = OpImage %image %sample
1168 %rd = OpImageSparseRead %struct %extract %v2int_0
1169 OpReturn
1170 OpFunctionEnd
1171 )";
1172 
1173   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1174 }
1175 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierNoChange)1176 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierNoChange) {
1177   const std::string text = R"(
1178 ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
1179 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1180 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[none]]
1181 OpCapability Tessellation
1182 OpMemoryModel Logical GLSL450
1183 OpEntryPoint TessellationControl %func "func"
1184 %void = OpTypeVoid
1185 %int = OpTypeInt 32 0
1186 %none = OpConstant %int 0
1187 %workgroup = OpConstant %int 2
1188 %func_ty = OpTypeFunction %void
1189 %func = OpFunction %void None %func_ty
1190 %1 = OpLabel
1191 OpControlBarrier %workgroup %workgroup %none
1192 OpReturn
1193 OpFunctionEnd
1194 )";
1195 
1196   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1197 }
1198 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutput)1199 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutput) {
1200   const std::string text = R"(
1201 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1202 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1203 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1204 OpCapability Tessellation
1205 OpMemoryModel Logical GLSL450
1206 OpEntryPoint TessellationControl %func "func" %var
1207 %void = OpTypeVoid
1208 %int = OpTypeInt 32 0
1209 %none = OpConstant %int 0
1210 %workgroup = OpConstant %int 2
1211 %ptr_int_Output = OpTypePointer Output %int
1212 %var = OpVariable %ptr_int_Output Output
1213 %func_ty = OpTypeFunction %void
1214 %func = OpFunction %void None %func_ty
1215 %1 = OpLabel
1216 %ld = OpLoad %int %var
1217 OpControlBarrier %workgroup %workgroup %none
1218 OpStore %var %ld
1219 OpReturn
1220 OpFunctionEnd
1221 )";
1222 
1223   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1224 }
1225 
TEST_F(UpgradeMemoryModelTest,TessellationMemoryBarrierNoChange)1226 TEST_F(UpgradeMemoryModelTest, TessellationMemoryBarrierNoChange) {
1227   const std::string text = R"(
1228 ; CHECK: [[none:%\w+]] = OpConstant {{%\w+}} 0
1229 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1230 ; CHECK: OpMemoryBarrier [[workgroup]] [[none]]
1231 OpCapability Tessellation
1232 OpMemoryModel Logical GLSL450
1233 OpEntryPoint TessellationControl %func "func" %var
1234 %void = OpTypeVoid
1235 %int = OpTypeInt 32 0
1236 %none = OpConstant %int 0
1237 %workgroup = OpConstant %int 2
1238 %ptr_int_Output = OpTypePointer Output %int
1239 %var = OpVariable %ptr_int_Output Output
1240 %func_ty = OpTypeFunction %void
1241 %func = OpFunction %void None %func_ty
1242 %1 = OpLabel
1243 %ld = OpLoad %int %var
1244 OpMemoryBarrier %workgroup %none
1245 OpStore %var %ld
1246 OpReturn
1247 OpFunctionEnd
1248 )";
1249 
1250   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1251 }
1252 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutputSubFunction)1253 TEST_F(UpgradeMemoryModelTest, TessellationControlBarrierAddOutputSubFunction) {
1254   const std::string text = R"(
1255 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1256 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1257 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1258 OpCapability Tessellation
1259 OpMemoryModel Logical GLSL450
1260 OpEntryPoint TessellationControl %func "func" %var
1261 %void = OpTypeVoid
1262 %int = OpTypeInt 32 0
1263 %none = OpConstant %int 0
1264 %workgroup = OpConstant %int 2
1265 %ptr_int_Output = OpTypePointer Output %int
1266 %var = OpVariable %ptr_int_Output Output
1267 %func_ty = OpTypeFunction %void
1268 %func = OpFunction %void None %func_ty
1269 %1 = OpLabel
1270 %call = OpFunctionCall %void %sub_func
1271 OpReturn
1272 OpFunctionEnd
1273 %sub_func = OpFunction %void None %func_ty
1274 %2 = OpLabel
1275 %ld = OpLoad %int %var
1276 OpControlBarrier %workgroup %workgroup %none
1277 OpStore %var %ld
1278 OpReturn
1279 OpFunctionEnd
1280 )";
1281 
1282   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1283 }
1284 
TEST_F(UpgradeMemoryModelTest,TessellationControlBarrierAddOutputDifferentFunctions)1285 TEST_F(UpgradeMemoryModelTest,
1286        TessellationControlBarrierAddOutputDifferentFunctions) {
1287   const std::string text = R"(
1288 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1289 ; CHECK: [[output:%\w+]] = OpConstant {{%\w+}} 4096
1290 ; CHECK: OpControlBarrier [[workgroup]] [[workgroup]] [[output]]
1291 OpCapability Tessellation
1292 OpMemoryModel Logical GLSL450
1293 OpEntryPoint TessellationControl %func "func" %var
1294 %void = OpTypeVoid
1295 %int = OpTypeInt 32 0
1296 %none = OpConstant %int 0
1297 %workgroup = OpConstant %int 2
1298 %ptr_int_Output = OpTypePointer Output %int
1299 %var = OpVariable %ptr_int_Output Output
1300 %func_ty = OpTypeFunction %void
1301 %ld_func_ty = OpTypeFunction %int
1302 %st_func_ty = OpTypeFunction %void %int
1303 %func = OpFunction %void None %func_ty
1304 %1 = OpLabel
1305 %call_ld = OpFunctionCall %int %ld_func
1306 %call_barrier = OpFunctionCall %void %barrier_func
1307 %call_st = OpFunctionCall %void %st_func %call_ld
1308 OpReturn
1309 OpFunctionEnd
1310 %ld_func = OpFunction %int None %ld_func_ty
1311 %2 = OpLabel
1312 %ld = OpLoad %int %var
1313 OpReturnValue %ld
1314 OpFunctionEnd
1315 %barrier_func = OpFunction %void None %func_ty
1316 %3 = OpLabel
1317 OpControlBarrier %workgroup %workgroup %none
1318 OpReturn
1319 OpFunctionEnd
1320 %st_func = OpFunction %void None %st_func_ty
1321 %param = OpFunctionParameter %int
1322 %4 = OpLabel
1323 OpStore %var %param
1324 OpReturn
1325 OpFunctionEnd
1326 )";
1327 
1328   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1329 }
1330 
TEST_F(UpgradeMemoryModelTest,ChangeControlBarrierMemoryScope)1331 TEST_F(UpgradeMemoryModelTest, ChangeControlBarrierMemoryScope) {
1332   std::string text = R"(
1333 ; CHECK: [[workgroup:%\w+]] = OpConstant {{%\w+}} 2
1334 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
1335 ; CHECK: OpControlBarrier [[workgroup]] [[queuefamily]]
1336 OpCapability Shader
1337 OpMemoryModel Logical GLSL450
1338 OpEntryPoint GLCompute %func "func"
1339 %void = OpTypeVoid
1340 %int = OpTypeInt 32 0
1341 %none = OpConstant %int 0
1342 %device = OpConstant %int 1
1343 %workgroup = OpConstant %int 2
1344 %func_ty = OpTypeFunction %void
1345 %func = OpFunction %void None %func_ty
1346 %1 = OpLabel
1347 OpControlBarrier %workgroup %device %none
1348 OpReturn
1349 OpFunctionEnd
1350 )";
1351 
1352   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1353 }
1354 
TEST_F(UpgradeMemoryModelTest,ChangeMemoryBarrierMemoryScope)1355 TEST_F(UpgradeMemoryModelTest, ChangeMemoryBarrierMemoryScope) {
1356   std::string text = R"(
1357 ; CHECK: [[queuefamily:%\w+]] = OpConstant {{%\w+}} 5
1358 ; CHECK: OpMemoryBarrier [[queuefamily]]
1359 OpCapability Shader
1360 OpMemoryModel Logical GLSL450
1361 OpEntryPoint GLCompute %func "func"
1362 %void = OpTypeVoid
1363 %int = OpTypeInt 32 0
1364 %none = OpConstant %int 0
1365 %device = OpConstant %int 1
1366 %func_ty = OpTypeFunction %void
1367 %func = OpFunction %void None %func_ty
1368 %1 = OpLabel
1369 OpMemoryBarrier %device %none
1370 OpReturn
1371 OpFunctionEnd
1372 )";
1373 
1374   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1375 }
1376 
TEST_F(UpgradeMemoryModelTest,ChangeAtomicMemoryScope)1377 TEST_F(UpgradeMemoryModelTest, ChangeAtomicMemoryScope) {
1378   std::string text = R"(
1379 ; CHECK: [[int:%\w+]] = OpTypeInt
1380 ; CHECK: [[var:%\w+]] = OpVariable
1381 ; CHECK: [[qf:%\w+]] = OpConstant [[int]] 5
1382 ; CHECK: OpAtomicLoad [[int]] [[var]] [[qf]]
1383 ; CHECK: OpAtomicStore [[var]] [[qf]]
1384 ; CHECK: OpAtomicExchange [[int]] [[var]] [[qf]]
1385 ; CHECK: OpAtomicCompareExchange [[int]] [[var]] [[qf]]
1386 ; CHECK: OpAtomicIIncrement [[int]] [[var]] [[qf]]
1387 ; CHECK: OpAtomicIDecrement [[int]] [[var]] [[qf]]
1388 ; CHECK: OpAtomicIAdd [[int]] [[var]] [[qf]]
1389 ; CHECK: OpAtomicISub [[int]] [[var]] [[qf]]
1390 ; CHECK: OpAtomicSMin [[int]] [[var]] [[qf]]
1391 ; CHECK: OpAtomicSMax [[int]] [[var]] [[qf]]
1392 ; CHECK: OpAtomicUMin [[int]] [[var]] [[qf]]
1393 ; CHECK: OpAtomicUMax [[int]] [[var]] [[qf]]
1394 ; CHECK: OpAtomicAnd [[int]] [[var]] [[qf]]
1395 ; CHECK: OpAtomicOr [[int]] [[var]] [[qf]]
1396 ; CHECK: OpAtomicXor [[int]] [[var]] [[qf]]
1397 OpCapability Shader
1398 OpExtension "SPV_KHR_storage_buffer_storage_class"
1399 OpMemoryModel Logical GLSL450
1400 OpEntryPoint GLCompute %func "func"
1401 %void = OpTypeVoid
1402 %int = OpTypeInt 32 0
1403 %none = OpConstant %int 0
1404 %device = OpConstant %int 1
1405 %func_ty = OpTypeFunction %void
1406 %ptr_int_StorageBuffer = OpTypePointer StorageBuffer %int
1407 %var = OpVariable %ptr_int_StorageBuffer StorageBuffer
1408 %func = OpFunction %void None %func_ty
1409 %1 = OpLabel
1410 %ld = OpAtomicLoad %int %var %device %none
1411 OpAtomicStore %var %device %none %ld
1412 %ex = OpAtomicExchange %int %var %device %none %ld
1413 %cmp_ex = OpAtomicCompareExchange %int %var %device %none %none %ld %ld
1414 %inc = OpAtomicIIncrement %int %var %device %none
1415 %dec = OpAtomicIDecrement %int %var %device %none
1416 %add = OpAtomicIAdd %int %var %device %none %ld
1417 %sub = OpAtomicISub %int %var %device %none %ld
1418 %smin = OpAtomicSMin %int %var %device %none %ld
1419 %smax = OpAtomicSMax %int %var %device %none %ld
1420 %umin = OpAtomicUMin %int %var %device %none %ld
1421 %umax = OpAtomicUMax %int %var %device %none %ld
1422 %and = OpAtomicAnd %int %var %device %none %ld
1423 %or = OpAtomicOr %int %var %device %none %ld
1424 %xor = OpAtomicXor %int %var %device %none %ld
1425 OpReturn
1426 OpFunctionEnd
1427 )";
1428 
1429   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1430 }
1431 
TEST_F(UpgradeMemoryModelTest,UpgradeModfNoFlags)1432 TEST_F(UpgradeMemoryModelTest, UpgradeModfNoFlags) {
1433   const std::string text = R"(
1434 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1435 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1436 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
1437 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1438 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
1439 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
1440 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1441 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
1442 ; CHECK: OpStore [[var]] [[ex1]]
1443 ; CHECK-NOT: NonPrivatePointer
1444 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1445 OpCapability Shader
1446 OpMemoryModel Logical GLSL450
1447 %import = OpExtInstImport "GLSL.std.450"
1448 OpEntryPoint GLCompute %func "func"
1449 %void = OpTypeVoid
1450 %float = OpTypeFloat 32
1451 %float_0 = OpConstant %float 0
1452 %ptr_ssbo_float = OpTypePointer StorageBuffer %float
1453 %ssbo_var = OpVariable %ptr_ssbo_float StorageBuffer
1454 %func_ty = OpTypeFunction %void
1455 %func = OpFunction %void None %func_ty
1456 %1 = OpLabel
1457 %2 = OpExtInst %float %import Modf %float_0 %ssbo_var
1458 %3 = OpFAdd %float %float_0 %2
1459 OpReturn
1460 OpFunctionEnd
1461 )";
1462 
1463   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1464 }
1465 
TEST_F(UpgradeMemoryModelTest,UpgradeModfWorkgroupCoherent)1466 TEST_F(UpgradeMemoryModelTest, UpgradeModfWorkgroupCoherent) {
1467   const std::string text = R"(
1468 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1469 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1470 ; CHECK: [[ptr:%\w+]] = OpTypePointer Workgroup [[float]]
1471 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] Workgroup
1472 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
1473 ; CHECK: [[wg_scope:%\w+]] = OpConstant {{%\w+}} 2
1474 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
1475 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1476 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
1477 ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
1478 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1479 OpCapability Shader
1480 OpMemoryModel Logical GLSL450
1481 %import = OpExtInstImport "GLSL.std.450"
1482 OpEntryPoint GLCompute %func "func"
1483 OpDecorate %wg_var Coherent
1484 %void = OpTypeVoid
1485 %float = OpTypeFloat 32
1486 %float_0 = OpConstant %float 0
1487 %ptr_wg_float = OpTypePointer Workgroup %float
1488 %wg_var = OpVariable %ptr_wg_float Workgroup
1489 %func_ty = OpTypeFunction %void
1490 %func = OpFunction %void None %func_ty
1491 %1 = OpLabel
1492 %2 = OpExtInst %float %import Modf %float_0 %wg_var
1493 %3 = OpFAdd %float %float_0 %2
1494 OpReturn
1495 OpFunctionEnd
1496 )";
1497 
1498   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1499 }
1500 
TEST_F(UpgradeMemoryModelTest,UpgradeModfSSBOCoherent)1501 TEST_F(UpgradeMemoryModelTest, UpgradeModfSSBOCoherent) {
1502   const std::string text = R"(
1503 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1504 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1505 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
1506 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1507 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
1508 ; CHECK: [[qf_scope:%\w+]] = OpConstant {{%\w+}} 5
1509 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
1510 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1511 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
1512 ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
1513 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1514 OpCapability Shader
1515 OpMemoryModel Logical GLSL450
1516 %import = OpExtInstImport "GLSL.std.450"
1517 OpEntryPoint GLCompute %func "func"
1518 OpDecorate %ssbo_var Coherent
1519 %void = OpTypeVoid
1520 %float = OpTypeFloat 32
1521 %float_0 = OpConstant %float 0
1522 %ptr_ssbo_float = OpTypePointer StorageBuffer %float
1523 %ssbo_var = OpVariable %ptr_ssbo_float StorageBuffer
1524 %func_ty = OpTypeFunction %void
1525 %func = OpFunction %void None %func_ty
1526 %1 = OpLabel
1527 %2 = OpExtInst %float %import Modf %float_0 %ssbo_var
1528 %3 = OpFAdd %float %float_0 %2
1529 OpReturn
1530 OpFunctionEnd
1531 )";
1532 
1533   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1534 }
1535 
TEST_F(UpgradeMemoryModelTest,UpgradeModfSSBOVolatile)1536 TEST_F(UpgradeMemoryModelTest, UpgradeModfSSBOVolatile) {
1537   const std::string text = R"(
1538 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1539 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1540 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[float]]
1541 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1542 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[float]]
1543 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} ModfStruct [[float_0]]
1544 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1545 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 1
1546 ; CHECK: OpStore [[var]] [[ex1]] Volatile
1547 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1548 OpCapability Shader
1549 OpMemoryModel Logical GLSL450
1550 %import = OpExtInstImport "GLSL.std.450"
1551 OpEntryPoint GLCompute %func "func"
1552 OpDecorate %wg_var Volatile
1553 %void = OpTypeVoid
1554 %float = OpTypeFloat 32
1555 %float_0 = OpConstant %float 0
1556 %ptr_ssbo_float = OpTypePointer StorageBuffer %float
1557 %wg_var = OpVariable %ptr_ssbo_float StorageBuffer
1558 %func_ty = OpTypeFunction %void
1559 %func = OpFunction %void None %func_ty
1560 %1 = OpLabel
1561 %2 = OpExtInst %float %import Modf %float_0 %wg_var
1562 %3 = OpFAdd %float %float_0 %2
1563 OpReturn
1564 OpFunctionEnd
1565 )";
1566 
1567   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1568 }
1569 
TEST_F(UpgradeMemoryModelTest,UpgradeFrexpNoFlags)1570 TEST_F(UpgradeMemoryModelTest, UpgradeFrexpNoFlags) {
1571   const std::string text = R"(
1572 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1573 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1574 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
1575 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
1576 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1577 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
1578 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
1579 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1580 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
1581 ; CHECK: OpStore [[var]] [[ex1]]
1582 ; CHECK-NOT: NonPrivatePointer
1583 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1584 OpCapability Shader
1585 OpMemoryModel Logical GLSL450
1586 %import = OpExtInstImport "GLSL.std.450"
1587 OpEntryPoint GLCompute %func "func"
1588 %void = OpTypeVoid
1589 %float = OpTypeFloat 32
1590 %float_0 = OpConstant %float 0
1591 %int = OpTypeInt 32 0
1592 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1593 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
1594 %func_ty = OpTypeFunction %void
1595 %func = OpFunction %void None %func_ty
1596 %1 = OpLabel
1597 %2 = OpExtInst %float %import Frexp %float_0 %ssbo_var
1598 %3 = OpFAdd %float %float_0 %2
1599 OpReturn
1600 OpFunctionEnd
1601 )";
1602 
1603   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1604 }
1605 
TEST_F(UpgradeMemoryModelTest,UpgradeFrexpWorkgroupCoherent)1606 TEST_F(UpgradeMemoryModelTest, UpgradeFrexpWorkgroupCoherent) {
1607   const std::string text = R"(
1608 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1609 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1610 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
1611 ; CHECK: [[ptr:%\w+]] = OpTypePointer Workgroup [[int]]
1612 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] Workgroup
1613 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
1614 ; CHECK: [[wg_scope:%\w+]] = OpConstant {{%\w+}} 2
1615 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
1616 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1617 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
1618 ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[wg_scope]]
1619 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1620 OpCapability Shader
1621 OpMemoryModel Logical GLSL450
1622 %import = OpExtInstImport "GLSL.std.450"
1623 OpEntryPoint GLCompute %func "func"
1624 OpDecorate %wg_var Coherent
1625 %void = OpTypeVoid
1626 %float = OpTypeFloat 32
1627 %float_0 = OpConstant %float 0
1628 %int = OpTypeInt 32 0
1629 %ptr_wg_int = OpTypePointer Workgroup %int
1630 %wg_var = OpVariable %ptr_wg_int Workgroup
1631 %func_ty = OpTypeFunction %void
1632 %func = OpFunction %void None %func_ty
1633 %1 = OpLabel
1634 %2 = OpExtInst %float %import Frexp %float_0 %wg_var
1635 %3 = OpFAdd %float %float_0 %2
1636 OpReturn
1637 OpFunctionEnd
1638 )";
1639 
1640   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1641 }
1642 
TEST_F(UpgradeMemoryModelTest,UpgradeFrexpSSBOCoherent)1643 TEST_F(UpgradeMemoryModelTest, UpgradeFrexpSSBOCoherent) {
1644   const std::string text = R"(
1645 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1646 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1647 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
1648 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
1649 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1650 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
1651 ; CHECK: [[qf_scope:%\w+]] = OpConstant {{%\w+}} 5
1652 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
1653 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1654 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
1655 ; CHECK: OpStore [[var]] [[ex1]] MakePointerAvailable|NonPrivatePointer [[qf_scope]]
1656 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1657 OpCapability Shader
1658 OpMemoryModel Logical GLSL450
1659 %import = OpExtInstImport "GLSL.std.450"
1660 OpEntryPoint GLCompute %func "func"
1661 OpDecorate %ssbo_var Coherent
1662 %void = OpTypeVoid
1663 %float = OpTypeFloat 32
1664 %float_0 = OpConstant %float 0
1665 %int = OpTypeInt 32 0
1666 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1667 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
1668 %func_ty = OpTypeFunction %void
1669 %func = OpFunction %void None %func_ty
1670 %1 = OpLabel
1671 %2 = OpExtInst %float %import Frexp %float_0 %ssbo_var
1672 %3 = OpFAdd %float %float_0 %2
1673 OpReturn
1674 OpFunctionEnd
1675 )";
1676 
1677   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1678 }
1679 
TEST_F(UpgradeMemoryModelTest,UpgradeFrexpSSBOVolatile)1680 TEST_F(UpgradeMemoryModelTest, UpgradeFrexpSSBOVolatile) {
1681   const std::string text = R"(
1682 ; CHECK: [[float:%\w+]] = OpTypeFloat 32
1683 ; CHECK: [[float_0:%\w+]] = OpConstant [[float]] 0
1684 ; CHECK: [[int:%\w+]] = OpTypeInt 32 0
1685 ; CHECK: [[ptr:%\w+]] = OpTypePointer StorageBuffer [[int]]
1686 ; CHECK: [[var:%\w+]] = OpVariable [[ptr]] StorageBuffer
1687 ; CHECK: [[struct:%\w+]] = OpTypeStruct [[float]] [[int]]
1688 ; CHECK: [[modfstruct:%\w+]] = OpExtInst [[struct]] {{%\w+}} FrexpStruct [[float_0]]
1689 ; CHECK: [[ex0:%\w+]] = OpCompositeExtract [[float]] [[modfstruct]] 0
1690 ; CHECK: [[ex1:%\w+]] = OpCompositeExtract [[int]] [[modfstruct]] 1
1691 ; CHECK: OpStore [[var]] [[ex1]] Volatile
1692 ; CHECK: OpFAdd [[float]] [[float_0]] [[ex0]]
1693 OpCapability Shader
1694 OpMemoryModel Logical GLSL450
1695 %import = OpExtInstImport "GLSL.std.450"
1696 OpEntryPoint GLCompute %func "func"
1697 OpDecorate %wg_var Volatile
1698 %void = OpTypeVoid
1699 %float = OpTypeFloat 32
1700 %float_0 = OpConstant %float 0
1701 %int = OpTypeInt 32 0
1702 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1703 %wg_var = OpVariable %ptr_ssbo_int StorageBuffer
1704 %func_ty = OpTypeFunction %void
1705 %func = OpFunction %void None %func_ty
1706 %1 = OpLabel
1707 %2 = OpExtInst %float %import Frexp %float_0 %wg_var
1708 %3 = OpFAdd %float %float_0 %2
1709 OpReturn
1710 OpFunctionEnd
1711 )";
1712 
1713   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1714 }
1715 
TEST_F(UpgradeMemoryModelTest,SPV14NormalizeCopyMemoryAddOperands)1716 TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryAddOperands) {
1717   const std::string text = R"(
1718 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None None
1719 OpCapability Shader
1720 OpMemoryModel Logical GLSL450
1721 OpEntryPoint GLCompute %func "func" %src %dst
1722 %void = OpTypeVoid
1723 %int = OpTypeInt 32 0
1724 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1725 %src = OpVariable %ptr_ssbo_int StorageBuffer
1726 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1727 %void_fn = OpTypeFunction %void
1728 %func = OpFunction %void None %void_fn
1729 %entry = OpLabel
1730 OpCopyMemory %dst %src
1731 OpReturn
1732 OpFunctionEnd
1733 )";
1734 
1735   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1736   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1737 }
1738 
TEST_F(UpgradeMemoryModelTest,SPV14NormalizeCopyMemoryDuplicateOperand)1739 TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryDuplicateOperand) {
1740   const std::string text = R"(
1741 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Nontemporal Nontemporal
1742 OpCapability Shader
1743 OpMemoryModel Logical GLSL450
1744 OpEntryPoint GLCompute %func "func" %src %dst
1745 %void = OpTypeVoid
1746 %int = OpTypeInt 32 0
1747 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1748 %src = OpVariable %ptr_ssbo_int StorageBuffer
1749 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1750 %void_fn = OpTypeFunction %void
1751 %func = OpFunction %void None %void_fn
1752 %entry = OpLabel
1753 OpCopyMemory %dst %src Nontemporal
1754 OpReturn
1755 OpFunctionEnd
1756 )";
1757 
1758   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1759   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1760 }
1761 
TEST_F(UpgradeMemoryModelTest,SPV14NormalizeCopyMemoryDuplicateOperands)1762 TEST_F(UpgradeMemoryModelTest, SPV14NormalizeCopyMemoryDuplicateOperands) {
1763   const std::string text = R"(
1764 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned 4
1765 OpCapability Shader
1766 OpMemoryModel Logical GLSL450
1767 OpEntryPoint GLCompute %func "func" %src %dst
1768 %void = OpTypeVoid
1769 %int = OpTypeInt 32 0
1770 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1771 %src = OpVariable %ptr_ssbo_int StorageBuffer
1772 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1773 %void_fn = OpTypeFunction %void
1774 %func = OpFunction %void None %void_fn
1775 %entry = OpLabel
1776 OpCopyMemory %dst %src Aligned 4
1777 OpReturn
1778 OpFunctionEnd
1779 )";
1780 
1781   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1782   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1783 }
1784 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryDstCoherent)1785 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherent) {
1786   const std::string text = R"(
1787 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1788 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
1789 OpCapability Shader
1790 OpMemoryModel Logical GLSL450
1791 OpEntryPoint GLCompute %func "func" %src %dst
1792 OpDecorate %dst Coherent
1793 %void = OpTypeVoid
1794 %int = OpTypeInt 32 0
1795 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1796 %src = OpVariable %ptr_ssbo_int StorageBuffer
1797 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1798 %void_fn = OpTypeFunction %void
1799 %func = OpFunction %void None %void_fn
1800 %entry = OpLabel
1801 OpCopyMemory %dst %src
1802 OpReturn
1803 OpFunctionEnd
1804 )";
1805 
1806   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1807   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1808 }
1809 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryDstCoherentPreviousArgs)1810 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentPreviousArgs) {
1811   const std::string text = R"(
1812 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1813 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 4
1814 OpCapability Shader
1815 OpMemoryModel Logical GLSL450
1816 OpEntryPoint GLCompute %func "func" %src %dst
1817 OpDecorate %dst Coherent
1818 %void = OpTypeVoid
1819 %int = OpTypeInt 32 0
1820 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1821 %src = OpVariable %ptr_ssbo_int StorageBuffer
1822 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1823 %void_fn = OpTypeFunction %void
1824 %func = OpFunction %void None %void_fn
1825 %entry = OpLabel
1826 OpCopyMemory %dst %src Aligned 4
1827 OpReturn
1828 OpFunctionEnd
1829 )";
1830 
1831   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1832   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1833 }
1834 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemorySrcCoherent)1835 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherent) {
1836   const std::string text = R"(
1837 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1838 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} None MakePointerVisible|NonPrivatePointer [[scope]]
1839 OpCapability Shader
1840 OpMemoryModel Logical GLSL450
1841 OpEntryPoint GLCompute %func "func" %src %dst
1842 OpDecorate %src Coherent
1843 %void = OpTypeVoid
1844 %int = OpTypeInt 32 0
1845 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1846 %src = OpVariable %ptr_ssbo_int StorageBuffer
1847 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1848 %void_fn = OpTypeFunction %void
1849 %func = OpFunction %void None %void_fn
1850 %entry = OpLabel
1851 OpCopyMemory %dst %src
1852 OpReturn
1853 OpFunctionEnd
1854 )";
1855 
1856   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1857   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1858 }
1859 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemorySrcCoherentPreviousArgs)1860 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemorySrcCoherentPreviousArgs) {
1861   const std::string text = R"(
1862 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1863 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned 4 Aligned|MakePointerVisible|NonPrivatePointer 4 [[scope]]
1864 OpCapability Shader
1865 OpMemoryModel Logical GLSL450
1866 OpEntryPoint GLCompute %func "func" %src %dst
1867 OpDecorate %src Coherent
1868 %void = OpTypeVoid
1869 %int = OpTypeInt 32 0
1870 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1871 %src = OpVariable %ptr_ssbo_int StorageBuffer
1872 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1873 %void_fn = OpTypeFunction %void
1874 %func = OpFunction %void None %void_fn
1875 %entry = OpLabel
1876 OpCopyMemory %dst %src Aligned 4
1877 OpReturn
1878 OpFunctionEnd
1879 )";
1880 
1881   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1882   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1883 }
1884 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryBothCoherent)1885 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherent) {
1886   const std::string text = R"(
1887 ; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
1888 ; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
1889 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[wg]] MakePointerVisible|NonPrivatePointer [[queue]]
1890 OpCapability Shader
1891 OpMemoryModel Logical GLSL450
1892 OpEntryPoint GLCompute %func "func" %src %dst
1893 OpDecorate %src Coherent
1894 %void = OpTypeVoid
1895 %int = OpTypeInt 32 0
1896 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1897 %ptr_wg_int = OpTypePointer Workgroup %int
1898 %src = OpVariable %ptr_ssbo_int StorageBuffer
1899 %dst = OpVariable %ptr_wg_int Workgroup
1900 %void_fn = OpTypeFunction %void
1901 %func = OpFunction %void None %void_fn
1902 %entry = OpLabel
1903 OpCopyMemory %dst %src
1904 OpReturn
1905 OpFunctionEnd
1906 )";
1907 
1908   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1909   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1910 }
1911 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryBothCoherentPreviousArgs)1912 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothCoherentPreviousArgs) {
1913   const std::string text = R"(
1914 ; CHECK-DAG: [[queue:%\w+]] = OpConstant {{%\w+}} 5
1915 ; CHECK-DAG: [[wg:%\w+]] = OpConstant {{%\w+}} 2
1916 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[queue]] Aligned|MakePointerVisible|NonPrivatePointer 4 [[wg]]
1917 OpCapability Shader
1918 OpMemoryModel Logical GLSL450
1919 OpEntryPoint GLCompute %func "func" %src %dst
1920 OpDecorate %dst Coherent
1921 %void = OpTypeVoid
1922 %int = OpTypeInt 32 0
1923 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1924 %ptr_wg_int = OpTypePointer Workgroup %int
1925 %src = OpVariable %ptr_wg_int Workgroup
1926 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1927 %void_fn = OpTypeFunction %void
1928 %func = OpFunction %void None %void_fn
1929 %entry = OpLabel
1930 OpCopyMemory %dst %src Aligned 4
1931 OpReturn
1932 OpFunctionEnd
1933 )";
1934 
1935   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1936   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1937 }
1938 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryBothVolatile)1939 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothVolatile) {
1940   const std::string text = R"(
1941 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile Volatile
1942 OpCapability Shader
1943 OpMemoryModel Logical GLSL450
1944 OpEntryPoint GLCompute %func "func" %src %dst
1945 OpDecorate %src Volatile
1946 OpDecorate %dst Volatile
1947 %void = OpTypeVoid
1948 %int = OpTypeInt 32 0
1949 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1950 %src = OpVariable %ptr_ssbo_int StorageBuffer
1951 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1952 %void_fn = OpTypeFunction %void
1953 %func = OpFunction %void None %void_fn
1954 %entry = OpLabel
1955 OpCopyMemory %dst %src
1956 OpReturn
1957 OpFunctionEnd
1958 )";
1959 
1960   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1961   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1962 }
1963 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryBothVolatilePreviousArgs)1964 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryBothVolatilePreviousArgs) {
1965   const std::string text = R"(
1966 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Volatile|Aligned 4 Volatile|Aligned 4
1967 OpCapability Shader
1968 OpMemoryModel Logical GLSL450
1969 OpEntryPoint GLCompute %func "func" %src %dst
1970 OpDecorate %src Volatile
1971 OpDecorate %dst Volatile
1972 %void = OpTypeVoid
1973 %int = OpTypeInt 32 0
1974 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
1975 %src = OpVariable %ptr_ssbo_int StorageBuffer
1976 %dst = OpVariable %ptr_ssbo_int StorageBuffer
1977 %void_fn = OpTypeFunction %void
1978 %func = OpFunction %void None %void_fn
1979 %entry = OpLabel
1980 OpCopyMemory %dst %src Aligned 4
1981 OpReturn
1982 OpFunctionEnd
1983 )";
1984 
1985   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
1986   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
1987 }
1988 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryDstCoherentTwoOperands)1989 TEST_F(UpgradeMemoryModelTest, SPV14CopyMemoryDstCoherentTwoOperands) {
1990   const std::string text = R"(
1991 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
1992 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} MakePointerAvailable|NonPrivatePointer [[scope]] None
1993 OpCapability Shader
1994 OpMemoryModel Logical GLSL450
1995 OpEntryPoint GLCompute %func "func" %src %dst
1996 OpDecorate %dst Coherent
1997 %void = OpTypeVoid
1998 %int = OpTypeInt 32 0
1999 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2000 %src = OpVariable %ptr_ssbo_int StorageBuffer
2001 %dst = OpVariable %ptr_ssbo_int StorageBuffer
2002 %void_fn = OpTypeFunction %void
2003 %func = OpFunction %void None %void_fn
2004 %entry = OpLabel
2005 OpCopyMemory %dst %src None None
2006 OpReturn
2007 OpFunctionEnd
2008 )";
2009 
2010   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
2011   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2012 }
2013 
TEST_F(UpgradeMemoryModelTest,SPV14CopyMemoryDstCoherentPreviousArgsTwoOperands)2014 TEST_F(UpgradeMemoryModelTest,
2015        SPV14CopyMemoryDstCoherentPreviousArgsTwoOperands) {
2016   const std::string text = R"(
2017 ; CHECK: [[scope:%\w+]] = OpConstant {{%\w+}} 5
2018 ; CHECK: OpCopyMemory {{%\w+}} {{%\w+}} Aligned|MakePointerAvailable|NonPrivatePointer 4 [[scope]] Aligned 8
2019 OpCapability Shader
2020 OpMemoryModel Logical GLSL450
2021 OpEntryPoint GLCompute %func "func" %src %dst
2022 OpDecorate %dst Coherent
2023 %void = OpTypeVoid
2024 %int = OpTypeInt 32 0
2025 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2026 %src = OpVariable %ptr_ssbo_int StorageBuffer
2027 %dst = OpVariable %ptr_ssbo_int StorageBuffer
2028 %void_fn = OpTypeFunction %void
2029 %func = OpFunction %void None %void_fn
2030 %entry = OpLabel
2031 OpCopyMemory %dst %src Aligned 4 Aligned 8
2032 OpReturn
2033 OpFunctionEnd
2034 )";
2035 
2036   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
2037   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2038 }
2039 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicLoad)2040 TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoad) {
2041   const std::string text = R"(
2042 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2043 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
2044 ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
2045 OpCapability Shader
2046 OpCapability Linkage
2047 OpMemoryModel Logical GLSL450
2048 OpDecorate %ssbo_var Volatile
2049 %void = OpTypeVoid
2050 %int = OpTypeInt 32 0
2051 %device = OpConstant %int 1
2052 %relaxed = OpConstant %int 0
2053 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2054 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2055 %void_fn = OpTypeFunction %void
2056 %func = OpFunction %void None %void_fn
2057 %entry = OpLabel
2058 %ld = OpAtomicLoad %int %ssbo_var %device %relaxed
2059 OpReturn
2060 OpFunctionEnd
2061 )";
2062 
2063   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2064 }
2065 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicLoadPreviousFlags)2066 TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoadPreviousFlags) {
2067   const std::string text = R"(
2068 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2069 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32834
2070 ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
2071 OpCapability Shader
2072 OpCapability Linkage
2073 OpMemoryModel Logical GLSL450
2074 OpDecorate %ssbo_var Volatile
2075 %void = OpTypeVoid
2076 %int = OpTypeInt 32 0
2077 %device = OpConstant %int 1
2078 %acquire_ssbo = OpConstant %int 66
2079 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2080 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2081 %void_fn = OpTypeFunction %void
2082 %func = OpFunction %void None %void_fn
2083 %entry = OpLabel
2084 %ld = OpAtomicLoad %int %ssbo_var %device %acquire_ssbo
2085 OpReturn
2086 OpFunctionEnd
2087 )";
2088 
2089   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2090 }
2091 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicStore)2092 TEST_F(UpgradeMemoryModelTest, VolatileAtomicStore) {
2093   const std::string text = R"(
2094 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2095 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 32768
2096 ; CHECK: OpAtomicStore {{.*}} {{.*}} [[volatile]]
2097 OpCapability Shader
2098 OpCapability Linkage
2099 OpMemoryModel Logical GLSL450
2100 OpDecorate %ssbo_var Volatile
2101 %void = OpTypeVoid
2102 %int = OpTypeInt 32 0
2103 %int_0 = OpConstant %int 0
2104 %device = OpConstant %int 1
2105 %relaxed = OpConstant %int 0
2106 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2107 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2108 %void_fn = OpTypeFunction %void
2109 %func = OpFunction %void None %void_fn
2110 %entry = OpLabel
2111 OpAtomicStore %ssbo_var %device %relaxed %int_0
2112 OpReturn
2113 OpFunctionEnd
2114 )";
2115 
2116   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2117 }
2118 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicStorePreviousFlags)2119 TEST_F(UpgradeMemoryModelTest, VolatileAtomicStorePreviousFlags) {
2120   const std::string text = R"(
2121 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2122 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 32836
2123 ; CHECK: OpAtomicStore {{.*}} {{.*}} [[volatile]]
2124 OpCapability Shader
2125 OpCapability Linkage
2126 OpMemoryModel Logical GLSL450
2127 OpDecorate %ssbo_var Volatile
2128 %void = OpTypeVoid
2129 %int = OpTypeInt 32 0
2130 %int_0 = OpConstant %int 0
2131 %device = OpConstant %int 1
2132 %release_ssbo = OpConstant %int 68
2133 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2134 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2135 %void_fn = OpTypeFunction %void
2136 %func = OpFunction %void None %void_fn
2137 %entry = OpLabel
2138 OpAtomicStore %ssbo_var %device %release_ssbo %int_0
2139 OpReturn
2140 OpFunctionEnd
2141 )";
2142 
2143   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2144 }
2145 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicCompareExchange)2146 TEST_F(UpgradeMemoryModelTest, VolatileAtomicCompareExchange) {
2147   const std::string text = R"(
2148 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2149 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
2150 ; CHECK: OpAtomicCompareExchange [[int]] {{.*}} {{.*}} [[volatile]] [[volatile]]
2151 OpCapability Shader
2152 OpCapability Linkage
2153 OpMemoryModel Logical GLSL450
2154 OpDecorate %ssbo_var Volatile
2155 %void = OpTypeVoid
2156 %int = OpTypeInt 32 0
2157 %int_0 = OpConstant %int 0
2158 %int_1 = OpConstant %int 1
2159 %device = OpConstant %int 1
2160 %relaxed = OpConstant %int 0
2161 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2162 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2163 %void_fn = OpTypeFunction %void
2164 %func = OpFunction %void None %void_fn
2165 %entry = OpLabel
2166 %ld = OpAtomicCompareExchange %int %ssbo_var %device %relaxed %relaxed %int_0 %int_1
2167 OpReturn
2168 OpFunctionEnd
2169 )";
2170 
2171   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2172 }
2173 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicCompareExchangePreviousFlags)2174 TEST_F(UpgradeMemoryModelTest, VolatileAtomicCompareExchangePreviousFlags) {
2175   const std::string text = R"(
2176 ; CHECK-NOT: OpDecorate {{.*}} Volatile
2177 ; CHECK: [[volatile_acq_rel:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32840
2178 ; CHECK: [[volatile_acq:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32834
2179 ; CHECK: OpAtomicCompareExchange [[int]] {{.*}} {{.*}} [[volatile_acq_rel]] [[volatile_acq]]
2180 OpCapability Shader
2181 OpCapability Linkage
2182 OpMemoryModel Logical GLSL450
2183 OpDecorate %ssbo_var Volatile
2184 %void = OpTypeVoid
2185 %int = OpTypeInt 32 0
2186 %int_0 = OpConstant %int 0
2187 %int_1 = OpConstant %int 1
2188 %device = OpConstant %int 1
2189 %acq_ssbo = OpConstant %int 66
2190 %acq_rel_ssbo = OpConstant %int 72
2191 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2192 %ssbo_var = OpVariable %ptr_ssbo_int StorageBuffer
2193 %void_fn = OpTypeFunction %void
2194 %func = OpFunction %void None %void_fn
2195 %entry = OpLabel
2196 %ld = OpAtomicCompareExchange %int %ssbo_var %device %acq_rel_ssbo %acq_ssbo %int_0 %int_1
2197 OpReturn
2198 OpFunctionEnd
2199 )";
2200 
2201   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2202 }
2203 
TEST_F(UpgradeMemoryModelTest,VolatileAtomicLoadMemberDecoration)2204 TEST_F(UpgradeMemoryModelTest, VolatileAtomicLoadMemberDecoration) {
2205   const std::string text = R"(
2206 ; CHECK-NOT: OpMemberDecorate {{.*}} {{.*}} Volatile
2207 ; CHECK: [[relaxed:%[a-zA-Z0-9_]+]] = OpConstant {{.*}} 0
2208 ; CHECK: [[volatile:%[a-zA-Z0-9_]+]] = OpConstant [[int:%[a-zA-Z0-9_]+]] 32768
2209 ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[relaxed]]
2210 ; CHECK: OpAtomicLoad [[int]] {{.*}} {{.*}} [[volatile]]
2211 OpCapability Shader
2212 OpCapability Linkage
2213 OpMemoryModel Logical GLSL450
2214 OpMemberDecorate %struct 1 Volatile
2215 %void = OpTypeVoid
2216 %int = OpTypeInt 32 0
2217 %device = OpConstant %int 1
2218 %relaxed = OpConstant %int 0
2219 %int_0 = OpConstant %int 0
2220 %int_1 = OpConstant %int 1
2221 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2222 %struct = OpTypeStruct %int %int
2223 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
2224 %ssbo_var = OpVariable %ptr_ssbo_struct StorageBuffer
2225 %void_fn = OpTypeFunction %void
2226 %func = OpFunction %void None %void_fn
2227 %entry = OpLabel
2228 %gep0 = OpAccessChain %ptr_ssbo_int %ssbo_var %int_0
2229 %ld0 = OpAtomicLoad %int %gep0 %device %relaxed
2230 %gep1 = OpAccessChain %ptr_ssbo_int %ssbo_var %int_1
2231 %ld1 = OpAtomicLoad %int %gep1 %device %relaxed
2232 OpReturn
2233 OpFunctionEnd
2234 )";
2235 
2236   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2237 }
2238 
TEST_F(UpgradeMemoryModelTest,CoherentStructMemberInArray)2239 TEST_F(UpgradeMemoryModelTest, CoherentStructMemberInArray) {
2240   const std::string text = R"(
2241 ; CHECK-NOT: OpMemberDecorate
2242 ; CHECK: [[int:%[a-zA-Z0-9_]+]] = OpTypeInt 32 0
2243 ; CHECK: [[device:%[a-zA-Z0-9_]+]] = OpConstant [[int]] 1
2244 ; CHECK: OpLoad [[int]] {{.*}} MakePointerVisible|NonPrivatePointer
2245 OpCapability Shader
2246 OpCapability Linkage
2247 OpMemoryModel Logical GLSL450
2248 OpMemberDecorate %inner 1 Coherent
2249 %void = OpTypeVoid
2250 %int = OpTypeInt 32 0
2251 %int_0 = OpConstant %int 0
2252 %int_1 = OpConstant %int 1
2253 %int_4 = OpConstant %int 4
2254 %inner = OpTypeStruct %int %int
2255 %array = OpTypeArray %inner %int_4
2256 %struct = OpTypeStruct %array
2257 %ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
2258 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
2259 %ssbo_var = OpVariable %ptr_ssbo_struct StorageBuffer
2260 %void_fn = OpTypeFunction %void
2261 %func = OpFunction %void None %void_fn
2262 %entry = OpLabel
2263 %gep = OpAccessChain %ptr_ssbo_int %ssbo_var %int_0 %int_0 %int_1
2264 %ld = OpLoad %int %gep
2265 OpReturn
2266 OpFunctionEnd
2267 )";
2268 
2269   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
2270 }
2271 
2272 }  // namespace
2273