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