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