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