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