1fd4e5da5Sopenharmony_ci// Copyright (c) 2019-2022 Valve Corporation 2fd4e5da5Sopenharmony_ci// Copyright (c) 2019-2022 LunarG Inc. 3fd4e5da5Sopenharmony_ci// 4fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 5fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 6fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 7fd4e5da5Sopenharmony_ci// 8fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 9fd4e5da5Sopenharmony_ci// 10fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 11fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 12fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 14fd4e5da5Sopenharmony_ci// limitations under the License. 15fd4e5da5Sopenharmony_ci 16fd4e5da5Sopenharmony_ci// Bindless Check Instrumentation Tests. 17fd4e5da5Sopenharmony_ci// Tests ending with V2 use version 2 record format. 18fd4e5da5Sopenharmony_ci 19fd4e5da5Sopenharmony_ci#include <string> 20fd4e5da5Sopenharmony_ci#include <vector> 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 23fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_cinamespace spvtools { 26fd4e5da5Sopenharmony_cinamespace opt { 27fd4e5da5Sopenharmony_cinamespace { 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_cistatic const std::string kFuncName = "inst_buff_addr_search_and_test"; 30fd4e5da5Sopenharmony_cistatic const std::string kImportDeco = R"( 31fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" + 32fd4e5da5Sopenharmony_ci kFuncName + R"(" Import 33fd4e5da5Sopenharmony_ci)"; 34fd4e5da5Sopenharmony_cistatic const std::string kImportStub = R"( 35fd4e5da5Sopenharmony_ci;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}} 36fd4e5da5Sopenharmony_ci;CHECK: OpFunctionEnd 37fd4e5da5Sopenharmony_ci)"; 38fd4e5da5Sopenharmony_ci// clang-format on 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ciusing InstBuffAddrTest = PassTest<::testing::Test>; 41fd4e5da5Sopenharmony_ci 42fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, InstPhysicalStorageBufferStore) { 43fd4e5da5Sopenharmony_ci // #version 450 44fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 45fd4e5da5Sopenharmony_ci // 46fd4e5da5Sopenharmony_ci // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; 47fd4e5da5Sopenharmony_ci // 48fd4e5da5Sopenharmony_ci // layout(set = 0, binding = 0) uniform ufoo { 49fd4e5da5Sopenharmony_ci // bufStruct data; 50fd4e5da5Sopenharmony_ci // uint offset; 51fd4e5da5Sopenharmony_ci // } u_info; 52fd4e5da5Sopenharmony_ci // 53fd4e5da5Sopenharmony_ci // layout(buffer_reference, std140) buffer bufStruct { 54fd4e5da5Sopenharmony_ci // layout(offset = 0) int a[2]; 55fd4e5da5Sopenharmony_ci // layout(offset = 32) int b; 56fd4e5da5Sopenharmony_ci // }; 57fd4e5da5Sopenharmony_ci // 58fd4e5da5Sopenharmony_ci // void main() { 59fd4e5da5Sopenharmony_ci // u_info.data.b = 0xca7; 60fd4e5da5Sopenharmony_ci // } 61fd4e5da5Sopenharmony_ci 62fd4e5da5Sopenharmony_ci const std::string defs = R"( 63fd4e5da5Sopenharmony_ciOpCapability Shader 64fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 65fd4e5da5Sopenharmony_ci;CHECK: OpCapability Int64 66fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer" 67fd4e5da5Sopenharmony_ci;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" 68fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 69fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 70fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 71fd4e5da5Sopenharmony_ci;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID 72fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 73fd4e5da5Sopenharmony_ciOpSource GLSL 450 74fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 75fd4e5da5Sopenharmony_ciOpName %main "main" 76fd4e5da5Sopenharmony_ciOpName %ufoo "ufoo" 77fd4e5da5Sopenharmony_ciOpMemberName %ufoo 0 "data" 78fd4e5da5Sopenharmony_ciOpMemberName %ufoo 1 "offset" 79fd4e5da5Sopenharmony_ciOpName %bufStruct "bufStruct" 80fd4e5da5Sopenharmony_ciOpMemberName %bufStruct 0 "a" 81fd4e5da5Sopenharmony_ciOpMemberName %bufStruct 1 "b" 82fd4e5da5Sopenharmony_ciOpName %u_info "u_info" 83fd4e5da5Sopenharmony_ci)"; 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ci // clang-format off 86fd4e5da5Sopenharmony_ci const std::string decorates = R"( 87fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 0 Offset 0 88fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 1 Offset 8 89fd4e5da5Sopenharmony_ciOpDecorate %ufoo Block 90fd4e5da5Sopenharmony_ciOpDecorate %_arr_int_uint_2 ArrayStride 16 91fd4e5da5Sopenharmony_ciOpMemberDecorate %bufStruct 0 Offset 0 92fd4e5da5Sopenharmony_ciOpMemberDecorate %bufStruct 1 Offset 32 93fd4e5da5Sopenharmony_ciOpDecorate %bufStruct Block 94fd4e5da5Sopenharmony_ciOpDecorate %u_info DescriptorSet 0 95fd4e5da5Sopenharmony_ciOpDecorate %u_info Binding 0 96fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 97fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId 98fd4e5da5Sopenharmony_ci)"; 99fd4e5da5Sopenharmony_ci 100fd4e5da5Sopenharmony_ci const std::string globals = R"( 101fd4e5da5Sopenharmony_ci%void = OpTypeVoid 102fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 103fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer 104fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 105fd4e5da5Sopenharmony_ci%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint 106fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 107fd4e5da5Sopenharmony_ci%uint_2 = OpConstant %uint 2 108fd4e5da5Sopenharmony_ci%_arr_int_uint_2 = OpTypeArray %int %uint_2 109fd4e5da5Sopenharmony_ci%bufStruct = OpTypeStruct %_arr_int_uint_2 %int 110fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct 111fd4e5da5Sopenharmony_ci%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo 112fd4e5da5Sopenharmony_ci%u_info = OpVariable %_ptr_Uniform_ufoo Uniform 113fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 114fd4e5da5Sopenharmony_ci%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct 115fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 116fd4e5da5Sopenharmony_ci%int_3239 = OpConstant %int 3239 117fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int 118fd4e5da5Sopenharmony_ci;CHECK: %ulong = OpTypeInt 64 0 119fd4e5da5Sopenharmony_ci;CHECK: %bool = OpTypeBool 120fd4e5da5Sopenharmony_ci;CHECK: %v3uint = OpTypeVector %uint 3 121fd4e5da5Sopenharmony_ci;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint 122fd4e5da5Sopenharmony_ci;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input 123fd4e5da5Sopenharmony_ci)"; 124fd4e5da5Sopenharmony_ci// clang-format off 125fd4e5da5Sopenharmony_ci 126fd4e5da5Sopenharmony_ci const std::string main_func = R"( 127fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 128fd4e5da5Sopenharmony_ci%5 = OpLabel 129fd4e5da5Sopenharmony_ci%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 130fd4e5da5Sopenharmony_ci%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 131fd4e5da5Sopenharmony_ci%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 132fd4e5da5Sopenharmony_ci;CHECK-NOT: %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 133fd4e5da5Sopenharmony_ci;CHECK-NOT: %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17 134fd4e5da5Sopenharmony_ci;CHECK-NOT: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1 135fd4e5da5Sopenharmony_ci;CHECK: %20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 136fd4e5da5Sopenharmony_ci;CHECK: %21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20 137fd4e5da5Sopenharmony_ci;CHECK: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1 138fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %22 139fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 140fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 141fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 142fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 143fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 144fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} {{%\w+}} %uint_4 145fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 146fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 147fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 148fd4e5da5Sopenharmony_ciOpStore %22 %int_3239 Aligned 16 149fd4e5da5Sopenharmony_ci;CHECK: OpStore %22 %int_3239 Aligned 16 150fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 151fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 152fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 153fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 154fd4e5da5Sopenharmony_ciOpReturn 155fd4e5da5Sopenharmony_ciOpFunctionEnd 156fd4e5da5Sopenharmony_ci)"; 157fd4e5da5Sopenharmony_ci 158fd4e5da5Sopenharmony_ci // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 159fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>( 160fd4e5da5Sopenharmony_ci defs + decorates + globals + kImportStub + main_func, true, 23u); 161fd4e5da5Sopenharmony_ci} 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) { 164fd4e5da5Sopenharmony_ci // #version 450 165fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci // // forward reference 168fd4e5da5Sopenharmony_ci // layout(buffer_reference) buffer blockType; 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ci // layout(buffer_reference, std430, buffer_reference_align = 16) buffer 171fd4e5da5Sopenharmony_ci // blockType { 172fd4e5da5Sopenharmony_ci // int x; 173fd4e5da5Sopenharmony_ci // blockType next; 174fd4e5da5Sopenharmony_ci // }; 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ci // layout(std430) buffer rootBlock { 177fd4e5da5Sopenharmony_ci // blockType root; 178fd4e5da5Sopenharmony_ci // } r; 179fd4e5da5Sopenharmony_ci 180fd4e5da5Sopenharmony_ci // void main() 181fd4e5da5Sopenharmony_ci // { 182fd4e5da5Sopenharmony_ci // blockType b = r.root; 183fd4e5da5Sopenharmony_ci // b = b.next; 184fd4e5da5Sopenharmony_ci // b.x = 531; 185fd4e5da5Sopenharmony_ci // } 186fd4e5da5Sopenharmony_ci 187fd4e5da5Sopenharmony_ci const std::string defs = R"( 188fd4e5da5Sopenharmony_ciOpCapability Shader 189fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 190fd4e5da5Sopenharmony_ci;CHECK: OpCapability Int64 191fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer" 192fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class" 193fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 194fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 195fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 196fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 197fd4e5da5Sopenharmony_ciOpSource GLSL 450 198fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 199fd4e5da5Sopenharmony_ciOpName %main "main" 200fd4e5da5Sopenharmony_ci;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID 201fd4e5da5Sopenharmony_ciOpName %blockType "blockType" 202fd4e5da5Sopenharmony_ciOpMemberName %blockType 0 "x" 203fd4e5da5Sopenharmony_ciOpMemberName %blockType 1 "next" 204fd4e5da5Sopenharmony_ciOpName %rootBlock "rootBlock" 205fd4e5da5Sopenharmony_ciOpMemberName %rootBlock 0 "root" 206fd4e5da5Sopenharmony_ciOpName %r "r" 207fd4e5da5Sopenharmony_ci)"; 208fd4e5da5Sopenharmony_ci 209fd4e5da5Sopenharmony_ci// clang-format off 210fd4e5da5Sopenharmony_ci const std::string decorates = R"( 211fd4e5da5Sopenharmony_ciOpMemberDecorate %blockType 0 Offset 0 212fd4e5da5Sopenharmony_ciOpMemberDecorate %blockType 1 Offset 8 213fd4e5da5Sopenharmony_ciOpDecorate %blockType Block 214fd4e5da5Sopenharmony_ciOpMemberDecorate %rootBlock 0 Offset 0 215fd4e5da5Sopenharmony_ciOpDecorate %rootBlock Block 216fd4e5da5Sopenharmony_ciOpDecorate %r DescriptorSet 0 217fd4e5da5Sopenharmony_ciOpDecorate %r Binding 0 218fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 219fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId 220fd4e5da5Sopenharmony_ci)"; 221fd4e5da5Sopenharmony_ci 222fd4e5da5Sopenharmony_ci const std::string globals = R"( 223fd4e5da5Sopenharmony_ci%void = OpTypeVoid 224fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 225fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer 226fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 227fd4e5da5Sopenharmony_ci%blockType = OpTypeStruct %int %_ptr_PhysicalStorageBuffer_blockType 228fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %blockType 229fd4e5da5Sopenharmony_ci%rootBlock = OpTypeStruct %_ptr_PhysicalStorageBuffer_blockType 230fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer_rootBlock = OpTypePointer StorageBuffer %rootBlock 231fd4e5da5Sopenharmony_ci%r = OpVariable %_ptr_StorageBuffer_rootBlock StorageBuffer 232fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 233fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer StorageBuffer %_ptr_PhysicalStorageBuffer_blockType 234fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 235fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType 236fd4e5da5Sopenharmony_ci%int_531 = OpConstant %int 531 237fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int 238fd4e5da5Sopenharmony_ci)"; 239fd4e5da5Sopenharmony_ci 240fd4e5da5Sopenharmony_ci const std::string main_func = R"( 241fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 242fd4e5da5Sopenharmony_ci%5 = OpLabel 243fd4e5da5Sopenharmony_ci%16 = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_blockType %r %int_0 244fd4e5da5Sopenharmony_ci%17 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %16 245fd4e5da5Sopenharmony_ci%21 = OpAccessChain %_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType %17 %int_1 246fd4e5da5Sopenharmony_ci%22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 247fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0 248fd4e5da5Sopenharmony_ciOpStore %26 %int_531 Aligned 16 249fd4e5da5Sopenharmony_ci;CHECK-NOT: %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 250fd4e5da5Sopenharmony_ci;CHECK-NOT: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0 251fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %21 252fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 253fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 254fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 255fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 256fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 257fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_45 {{%\w+}} {{%\w+}} %uint_8 258fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 259fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 260fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 261fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8 262fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 263fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 264fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_blockType %52 265fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 266fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 267fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpPhi %_ptr_PhysicalStorageBuffer_blockType {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 268fd4e5da5Sopenharmony_ci;CHECK: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int {{%\w+}} %int_0 269fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %26 270fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID 271fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 272fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 273fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2 274fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} 275fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} {{%\w+}} %uint_4 276fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 277fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 278fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 279fd4e5da5Sopenharmony_ci;CHECK: OpStore %26 %int_531 Aligned 16 280fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 281fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 282fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 283fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 284fd4e5da5Sopenharmony_ciOpReturn 285fd4e5da5Sopenharmony_ciOpFunctionEnd 286fd4e5da5Sopenharmony_ci)"; 287fd4e5da5Sopenharmony_ci // clang-format on 288fd4e5da5Sopenharmony_ci 289fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 290fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>( 291fd4e5da5Sopenharmony_ci defs + decorates + globals + kImportStub + main_func, true, 23u); 292fd4e5da5Sopenharmony_ci} 293fd4e5da5Sopenharmony_ci 294fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, StructLoad) { 295fd4e5da5Sopenharmony_ci // #version 450 296fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 297fd4e5da5Sopenharmony_ci // #extension GL_ARB_gpu_shader_int64 : enable 298fd4e5da5Sopenharmony_ci // struct Test { 299fd4e5da5Sopenharmony_ci // float a; 300fd4e5da5Sopenharmony_ci // }; 301fd4e5da5Sopenharmony_ci // 302fd4e5da5Sopenharmony_ci // layout(buffer_reference, std430, buffer_reference_align = 16) buffer 303fd4e5da5Sopenharmony_ci // TestBuffer { Test test; }; 304fd4e5da5Sopenharmony_ci // 305fd4e5da5Sopenharmony_ci // Test GetTest(uint64_t ptr) { 306fd4e5da5Sopenharmony_ci // return TestBuffer(ptr).test; 307fd4e5da5Sopenharmony_ci // } 308fd4e5da5Sopenharmony_ci // 309fd4e5da5Sopenharmony_ci // void main() { 310fd4e5da5Sopenharmony_ci // GetTest(0xe0000000); 311fd4e5da5Sopenharmony_ci // } 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ci const std::string defs = 314fd4e5da5Sopenharmony_ci R"( 315fd4e5da5Sopenharmony_ciOpCapability Shader 316fd4e5da5Sopenharmony_ciOpCapability Int64 317fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 318fd4e5da5Sopenharmony_ci;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class" 319fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 320fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 321fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" 322fd4e5da5Sopenharmony_ci;CHECK: OpEntryPoint Fragment %main "main" %gl_FragCoord 323fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft 324fd4e5da5Sopenharmony_ciOpSource GLSL 450 325fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_gpu_shader_int64" 326fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 327fd4e5da5Sopenharmony_ciOpName %main "main" 328fd4e5da5Sopenharmony_ciOpName %Test "Test" 329fd4e5da5Sopenharmony_ciOpMemberName %Test 0 "a" 330fd4e5da5Sopenharmony_ciOpName %Test_0 "Test" 331fd4e5da5Sopenharmony_ciOpMemberName %Test_0 0 "a" 332fd4e5da5Sopenharmony_ciOpName %TestBuffer "TestBuffer" 333fd4e5da5Sopenharmony_ciOpMemberName %TestBuffer 0 "test" 334fd4e5da5Sopenharmony_ci)"; 335fd4e5da5Sopenharmony_ci 336fd4e5da5Sopenharmony_ci // clang-format off 337fd4e5da5Sopenharmony_ci const std::string decorates = R"( 338fd4e5da5Sopenharmony_ciOpMemberDecorate %Test_0 0 Offset 0 339fd4e5da5Sopenharmony_ciOpMemberDecorate %TestBuffer 0 Offset 0 340fd4e5da5Sopenharmony_ciOpDecorate %TestBuffer Block 341fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 342fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord 343fd4e5da5Sopenharmony_ci)"; 344fd4e5da5Sopenharmony_ci 345fd4e5da5Sopenharmony_ci const std::string globals = R"( 346fd4e5da5Sopenharmony_ci%void = OpTypeVoid 347fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 348fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 349fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 350fd4e5da5Sopenharmony_ci%Test = OpTypeStruct %float 351fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffer 352fd4e5da5Sopenharmony_ci%Test_0 = OpTypeStruct %float 353fd4e5da5Sopenharmony_ci%TestBuffer = OpTypeStruct %Test_0 354fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_TestBuffer = OpTypePointer PhysicalStorageBuffer %TestBuffer 355fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 356fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 357fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0 358fd4e5da5Sopenharmony_ci%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704 359fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConstantNull %Test_0 360fd4e5da5Sopenharmony_ci)"; 361fd4e5da5Sopenharmony_ci 362fd4e5da5Sopenharmony_ci const std::string main_func = R"( 363fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 364fd4e5da5Sopenharmony_ci%5 = OpLabel 365fd4e5da5Sopenharmony_ci%37 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %ulong_18446744073172680704 366fd4e5da5Sopenharmony_ci%38 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %37 %int_0 367fd4e5da5Sopenharmony_ci%39 = OpLoad %Test_0 %38 Aligned 16 368fd4e5da5Sopenharmony_ci;CHECK-NOT: %39 = OpLoad %Test_0 %38 Aligned 16 369fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %38 370fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord 371fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}} 372fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0 373fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1 374fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0 375fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_38 {{%\w+}} {{%\w+}} %uint_4 376fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 377fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 378fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 379fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %Test_0 %38 Aligned 16 380fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 381fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 382fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 383fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 384fd4e5da5Sopenharmony_ci;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 385fd4e5da5Sopenharmony_ci%40 = OpCopyLogical %Test %39 386fd4e5da5Sopenharmony_ci;CHECK-NOT: %40 = OpCopyLogical %Test %39 387fd4e5da5Sopenharmony_ci;CHECK: %40 = OpCopyLogical %Test [[phi_result]] 388fd4e5da5Sopenharmony_ciOpReturn 389fd4e5da5Sopenharmony_ciOpFunctionEnd 390fd4e5da5Sopenharmony_ci)"; 391fd4e5da5Sopenharmony_ci // clang-format on 392fd4e5da5Sopenharmony_ci 393fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 394fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 395fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>( 396fd4e5da5Sopenharmony_ci defs + decorates + globals + kImportStub + main_func, true); 397fd4e5da5Sopenharmony_ci} 398fd4e5da5Sopenharmony_ci 399fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, PaddedStructLoad) { 400fd4e5da5Sopenharmony_ci // #version 450 401fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 402fd4e5da5Sopenharmony_ci // #extension GL_ARB_gpu_shader_int64 : enable 403fd4e5da5Sopenharmony_ci // struct Test { 404fd4e5da5Sopenharmony_ci // uvec3 pad_1; // Offset 0 Size 12 405fd4e5da5Sopenharmony_ci // double pad_2; // Offset 16 Size 8 (alignment requirement) 406fd4e5da5Sopenharmony_ci // float a; // Offset 24 Size 4 407fd4e5da5Sopenharmony_ci // }; // Total Size 28 408fd4e5da5Sopenharmony_ci // 409fd4e5da5Sopenharmony_ci // layout(buffer_reference, std430, buffer_reference_align = 16) buffer 410fd4e5da5Sopenharmony_ci // TestBuffer { Test test; }; 411fd4e5da5Sopenharmony_ci // 412fd4e5da5Sopenharmony_ci // Test GetTest(uint64_t ptr) { 413fd4e5da5Sopenharmony_ci // return TestBuffer(ptr).test; 414fd4e5da5Sopenharmony_ci // } 415fd4e5da5Sopenharmony_ci // 416fd4e5da5Sopenharmony_ci // void main() { 417fd4e5da5Sopenharmony_ci // GetTest(0xe0000000); 418fd4e5da5Sopenharmony_ci // } 419fd4e5da5Sopenharmony_ci 420fd4e5da5Sopenharmony_ci const std::string defs = 421fd4e5da5Sopenharmony_ci R"( 422fd4e5da5Sopenharmony_ciOpCapability Shader 423fd4e5da5Sopenharmony_ciOpCapability Float64 424fd4e5da5Sopenharmony_ciOpCapability Int64 425fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 426fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 427fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 428fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 429fd4e5da5Sopenharmony_ciOpSource GLSL 450 430fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_gpu_shader_int64" 431fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 432fd4e5da5Sopenharmony_ciOpName %main "main" 433fd4e5da5Sopenharmony_ciOpName %Test "Test" 434fd4e5da5Sopenharmony_ciOpMemberName %Test 0 "pad_1" 435fd4e5da5Sopenharmony_ciOpMemberName %Test 1 "pad_2" 436fd4e5da5Sopenharmony_ciOpMemberName %Test 2 "a" 437fd4e5da5Sopenharmony_ciOpName %GetTest_u641_ "GetTest(u641;" 438fd4e5da5Sopenharmony_ciOpName %ptr "ptr" 439fd4e5da5Sopenharmony_ciOpName %Test_0 "Test" 440fd4e5da5Sopenharmony_ciOpMemberName %Test_0 0 "pad_1" 441fd4e5da5Sopenharmony_ciOpMemberName %Test_0 1 "pad_2" 442fd4e5da5Sopenharmony_ciOpMemberName %Test_0 2 "a" 443fd4e5da5Sopenharmony_ciOpName %TestBuffer "TestBuffer" 444fd4e5da5Sopenharmony_ciOpMemberName %TestBuffer 0 "test" 445fd4e5da5Sopenharmony_ciOpName %param "param" 446fd4e5da5Sopenharmony_ci)"; 447fd4e5da5Sopenharmony_ci 448fd4e5da5Sopenharmony_ci // clang-format off 449fd4e5da5Sopenharmony_ci const std::string decorates = R"( 450fd4e5da5Sopenharmony_ciOpDecorate %TestBuffer Block 451fd4e5da5Sopenharmony_ciOpMemberDecorate %Test_0 0 Offset 0 452fd4e5da5Sopenharmony_ciOpMemberDecorate %Test_0 1 Offset 16 453fd4e5da5Sopenharmony_ciOpMemberDecorate %Test_0 2 Offset 24 454fd4e5da5Sopenharmony_ciOpMemberDecorate %TestBuffer 0 Offset 0 455fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 456fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex 457fd4e5da5Sopenharmony_ci;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex 458fd4e5da5Sopenharmony_ci)"; 459fd4e5da5Sopenharmony_ci 460fd4e5da5Sopenharmony_ci const std::string globals = R"( 461fd4e5da5Sopenharmony_ci%void = OpTypeVoid 462fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 463fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0 464fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong 465fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 466fd4e5da5Sopenharmony_ci%v3uint = OpTypeVector %uint 3 467fd4e5da5Sopenharmony_ci%double = OpTypeFloat 64 468fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 469fd4e5da5Sopenharmony_ci%Test = OpTypeStruct %v3uint %double %float 470fd4e5da5Sopenharmony_ci%13 = OpTypeFunction %Test %_ptr_Function_ulong 471fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffer 472fd4e5da5Sopenharmony_ci%Test_0 = OpTypeStruct %v3uint %double %float 473fd4e5da5Sopenharmony_ci%TestBuffer = OpTypeStruct %Test_0 474fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_TestBuffer = OpTypePointer PhysicalStorageBuffer %TestBuffer 475fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 476fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 477fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0 478fd4e5da5Sopenharmony_ci%_ptr_Function_Test = OpTypePointer Function %Test 479fd4e5da5Sopenharmony_ci%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704 480fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConstantNull %Test_0 481fd4e5da5Sopenharmony_ci)"; 482fd4e5da5Sopenharmony_ci 483fd4e5da5Sopenharmony_ci const std::string main_func = R"( 484fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 485fd4e5da5Sopenharmony_ci%5 = OpLabel 486fd4e5da5Sopenharmony_ci%param = OpVariable %_ptr_Function_ulong Function 487fd4e5da5Sopenharmony_ciOpStore %param %ulong_18446744073172680704 488fd4e5da5Sopenharmony_ci%35 = OpFunctionCall %Test %GetTest_u641_ %param 489fd4e5da5Sopenharmony_ciOpReturn 490fd4e5da5Sopenharmony_ciOpFunctionEnd 491fd4e5da5Sopenharmony_ci%GetTest_u641_ = OpFunction %Test None %13 492fd4e5da5Sopenharmony_ci%ptr = OpFunctionParameter %_ptr_Function_ulong 493fd4e5da5Sopenharmony_ci%16 = OpLabel 494fd4e5da5Sopenharmony_ci%28 = OpVariable %_ptr_Function_Test Function 495fd4e5da5Sopenharmony_ci%17 = OpLoad %ulong %ptr 496fd4e5da5Sopenharmony_ci%21 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %17 497fd4e5da5Sopenharmony_ci%25 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %21 %int_0 498fd4e5da5Sopenharmony_ci%26 = OpLoad %Test_0 %25 Aligned 16 499fd4e5da5Sopenharmony_ci%29 = OpCopyLogical %Test %26 500fd4e5da5Sopenharmony_ci;CHECK-NOT: %30 = OpLoad %Test %28 501fd4e5da5Sopenharmony_ci;CHECK-NOT: %26 = OpLoad %Test_0 %25 Aligned 16 502fd4e5da5Sopenharmony_ci;CHECK-NOT: %29 = OpCopyLogical %Test %26 503fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %25 504fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 505fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 506fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 507fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_28 508fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 509fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 510fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 511fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %Test_0 %25 Aligned 16 512fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 513fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 514fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 515fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 516fd4e5da5Sopenharmony_ci;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 517fd4e5da5Sopenharmony_ci;CHECK: %29 = OpCopyLogical %Test [[phi_result]] 518fd4e5da5Sopenharmony_ciOpStore %28 %29 519fd4e5da5Sopenharmony_ci%30 = OpLoad %Test %28 520fd4e5da5Sopenharmony_ciOpReturnValue %30 521fd4e5da5Sopenharmony_ciOpFunctionEnd 522fd4e5da5Sopenharmony_ci)"; 523fd4e5da5Sopenharmony_ci // clang-format on 524fd4e5da5Sopenharmony_ci 525fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 526fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 527fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>( 528fd4e5da5Sopenharmony_ci defs + decorates + globals + kImportStub + main_func, true); 529fd4e5da5Sopenharmony_ci} 530fd4e5da5Sopenharmony_ci 531fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, DeviceBufferAddressOOB) { 532fd4e5da5Sopenharmony_ci // #version 450 533fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 534fd4e5da5Sopenharmony_ci // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct; 535fd4e5da5Sopenharmony_ci // layout(set = 0, binding = 0) uniform ufoo { 536fd4e5da5Sopenharmony_ci // bufStruct data; 537fd4e5da5Sopenharmony_ci // int nWrites; 538fd4e5da5Sopenharmony_ci // } u_info; 539fd4e5da5Sopenharmony_ci // layout(buffer_reference, std140) buffer bufStruct { 540fd4e5da5Sopenharmony_ci // int a[4]; 541fd4e5da5Sopenharmony_ci // }; 542fd4e5da5Sopenharmony_ci // void main() { 543fd4e5da5Sopenharmony_ci // for (int i=0; i < u_info.nWrites; ++i) { 544fd4e5da5Sopenharmony_ci // u_info.data.a[i] = 0xdeadca71; 545fd4e5da5Sopenharmony_ci // } 546fd4e5da5Sopenharmony_ci // } 547fd4e5da5Sopenharmony_ci 548fd4e5da5Sopenharmony_ci // clang-format off 549fd4e5da5Sopenharmony_ci const std::string text = R"( 550fd4e5da5Sopenharmony_ciOpCapability Shader 551fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 552fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 553fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 554fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %u_info 555fd4e5da5Sopenharmony_ci;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex 556fd4e5da5Sopenharmony_ciOpSource GLSL 450 557fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 558fd4e5da5Sopenharmony_ciOpName %main "main" 559fd4e5da5Sopenharmony_ciOpName %i "i" 560fd4e5da5Sopenharmony_ciOpName %ufoo "ufoo" 561fd4e5da5Sopenharmony_ciOpMemberName %ufoo 0 "data" 562fd4e5da5Sopenharmony_ciOpMemberName %ufoo 1 "nWrites" 563fd4e5da5Sopenharmony_ciOpName %bufStruct "bufStruct" 564fd4e5da5Sopenharmony_ciOpMemberName %bufStruct 0 "a" 565fd4e5da5Sopenharmony_ciOpName %u_info "u_info" 566fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 0 Offset 0 567fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 1 Offset 8 568fd4e5da5Sopenharmony_ciOpDecorate %ufoo Block 569fd4e5da5Sopenharmony_ciOpDecorate %_arr_int_uint_4 ArrayStride 16 570fd4e5da5Sopenharmony_ciOpMemberDecorate %bufStruct 0 Offset 0 571fd4e5da5Sopenharmony_ciOpDecorate %bufStruct Block 572fd4e5da5Sopenharmony_ciOpDecorate %u_info DescriptorSet 0 573fd4e5da5Sopenharmony_ciOpDecorate %u_info Binding 0 574fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 575fd4e5da5Sopenharmony_ci%void = OpTypeVoid 576fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 577fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 578fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 579fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 580fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer 581fd4e5da5Sopenharmony_ci%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %int 582fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 583fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4 584fd4e5da5Sopenharmony_ci%_arr_int_uint_4 = OpTypeArray %int %uint_4 585fd4e5da5Sopenharmony_ci%bufStruct = OpTypeStruct %_arr_int_uint_4 586fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct 587fd4e5da5Sopenharmony_ci%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo 588fd4e5da5Sopenharmony_ci%u_info = OpVariable %_ptr_Uniform_ufoo Uniform 589fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 590fd4e5da5Sopenharmony_ci%_ptr_Uniform_int = OpTypePointer Uniform %int 591fd4e5da5Sopenharmony_ci%bool = OpTypeBool 592fd4e5da5Sopenharmony_ci%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct 593fd4e5da5Sopenharmony_ci%int_n559035791 = OpConstant %int -559035791 594fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int 595fd4e5da5Sopenharmony_ci)" + kImportStub + R"( 596fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 597fd4e5da5Sopenharmony_ci%5 = OpLabel 598fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 599fd4e5da5Sopenharmony_ciOpStore %i %int_0 600fd4e5da5Sopenharmony_ciOpBranch %10 601fd4e5da5Sopenharmony_ci%10 = OpLabel 602fd4e5da5Sopenharmony_ciOpLoopMerge %12 %13 None 603fd4e5da5Sopenharmony_ciOpBranch %14 604fd4e5da5Sopenharmony_ci%14 = OpLabel 605fd4e5da5Sopenharmony_ci%15 = OpLoad %int %i 606fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 607fd4e5da5Sopenharmony_ci%27 = OpLoad %int %26 608fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %15 %27 609fd4e5da5Sopenharmony_ciOpBranchConditional %29 %11 %12 610fd4e5da5Sopenharmony_ci%11 = OpLabel 611fd4e5da5Sopenharmony_ci%31 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0 612fd4e5da5Sopenharmony_ci%32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31 613fd4e5da5Sopenharmony_ci%33 = OpLoad %int %i 614fd4e5da5Sopenharmony_ci%36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33 615fd4e5da5Sopenharmony_ciOpStore %36 %int_n559035791 Aligned 16 616fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %36 617fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 618fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 619fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 620fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_4 621fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 622fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}} 623fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 624fd4e5da5Sopenharmony_ci;CHECK: OpStore %36 %int_n559035791 Aligned 16 625fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 626fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 627fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 628fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 629fd4e5da5Sopenharmony_ciOpBranch %13 630fd4e5da5Sopenharmony_ci%13 = OpLabel 631fd4e5da5Sopenharmony_ci%37 = OpLoad %int %i 632fd4e5da5Sopenharmony_ci%38 = OpIAdd %int %37 %int_1 633fd4e5da5Sopenharmony_ciOpStore %i %38 634fd4e5da5Sopenharmony_ciOpBranch %10 635fd4e5da5Sopenharmony_ci%12 = OpLabel 636fd4e5da5Sopenharmony_ciOpReturn 637fd4e5da5Sopenharmony_ciOpFunctionEnd)"; 638fd4e5da5Sopenharmony_ci // clang-format on 639fd4e5da5Sopenharmony_ci 640fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 641fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 642fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>(text, true, 23); 643fd4e5da5Sopenharmony_ci} 644fd4e5da5Sopenharmony_ci 645fd4e5da5Sopenharmony_ciTEST_F(InstBuffAddrTest, UVec3ScalarAddressOOB) { 646fd4e5da5Sopenharmony_ci // clang-format off 647fd4e5da5Sopenharmony_ci // #version 450 648fd4e5da5Sopenharmony_ci // #extension GL_EXT_buffer_reference : enable 649fd4e5da5Sopenharmony_ci // #extension GL_EXT_scalar_block_layout : enable 650fd4e5da5Sopenharmony_ci // layout(buffer_reference, std430, scalar) readonly buffer IndexBuffer 651fd4e5da5Sopenharmony_ci // { 652fd4e5da5Sopenharmony_ci // uvec3 indices[]; 653fd4e5da5Sopenharmony_ci // }; 654fd4e5da5Sopenharmony_ci // layout(set = 0, binding = 0) uniform ufoo { 655fd4e5da5Sopenharmony_ci // IndexBuffer data; 656fd4e5da5Sopenharmony_ci // int nReads; 657fd4e5da5Sopenharmony_ci // } u_info; 658fd4e5da5Sopenharmony_ci // void main() { 659fd4e5da5Sopenharmony_ci // uvec3 readvec; 660fd4e5da5Sopenharmony_ci // for (int i=0; i < u_info.nReads; ++i) { 661fd4e5da5Sopenharmony_ci // readvec = u_info.data.indices[i]; 662fd4e5da5Sopenharmony_ci // } 663fd4e5da5Sopenharmony_ci // } 664fd4e5da5Sopenharmony_ci const std::string text = R"( 665fd4e5da5Sopenharmony_ciOpCapability Shader 666fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses 667fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 668fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450 669fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %u_info 670fd4e5da5Sopenharmony_ciOpSource GLSL 450 671fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_buffer_reference" 672fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_scalar_block_layout" 673fd4e5da5Sopenharmony_ciOpName %main "main" 674fd4e5da5Sopenharmony_ciOpName %i "i" 675fd4e5da5Sopenharmony_ciOpName %ufoo "ufoo" 676fd4e5da5Sopenharmony_ciOpMemberName %ufoo 0 "data" 677fd4e5da5Sopenharmony_ciOpMemberName %ufoo 1 "nReads" 678fd4e5da5Sopenharmony_ciOpName %IndexBuffer "IndexBuffer" 679fd4e5da5Sopenharmony_ciOpMemberName %IndexBuffer 0 "indices" 680fd4e5da5Sopenharmony_ciOpName %u_info "u_info" 681fd4e5da5Sopenharmony_ciOpName %readvec "readvec" 682fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 0 Offset 0 683fd4e5da5Sopenharmony_ciOpMemberDecorate %ufoo 1 Offset 8 684fd4e5da5Sopenharmony_ciOpDecorate %ufoo Block 685fd4e5da5Sopenharmony_ciOpDecorate %_runtimearr_v3uint ArrayStride 12 686fd4e5da5Sopenharmony_ciOpMemberDecorate %IndexBuffer 0 NonWritable 687fd4e5da5Sopenharmony_ciOpMemberDecorate %IndexBuffer 0 Offset 0 688fd4e5da5Sopenharmony_ciOpDecorate %IndexBuffer Block 689fd4e5da5Sopenharmony_ciOpDecorate %u_info DescriptorSet 0 690fd4e5da5Sopenharmony_ciOpDecorate %u_info Binding 0 691fd4e5da5Sopenharmony_ci)" + kImportDeco + R"( 692fd4e5da5Sopenharmony_ci%void = OpTypeVoid 693fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 694fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 695fd4e5da5Sopenharmony_ci%_ptr_Function_int = OpTypePointer Function %int 696fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 697fd4e5da5Sopenharmony_ciOpTypeForwardPointer %_ptr_PhysicalStorageBuffer_IndexBuffer PhysicalStorageBuffer 698fd4e5da5Sopenharmony_ci%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_IndexBuffer %int 699fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 700fd4e5da5Sopenharmony_ci%v3uint = OpTypeVector %uint 3 701fd4e5da5Sopenharmony_ci%_runtimearr_v3uint = OpTypeRuntimeArray %v3uint 702fd4e5da5Sopenharmony_ci%IndexBuffer = OpTypeStruct %_runtimearr_v3uint 703fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer PhysicalStorageBuffer %IndexBuffer 704fd4e5da5Sopenharmony_ci%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo 705fd4e5da5Sopenharmony_ci%u_info = OpVariable %_ptr_Uniform_ufoo Uniform 706fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1 707fd4e5da5Sopenharmony_ci%_ptr_Uniform_int = OpTypePointer Uniform %int 708fd4e5da5Sopenharmony_ci%bool = OpTypeBool 709fd4e5da5Sopenharmony_ci)" + kImportStub + R"( 710fd4e5da5Sopenharmony_ci%_ptr_Function_v3uint = OpTypePointer Function %v3uint 711fd4e5da5Sopenharmony_ci%_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_IndexBuffer 712fd4e5da5Sopenharmony_ci%_ptr_PhysicalStorageBuffer_v3uint = OpTypePointer PhysicalStorageBuffer %v3uint 713fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 714fd4e5da5Sopenharmony_ci%5 = OpLabel 715fd4e5da5Sopenharmony_ci%i = OpVariable %_ptr_Function_int Function 716fd4e5da5Sopenharmony_ci%readvec = OpVariable %_ptr_Function_v3uint Function 717fd4e5da5Sopenharmony_ciOpStore %i %int_0 718fd4e5da5Sopenharmony_ciOpBranch %10 719fd4e5da5Sopenharmony_ci%10 = OpLabel 720fd4e5da5Sopenharmony_ciOpLoopMerge %12 %13 None 721fd4e5da5Sopenharmony_ciOpBranch %14 722fd4e5da5Sopenharmony_ci%14 = OpLabel 723fd4e5da5Sopenharmony_ci%15 = OpLoad %int %i 724fd4e5da5Sopenharmony_ci%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1 725fd4e5da5Sopenharmony_ci%27 = OpLoad %int %26 726fd4e5da5Sopenharmony_ci%29 = OpSLessThan %bool %15 %27 727fd4e5da5Sopenharmony_ciOpBranchConditional %29 %11 %12 728fd4e5da5Sopenharmony_ci%11 = OpLabel 729fd4e5da5Sopenharmony_ci%33 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer %u_info %int_0 730fd4e5da5Sopenharmony_ci%34 = OpLoad %_ptr_PhysicalStorageBuffer_IndexBuffer %33 731fd4e5da5Sopenharmony_ci%35 = OpLoad %int %i 732fd4e5da5Sopenharmony_ci%37 = OpAccessChain %_ptr_PhysicalStorageBuffer_v3uint %34 %int_0 %35 733fd4e5da5Sopenharmony_ci%38 = OpLoad %v3uint %37 Aligned 4 734fd4e5da5Sopenharmony_ciOpStore %readvec %38 735fd4e5da5Sopenharmony_ci;CHECK-NOT: %38 = OpLoad %v3uint %37 Aligned 4 736fd4e5da5Sopenharmony_ci;CHECK-NOT: OpStore %readvec %38 737fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %37 738fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex 739fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex 740fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0 741fd4e5da5Sopenharmony_ci;CHECK: [[test_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_67 {{%\w+}} {{%\w+}} %uint_12 742fd4e5da5Sopenharmony_ci;CHECK: OpSelectionMerge {{%\w+}} None 743fd4e5da5Sopenharmony_ci;CHECK: OpBranchConditional [[test_result]] {{%\w+}} {{%\w+}} 744fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 745fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLoad %v3uint %37 Aligned 4 746fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 747fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 748fd4e5da5Sopenharmony_ci;CHECK: OpBranch {{%\w+}} 749fd4e5da5Sopenharmony_ci;CHECK: {{%\w+}} = OpLabel 750fd4e5da5Sopenharmony_ci;CHECK: [[phi_result:%\w+]] = OpPhi %v3uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} 751fd4e5da5Sopenharmony_ci;CHECK: OpStore %readvec [[phi_result]] 752fd4e5da5Sopenharmony_ciOpBranch %13 753fd4e5da5Sopenharmony_ci%13 = OpLabel 754fd4e5da5Sopenharmony_ci%39 = OpLoad %int %i 755fd4e5da5Sopenharmony_ci%40 = OpIAdd %int %39 %int_1 756fd4e5da5Sopenharmony_ciOpStore %i %40 757fd4e5da5Sopenharmony_ciOpBranch %10 758fd4e5da5Sopenharmony_ci%12 = OpLabel 759fd4e5da5Sopenharmony_ciOpReturn 760fd4e5da5Sopenharmony_ciOpFunctionEnd 761fd4e5da5Sopenharmony_ci)"; 762fd4e5da5Sopenharmony_ci // clang-format on 763fd4e5da5Sopenharmony_ci 764fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_UNIVERSAL_1_4); 765fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 766fd4e5da5Sopenharmony_ci ValidatorOptions()->scalar_block_layout = true; 767fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<InstBuffAddrCheckPass>(text, true, 23); 768fd4e5da5Sopenharmony_ci} 769fd4e5da5Sopenharmony_ci 770fd4e5da5Sopenharmony_ci} // namespace 771fd4e5da5Sopenharmony_ci} // namespace opt 772fd4e5da5Sopenharmony_ci} // namespace spvtools 773