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