1 // Copyright (c) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <string>
16 
17 #include "test/opt/pass_fixture.h"
18 #include "test/opt/pass_utils.h"
19 
20 namespace spvtools {
21 namespace opt {
22 namespace {
23 
24 using FixStorageClassTest = PassTest<::testing::Test>;
25 
TEST_F(FixStorageClassTest, FixAccessChain)26 TEST_F(FixStorageClassTest, FixAccessChain) {
27   const std::string text = R"(
28 ; CHECK: OpAccessChain %_ptr_Workgroup_float
29 ; CHECK: OpAccessChain %_ptr_Uniform_float
30                OpCapability Shader
31                OpMemoryModel Logical GLSL450
32                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
33                OpExecutionMode %1 LocalSize 8 8 1
34                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
35                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
36                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
37                OpDecorate %8 DescriptorSet 0
38                OpDecorate %8 Binding 0
39                OpDecorate %_runtimearr_float ArrayStride 4
40                OpMemberDecorate %_struct_7 0 Offset 0
41                OpDecorate %_struct_7 BufferBlock
42         %int = OpTypeInt 32 1
43       %int_0 = OpConstant %int 0
44       %float = OpTypeFloat 32
45     %float_2 = OpConstant %float 2
46        %uint = OpTypeInt 32 0
47     %uint_10 = OpConstant %uint 10
48 %_arr_float_uint_10 = OpTypeArray %float %uint_10
49 %ptr = OpTypePointer Function %_arr_float_uint_10
50 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
51   %_struct_5 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
52 %_ptr_Workgroup__struct_5 = OpTypePointer Workgroup %_struct_5
53 %_runtimearr_float = OpTypeRuntimeArray %float
54   %_struct_7 = OpTypeStruct %_runtimearr_float
55 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
56      %v3uint = OpTypeVector %uint 3
57 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
58        %void = OpTypeVoid
59          %30 = OpTypeFunction %void
60 %_ptr_Function_float = OpTypePointer Function %float
61 %_ptr_Uniform_float = OpTypePointer Uniform %float
62           %6 = OpVariable %_ptr_Workgroup__struct_5 Workgroup
63           %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
64 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
65 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
66 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
67           %1 = OpFunction %void None %30
68          %38 = OpLabel
69          %44 = OpLoad %v3uint %gl_LocalInvocationID
70          %50 = OpAccessChain %_ptr_Function_float %6 %int_0 %int_0 %int_0
71          %51 = OpLoad %float %50
72          %52 = OpFMul %float %float_2 %51
73                OpStore %50 %52
74          %55 = OpLoad %float %50
75          %59 = OpCompositeExtract %uint %44 0
76          %60 = OpAccessChain %_ptr_Uniform_float %8 %int_0 %59
77                OpStore %60 %55
78                OpReturn
79                OpFunctionEnd
80 )";
81 
82   SinglePassRunAndMatch<FixStorageClass>(text, false);
83 }
84 
TEST_F(FixStorageClassTest, FixLinkedAccessChain)85 TEST_F(FixStorageClassTest, FixLinkedAccessChain) {
86   const std::string text = R"(
87 ; CHECK: OpAccessChain %_ptr_Workgroup__arr_float_uint_10
88 ; CHECK: OpAccessChain %_ptr_Workgroup_float
89 ; CHECK: OpAccessChain %_ptr_Uniform_float
90                OpCapability Shader
91                OpMemoryModel Logical GLSL450
92                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
93                OpExecutionMode %1 LocalSize 8 8 1
94                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
95                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
96                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
97                OpDecorate %5 DescriptorSet 0
98                OpDecorate %5 Binding 0
99                OpDecorate %_runtimearr_float ArrayStride 4
100                OpMemberDecorate %_struct_7 0 Offset 0
101                OpDecorate %_struct_7 BufferBlock
102         %int = OpTypeInt 32 1
103       %int_0 = OpConstant %int 0
104       %float = OpTypeFloat 32
105     %float_2 = OpConstant %float 2
106        %uint = OpTypeInt 32 0
107     %uint_10 = OpConstant %uint 10
108 %_arr_float_uint_10 = OpTypeArray %float %uint_10
109 %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
110 %_ptr = OpTypePointer Function %_arr_float_uint_10
111 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
112  %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
113 %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
114 %_runtimearr_float = OpTypeRuntimeArray %float
115   %_struct_7 = OpTypeStruct %_runtimearr_float
116 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
117      %v3uint = OpTypeVector %uint 3
118 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
119        %void = OpTypeVoid
120          %23 = OpTypeFunction %void
121 %_ptr_Function_float = OpTypePointer Function %float
122 %_ptr_Uniform_float = OpTypePointer Uniform %float
123          %27 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
124           %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
125 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
126 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
127 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
128           %1 = OpFunction %void None %23
129          %28 = OpLabel
130          %29 = OpLoad %v3uint %gl_LocalInvocationID
131          %30 = OpAccessChain %_ptr_Function__arr_float_uint_10 %27 %int_0 %int_0
132          %31 = OpAccessChain %_ptr_Function_float %30 %int_0
133          %32 = OpLoad %float %31
134          %33 = OpFMul %float %float_2 %32
135                OpStore %31 %33
136          %34 = OpLoad %float %31
137          %35 = OpCompositeExtract %uint %29 0
138          %36 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %35
139                OpStore %36 %34
140                OpReturn
141                OpFunctionEnd
142 )";
143 
144   SinglePassRunAndMatch<FixStorageClass>(text, false);
145 }
146 
TEST_F(FixStorageClassTest, FixCopyObject)147 TEST_F(FixStorageClassTest, FixCopyObject) {
148   const std::string text = R"(
149 ; CHECK: OpCopyObject %_ptr_Workgroup__struct_17
150 ; CHECK: OpAccessChain %_ptr_Workgroup_float
151 ; CHECK: OpAccessChain %_ptr_Uniform_float
152                OpCapability Shader
153                OpMemoryModel Logical GLSL450
154                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
155                OpExecutionMode %1 LocalSize 8 8 1
156                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
157                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
158                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
159                OpDecorate %8 DescriptorSet 0
160                OpDecorate %8 Binding 0
161                OpDecorate %_runtimearr_float ArrayStride 4
162                OpMemberDecorate %_struct_7 0 Offset 0
163                OpDecorate %_struct_7 BufferBlock
164         %int = OpTypeInt 32 1
165       %int_0 = OpConstant %int 0
166       %float = OpTypeFloat 32
167     %float_2 = OpConstant %float 2
168        %uint = OpTypeInt 32 0
169     %uint_10 = OpConstant %uint 10
170 %_arr_float_uint_10 = OpTypeArray %float %uint_10
171 %ptr = OpTypePointer Function %_arr_float_uint_10
172 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
173   %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
174 %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
175 %_ptr_Function__struct_17 = OpTypePointer Function %_struct_17
176 %_runtimearr_float = OpTypeRuntimeArray %float
177   %_struct_7 = OpTypeStruct %_runtimearr_float
178 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
179      %v3uint = OpTypeVector %uint 3
180 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
181        %void = OpTypeVoid
182          %30 = OpTypeFunction %void
183 %_ptr_Function_float = OpTypePointer Function %float
184 %_ptr_Uniform_float = OpTypePointer Uniform %float
185           %6 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
186           %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
187 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
188 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
189 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
190           %1 = OpFunction %void None %30
191          %38 = OpLabel
192          %44 = OpLoad %v3uint %gl_LocalInvocationID
193          %cp = OpCopyObject %_ptr_Function__struct_17 %6
194          %50 = OpAccessChain %_ptr_Function_float %cp %int_0 %int_0 %int_0
195          %51 = OpLoad %float %50
196          %52 = OpFMul %float %float_2 %51
197                OpStore %50 %52
198          %55 = OpLoad %float %50
199          %59 = OpCompositeExtract %uint %44 0
200          %60 = OpAccessChain %_ptr_Uniform_float %8 %int_0 %59
201                OpStore %60 %55
202                OpReturn
203                OpFunctionEnd
204 )";
205 
206   SinglePassRunAndMatch<FixStorageClass>(text, false);
207 }
208 
TEST_F(FixStorageClassTest, FixPhiInSelMerge)209 TEST_F(FixStorageClassTest, FixPhiInSelMerge) {
210   const std::string text = R"(
211 ; CHECK: OpPhi %_ptr_Workgroup__struct_19
212 ; CHECK: OpAccessChain %_ptr_Workgroup_float
213 ; CHECK: OpAccessChain %_ptr_Uniform_float
214                OpCapability Shader
215                OpMemoryModel Logical GLSL450
216                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
217                OpExecutionMode %1 LocalSize 8 8 1
218                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
219                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
220                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
221                OpDecorate %5 DescriptorSet 0
222                OpDecorate %5 Binding 0
223                OpDecorate %_runtimearr_float ArrayStride 4
224                OpMemberDecorate %_struct_7 0 Offset 0
225                OpDecorate %_struct_7 BufferBlock
226        %bool = OpTypeBool
227        %true = OpConstantTrue %bool
228         %int = OpTypeInt 32 1
229       %int_0 = OpConstant %int 0
230       %float = OpTypeFloat 32
231     %float_2 = OpConstant %float 2
232        %uint = OpTypeInt 32 0
233     %uint_10 = OpConstant %uint 10
234 %_arr_float_uint_10 = OpTypeArray %float %uint_10
235 %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
236 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
237  %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
238 %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
239 %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
240 %_runtimearr_float = OpTypeRuntimeArray %float
241   %_struct_7 = OpTypeStruct %_runtimearr_float
242 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
243      %v3uint = OpTypeVector %uint 3
244 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
245        %void = OpTypeVoid
246          %25 = OpTypeFunction %void
247 %_ptr_Function_float = OpTypePointer Function %float
248 %_ptr_Uniform_float = OpTypePointer Uniform %float
249          %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
250          %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
251           %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
252 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
253 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
254 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
255           %1 = OpFunction %void None %25
256          %30 = OpLabel
257                OpSelectionMerge %31 None
258                OpBranchConditional %true %32 %31
259          %32 = OpLabel
260                OpBranch %31
261          %31 = OpLabel
262          %33 = OpPhi %_ptr_Function__struct_19 %28 %30 %29 %32
263          %34 = OpLoad %v3uint %gl_LocalInvocationID
264          %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
265          %36 = OpLoad %float %35
266          %37 = OpFMul %float %float_2 %36
267                OpStore %35 %37
268          %38 = OpLoad %float %35
269          %39 = OpCompositeExtract %uint %34 0
270          %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
271                OpStore %40 %38
272                OpReturn
273                OpFunctionEnd
274 )";
275 
276   SinglePassRunAndMatch<FixStorageClass>(text, false);
277 }
278 
TEST_F(FixStorageClassTest, FixPhiInLoop)279 TEST_F(FixStorageClassTest, FixPhiInLoop) {
280   const std::string text = R"(
281 ; CHECK: OpPhi %_ptr_Workgroup__struct_19
282 ; CHECK: OpAccessChain %_ptr_Workgroup_float
283 ; CHECK: OpAccessChain %_ptr_Uniform_float
284                OpCapability Shader
285                OpMemoryModel Logical GLSL450
286                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
287                OpExecutionMode %1 LocalSize 8 8 1
288                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
289                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
290                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
291                OpDecorate %5 DescriptorSet 0
292                OpDecorate %5 Binding 0
293                OpDecorate %_runtimearr_float ArrayStride 4
294                OpMemberDecorate %_struct_7 0 Offset 0
295                OpDecorate %_struct_7 BufferBlock
296        %bool = OpTypeBool
297        %true = OpConstantTrue %bool
298         %int = OpTypeInt 32 1
299       %int_0 = OpConstant %int 0
300       %float = OpTypeFloat 32
301     %float_2 = OpConstant %float 2
302        %uint = OpTypeInt 32 0
303     %uint_10 = OpConstant %uint 10
304 %_arr_float_uint_10 = OpTypeArray %float %uint_10
305 %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
306 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
307  %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
308 %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
309 %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
310 %_runtimearr_float = OpTypeRuntimeArray %float
311   %_struct_7 = OpTypeStruct %_runtimearr_float
312 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
313      %v3uint = OpTypeVector %uint 3
314 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
315        %void = OpTypeVoid
316          %25 = OpTypeFunction %void
317 %_ptr_Function_float = OpTypePointer Function %float
318 %_ptr_Uniform_float = OpTypePointer Uniform %float
319          %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
320          %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
321           %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
322 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
323 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
324 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
325           %1 = OpFunction %void None %25
326          %30 = OpLabel
327                OpSelectionMerge %31 None
328                OpBranchConditional %true %32 %31
329          %32 = OpLabel
330                OpBranch %31
331          %31 = OpLabel
332          %33 = OpPhi %_ptr_Function__struct_19 %28 %30 %29 %32
333          %34 = OpLoad %v3uint %gl_LocalInvocationID
334          %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
335          %36 = OpLoad %float %35
336          %37 = OpFMul %float %float_2 %36
337                OpStore %35 %37
338          %38 = OpLoad %float %35
339          %39 = OpCompositeExtract %uint %34 0
340          %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
341                OpStore %40 %38
342                OpReturn
343                OpFunctionEnd
344 )";
345 
346   SinglePassRunAndMatch<FixStorageClass>(text, false);
347 }
348 
TEST_F(FixStorageClassTest, DontChangeFunctionCalls)349 TEST_F(FixStorageClassTest, DontChangeFunctionCalls) {
350   const std::string text = R"(OpCapability Shader
351 OpMemoryModel Logical GLSL450
352 OpEntryPoint GLCompute %1 "testMain"
353 OpExecutionMode %1 LocalSize 8 8 1
354 OpDecorate %2 DescriptorSet 0
355 OpDecorate %2 Binding 0
356 %int = OpTypeInt 32 1
357 %_ptr_Function_int = OpTypePointer Function %int
358 %_ptr_Workgroup_int = OpTypePointer Workgroup %int
359 %_ptr_Uniform_int = OpTypePointer Uniform %int
360 %void = OpTypeVoid
361 %8 = OpTypeFunction %void
362 %9 = OpTypeFunction %_ptr_Uniform_int %_ptr_Function_int
363 %10 = OpVariable %_ptr_Workgroup_int Workgroup
364 %2 = OpVariable %_ptr_Uniform_int Uniform
365 %1 = OpFunction %void None %8
366 %11 = OpLabel
367 %12 = OpFunctionCall %_ptr_Uniform_int %13 %10
368 OpReturn
369 OpFunctionEnd
370 %13 = OpFunction %_ptr_Uniform_int None %9
371 %14 = OpFunctionParameter %_ptr_Function_int
372 %15 = OpLabel
373 OpReturnValue %2
374 OpFunctionEnd
375 )";
376 
377   SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
378 }
379 
TEST_F(FixStorageClassTest, FixSelect)380 TEST_F(FixStorageClassTest, FixSelect) {
381   const std::string text = R"(
382 ; CHECK: OpSelect %_ptr_Workgroup__struct_19
383 ; CHECK: OpAccessChain %_ptr_Workgroup_float
384 ; CHECK: OpAccessChain %_ptr_Uniform_float
385                OpCapability Shader
386                OpMemoryModel Logical GLSL450
387                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
388                OpExecutionMode %1 LocalSize 8 8 1
389                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
390                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
391                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
392                OpDecorate %5 DescriptorSet 0
393                OpDecorate %5 Binding 0
394                OpDecorate %_runtimearr_float ArrayStride 4
395                OpMemberDecorate %_struct_7 0 Offset 0
396                OpDecorate %_struct_7 BufferBlock
397        %bool = OpTypeBool
398        %true = OpConstantTrue %bool
399         %int = OpTypeInt 32 1
400       %int_0 = OpConstant %int 0
401       %float = OpTypeFloat 32
402     %float_2 = OpConstant %float 2
403        %uint = OpTypeInt 32 0
404     %uint_10 = OpConstant %uint 10
405 %_arr_float_uint_10 = OpTypeArray %float %uint_10
406 %_ptr_Function__arr_float_uint_10 = OpTypePointer Function %_arr_float_uint_10
407 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
408  %_struct_19 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
409 %_ptr_Workgroup__struct_19 = OpTypePointer Workgroup %_struct_19
410 %_ptr_Function__struct_19 = OpTypePointer Function %_struct_19
411 %_runtimearr_float = OpTypeRuntimeArray %float
412   %_struct_7 = OpTypeStruct %_runtimearr_float
413 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
414      %v3uint = OpTypeVector %uint 3
415 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
416        %void = OpTypeVoid
417          %25 = OpTypeFunction %void
418 %_ptr_Function_float = OpTypePointer Function %float
419 %_ptr_Uniform_float = OpTypePointer Uniform %float
420          %28 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
421          %29 = OpVariable %_ptr_Workgroup__struct_19 Workgroup
422           %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
423 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
424 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
425 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
426           %1 = OpFunction %void None %25
427          %30 = OpLabel
428          %33 = OpSelect %_ptr_Function__struct_19 %true %28 %29
429          %34 = OpLoad %v3uint %gl_LocalInvocationID
430          %35 = OpAccessChain %_ptr_Function_float %33 %int_0 %int_0 %int_0
431          %36 = OpLoad %float %35
432          %37 = OpFMul %float %float_2 %36
433                OpStore %35 %37
434          %38 = OpLoad %float %35
435          %39 = OpCompositeExtract %uint %34 0
436          %40 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %39
437                OpStore %40 %38
438                OpReturn
439                OpFunctionEnd
440 )";
441 
442   SinglePassRunAndMatch<FixStorageClass>(text, false);
443 }
444 
TEST_F(FixStorageClassTest, BitCast)445 TEST_F(FixStorageClassTest, BitCast) {
446   const std::string text = R"(OpCapability VariablePointersStorageBuffer
447 OpMemoryModel Logical GLSL450
448 OpEntryPoint GLCompute %1 "main"
449 %void = OpTypeVoid
450 %3 = OpTypeFunction %void
451 %_ptr_Output_void = OpTypePointer Output %void
452 %_ptr_Private__ptr_Output_void = OpTypePointer Private %_ptr_Output_void
453 %6 = OpVariable %_ptr_Private__ptr_Output_void Private
454 %1 = OpFunction %void Inline %3
455 %7 = OpLabel
456 %8 = OpBitcast %_ptr_Output_void %6
457 OpReturn
458 OpFunctionEnd
459 )";
460 
461   SinglePassRunAndCheck<FixStorageClass>(text, text, false);
462 }
463 
TEST_F(FixStorageClassTest, FixLinkedAccessChain2)464 TEST_F(FixStorageClassTest, FixLinkedAccessChain2) {
465   // This case is similar to FixLinkedAccessChain.  The difference is that the
466   // first OpAccessChain instruction starts as workgroup storage class.  Only
467   // the second one needs to change.
468   const std::string text = R"(
469 ; CHECK: OpAccessChain %_ptr_Workgroup__arr_float_uint_10
470 ; CHECK: OpAccessChain %_ptr_Workgroup_float
471 ; CHECK: OpAccessChain %_ptr_Uniform_float
472                OpCapability Shader
473                OpMemoryModel Logical GLSL450
474                OpEntryPoint GLCompute %1 "testMain" %gl_GlobalInvocationID %gl_LocalInvocationID %gl_WorkGroupID
475                OpExecutionMode %1 LocalSize 8 8 1
476                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
477                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
478                OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
479                OpDecorate %5 DescriptorSet 0
480                OpDecorate %5 Binding 0
481                OpDecorate %_runtimearr_float ArrayStride 4
482                OpMemberDecorate %_struct_7 0 Offset 0
483                OpDecorate %_struct_7 BufferBlock
484         %int = OpTypeInt 32 1
485       %int_0 = OpConstant %int 0
486       %float = OpTypeFloat 32
487     %float_2 = OpConstant %float 2
488        %uint = OpTypeInt 32 0
489     %uint_10 = OpConstant %uint 10
490 %_arr_float_uint_10 = OpTypeArray %float %uint_10
491 %_ptr_Workgroup__arr_float_uint_10 = OpTypePointer Workgroup %_arr_float_uint_10
492 %_ptr = OpTypePointer Function %_arr_float_uint_10
493 %_arr__arr_float_uint_10_uint_10 = OpTypeArray %_arr_float_uint_10 %uint_10
494  %_struct_17 = OpTypeStruct %_arr__arr_float_uint_10_uint_10
495 %_ptr_Workgroup__struct_17 = OpTypePointer Workgroup %_struct_17
496 %_runtimearr_float = OpTypeRuntimeArray %float
497   %_struct_7 = OpTypeStruct %_runtimearr_float
498 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
499      %v3uint = OpTypeVector %uint 3
500 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
501        %void = OpTypeVoid
502          %23 = OpTypeFunction %void
503 %_ptr_Function_float = OpTypePointer Function %float
504 %_ptr_Uniform_float = OpTypePointer Uniform %float
505          %27 = OpVariable %_ptr_Workgroup__struct_17 Workgroup
506           %5 = OpVariable %_ptr_Uniform__struct_7 Uniform
507 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
508 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
509 %gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
510           %1 = OpFunction %void None %23
511          %28 = OpLabel
512          %29 = OpLoad %v3uint %gl_LocalInvocationID
513          %30 = OpAccessChain %_ptr_Workgroup__arr_float_uint_10 %27 %int_0 %int_0
514          %31 = OpAccessChain %_ptr_Function_float %30 %int_0
515          %32 = OpLoad %float %31
516          %33 = OpFMul %float %float_2 %32
517                OpStore %31 %33
518          %34 = OpLoad %float %31
519          %35 = OpCompositeExtract %uint %29 0
520          %36 = OpAccessChain %_ptr_Uniform_float %5 %int_0 %35
521                OpStore %36 %34
522                OpReturn
523                OpFunctionEnd
524 )";
525 
526   SinglePassRunAndMatch<FixStorageClass>(text, false);
527 }
528 
TEST_F(FixStorageClassTest, AllowImageFormatMismatch)529 TEST_F(FixStorageClassTest, AllowImageFormatMismatch) {
530   const std::string text = R"(OpCapability Shader
531 OpCapability SampledBuffer
532 OpCapability ImageBuffer
533 OpMemoryModel Logical GLSL450
534 OpEntryPoint GLCompute %main "main"
535 OpExecutionMode %main LocalSize 1 1 1
536 OpSource HLSL 600
537 OpName %type_buffer_image "type.buffer.image"
538 OpName %Buf "Buf"
539 OpName %main "main"
540 OpName %src_main "src.main"
541 OpName %bb_entry "bb.entry"
542 OpName %type_buffer_image_0 "type.buffer.image"
543 OpName %b "b"
544 OpDecorate %Buf DescriptorSet 0
545 OpDecorate %Buf Binding 0
546 %float = OpTypeFloat 32
547 %type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba16f
548 %_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
549 %void = OpTypeVoid
550 %11 = OpTypeFunction %void
551 %type_buffer_image_0 = OpTypeImage %float Buffer 2 0 0 2 Rgba32f
552 %_ptr_Function_type_buffer_image_0 = OpTypePointer Function %type_buffer_image_0
553 %Buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
554 %main = OpFunction %void None %11
555 %13 = OpLabel
556 %14 = OpFunctionCall %void %src_main
557 OpReturn
558 OpFunctionEnd
559 %src_main = OpFunction %void None %11
560 %bb_entry = OpLabel
561 %b = OpVariable %_ptr_Function_type_buffer_image_0 Function
562 %15 = OpLoad %type_buffer_image %Buf
563 OpStore %b %15
564 OpReturn
565 OpFunctionEnd
566 )";
567 
568   SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
569 }
570 
571 using FixTypeTest = PassTest<::testing::Test>;
572 
TEST_F(FixTypeTest, FixAccessChain)573 TEST_F(FixTypeTest, FixAccessChain) {
574   const std::string text = R"(
575 ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
576 ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_T [[ac1]] %int_0
577                OpCapability Shader
578                OpMemoryModel Logical GLSL450
579                OpEntryPoint GLCompute %main "main"
580                OpExecutionMode %main LocalSize 1 1 1
581                OpSource HLSL 600
582                OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
583                OpName %S "S"
584                OpMemberName %S 0 "t"
585                OpName %T "T"
586                OpMemberName %T 0 "a"
587                OpName %A "A"
588                OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
589                OpMemberName %type_ACSBuffer_counter 0 "counter"
590                OpName %counter_var_A "counter.var.A"
591                OpName %main "main"
592                OpName %S_0 "S"
593                OpMemberName %S_0 0 "t"
594                OpName %T_0 "T"
595                OpMemberName %T_0 0 "a"
596                OpDecorate %A DescriptorSet 0
597                OpDecorate %A Binding 0
598                OpDecorate %counter_var_A DescriptorSet 0
599                OpDecorate %counter_var_A Binding 1
600                OpMemberDecorate %T 0 Offset 0
601                OpMemberDecorate %S 0 Offset 0
602                OpDecorate %_runtimearr_S ArrayStride 4
603                OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
604                OpDecorate %type_RWStructuredBuffer_S BufferBlock
605                OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
606                OpDecorate %type_ACSBuffer_counter BufferBlock
607         %int = OpTypeInt 32 1
608       %int_0 = OpConstant %int 0
609        %uint = OpTypeInt 32 0
610      %uint_0 = OpConstant %uint 0
611           %T = OpTypeStruct %int
612           %S = OpTypeStruct %T
613 %_runtimearr_S = OpTypeRuntimeArray %S
614 %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
615 %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
616 %type_ACSBuffer_counter = OpTypeStruct %int
617 %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
618        %void = OpTypeVoid
619          %18 = OpTypeFunction %void
620         %T_0 = OpTypeStruct %int
621         %S_0 = OpTypeStruct %T_0
622 %_ptr_Function_S_0 = OpTypePointer Function %S_0
623 %_ptr_Uniform_S = OpTypePointer Uniform %S
624 %_ptr_Uniform_T = OpTypePointer Uniform %T
625          %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
626 %_ptr_Function_T_0 = OpTypePointer Function %T_0
627           %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
628 %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
629        %main = OpFunction %void None %18
630          %24 = OpLabel
631          %25 = OpVariable %_ptr_Function_T_0 Function
632          %26 = OpVariable %_ptr_Function_S_0 Function
633          %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
634          %28 = OpAccessChain %_ptr_Function_T_0 %27 %int_0
635                OpReturn
636                OpFunctionEnd
637 )";
638 
639   SinglePassRunAndMatch<FixStorageClass>(text, false);
640 }
641 
TEST_F(FixTypeTest, FixLoad)642 TEST_F(FixTypeTest, FixLoad) {
643   const std::string text = R"(
644 ; CHECK: [[ac1:%\w+]] = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
645 ; CHECK: [[ac2:%\w+]] = OpAccessChain %_ptr_Uniform_T [[ac1]] %int_0
646 ; CHECK: [[ld:%\w+]] = OpLoad %T [[ac2]]
647                OpCapability Shader
648                OpMemoryModel Logical GLSL450
649                OpEntryPoint GLCompute %main "main"
650                OpExecutionMode %main LocalSize 1 1 1
651                OpSource HLSL 600
652                OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
653                OpName %S "S"
654                OpMemberName %S 0 "t"
655                OpName %T "T"
656                OpMemberName %T 0 "a"
657                OpName %A "A"
658                OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
659                OpMemberName %type_ACSBuffer_counter 0 "counter"
660                OpName %counter_var_A "counter.var.A"
661                OpName %main "main"
662                OpName %S_0 "S"
663                OpMemberName %S_0 0 "t"
664                OpName %T_0 "T"
665                OpMemberName %T_0 0 "a"
666                OpDecorate %A DescriptorSet 0
667                OpDecorate %A Binding 0
668                OpDecorate %counter_var_A DescriptorSet 0
669                OpDecorate %counter_var_A Binding 1
670                OpMemberDecorate %T 0 Offset 0
671                OpMemberDecorate %S 0 Offset 0
672                OpDecorate %_runtimearr_S ArrayStride 4
673                OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
674                OpDecorate %type_RWStructuredBuffer_S BufferBlock
675                OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
676                OpDecorate %type_ACSBuffer_counter BufferBlock
677         %int = OpTypeInt 32 1
678       %int_0 = OpConstant %int 0
679        %uint = OpTypeInt 32 0
680      %uint_0 = OpConstant %uint 0
681           %T = OpTypeStruct %int
682           %S = OpTypeStruct %T
683 %_runtimearr_S = OpTypeRuntimeArray %S
684 %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
685 %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
686 %type_ACSBuffer_counter = OpTypeStruct %int
687 %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
688        %void = OpTypeVoid
689          %18 = OpTypeFunction %void
690         %T_0 = OpTypeStruct %int
691         %S_0 = OpTypeStruct %T_0
692 %_ptr_Function_S_0 = OpTypePointer Function %S_0
693 %_ptr_Uniform_S = OpTypePointer Uniform %S
694 %_ptr_Uniform_T = OpTypePointer Uniform %T
695          %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
696 %_ptr_Function_T_0 = OpTypePointer Function %T_0
697           %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
698 %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
699        %main = OpFunction %void None %18
700          %24 = OpLabel
701          %25 = OpVariable %_ptr_Function_T_0 Function
702          %26 = OpVariable %_ptr_Function_S_0 Function
703          %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
704          %28 = OpAccessChain %_ptr_Uniform_T %27 %int_0
705          %29 = OpLoad %T_0 %28
706                OpReturn
707                OpFunctionEnd
708 )";
709 
710   SinglePassRunAndMatch<FixStorageClass>(text, false);
711 }
712 
TEST_F(FixTypeTest, FixStore)713 TEST_F(FixTypeTest, FixStore) {
714   const std::string text = R"(
715 ; CHECK: [[ld:%\w+]] = OpLoad %T
716 ; CHECK: OpStore
717                OpCapability Shader
718                OpMemoryModel Logical GLSL450
719                OpEntryPoint GLCompute %main "main"
720                OpExecutionMode %main LocalSize 1 1 1
721                OpSource HLSL 600
722                OpName %type_RWStructuredBuffer_S "type.RWStructuredBuffer.S"
723                OpName %S "S"
724                OpMemberName %S 0 "t"
725                OpName %T "T"
726                OpMemberName %T 0 "a"
727                OpName %A "A"
728                OpName %type_ACSBuffer_counter "type.ACSBuffer.counter"
729                OpMemberName %type_ACSBuffer_counter 0 "counter"
730                OpName %counter_var_A "counter.var.A"
731                OpName %main "main"
732                OpName %S_0 "S"
733                OpMemberName %S_0 0 "t"
734                OpName %T_0 "T"
735                OpMemberName %T_0 0 "a"
736                OpDecorate %A DescriptorSet 0
737                OpDecorate %A Binding 0
738                OpDecorate %counter_var_A DescriptorSet 0
739                OpDecorate %counter_var_A Binding 1
740                OpMemberDecorate %T 0 Offset 0
741                OpMemberDecorate %S 0 Offset 0
742                OpDecorate %_runtimearr_S ArrayStride 4
743                OpMemberDecorate %type_RWStructuredBuffer_S 0 Offset 0
744                OpDecorate %type_RWStructuredBuffer_S BufferBlock
745                OpMemberDecorate %type_ACSBuffer_counter 0 Offset 0
746                OpDecorate %type_ACSBuffer_counter BufferBlock
747         %int = OpTypeInt 32 1
748       %int_0 = OpConstant %int 0
749        %uint = OpTypeInt 32 0
750      %uint_0 = OpConstant %uint 0
751           %T = OpTypeStruct %int
752           %S = OpTypeStruct %T
753 %_runtimearr_S = OpTypeRuntimeArray %S
754 %type_RWStructuredBuffer_S = OpTypeStruct %_runtimearr_S
755 %_ptr_Uniform_type_RWStructuredBuffer_S = OpTypePointer Uniform %type_RWStructuredBuffer_S
756 %type_ACSBuffer_counter = OpTypeStruct %int
757 %_ptr_Uniform_type_ACSBuffer_counter = OpTypePointer Uniform %type_ACSBuffer_counter
758        %void = OpTypeVoid
759          %18 = OpTypeFunction %void
760         %T_0 = OpTypeStruct %int
761         %S_0 = OpTypeStruct %T_0
762 %_ptr_Function_S_0 = OpTypePointer Function %S_0
763 %_ptr_Uniform_S = OpTypePointer Uniform %S
764 %_ptr_Uniform_T = OpTypePointer Uniform %T
765          %22 = OpTypeFunction %T_0 %_ptr_Function_S_0
766 %_ptr_Function_T_0 = OpTypePointer Function %T_0
767           %A = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_S Uniform
768 %counter_var_A = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
769        %main = OpFunction %void None %18
770          %24 = OpLabel
771          %25 = OpVariable %_ptr_Function_T_0 Function
772          %26 = OpVariable %_ptr_Function_S_0 Function
773          %27 = OpAccessChain %_ptr_Uniform_S %A %int_0 %uint_0
774          %28 = OpAccessChain %_ptr_Uniform_T %27 %int_0
775          %29 = OpLoad %T %28
776                OpStore %25 %29
777                OpReturn
778                OpFunctionEnd
779 )";
780 
781   SinglePassRunAndMatch<FixStorageClass>(text, false);
782 }
783 
TEST_F(FixTypeTest, FixSelect)784 TEST_F(FixTypeTest, FixSelect) {
785   const std::string text = R"(
786 ; CHECK: OpSelect %_ptr_Uniform__struct_3
787                OpCapability Shader
788                OpMemoryModel Logical GLSL450
789                OpEntryPoint GLCompute %1 "main"
790                OpExecutionMode %1 LocalSize 1 1 1
791                OpSource HLSL 600
792                OpDecorate %2 DescriptorSet 0
793                OpDecorate %2 Binding 0
794                OpMemberDecorate %_struct_3 0 Offset 0
795                OpDecorate %_runtimearr__struct_3 ArrayStride 4
796                OpMemberDecorate %_struct_5 0 Offset 0
797                OpDecorate %_struct_5 BufferBlock
798        %uint = OpTypeInt 32 0
799      %uint_0 = OpConstant %uint 0
800      %uint_1 = OpConstant %uint 1
801   %_struct_3 = OpTypeStruct %uint
802 %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
803   %_struct_5 = OpTypeStruct %_runtimearr__struct_3
804 %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
805        %void = OpTypeVoid
806          %11 = OpTypeFunction %void
807  %_struct_12 = OpTypeStruct %uint
808 %_ptr_Function__struct_12 = OpTypePointer Function %_struct_12
809 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
810        %bool = OpTypeBool
811 %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
812           %2 = OpVariable %_ptr_Uniform__struct_5 Uniform
813           %1 = OpFunction %void None %11
814          %17 = OpLabel
815          %18 = OpAccessChain %_ptr_Uniform_uint %2 %uint_0 %uint_0 %uint_0
816          %19 = OpLoad %uint %18
817          %20 = OpSGreaterThan %bool %19 %uint_0
818          %21 = OpAccessChain %_ptr_Uniform__struct_3 %2 %uint_0 %uint_0
819          %22 = OpAccessChain %_ptr_Uniform__struct_3 %2 %uint_0 %uint_1
820          %23 = OpSelect %_ptr_Function__struct_12 %20 %21 %22
821                OpReturn
822                OpFunctionEnd
823 )";
824 
825   SinglePassRunAndMatch<FixStorageClass>(text, false);
826 }
827 
TEST_F(FixTypeTest, FixPhiInLoop)828 TEST_F(FixTypeTest, FixPhiInLoop) {
829   const std::string text = R"(
830 ; CHECK: [[ac_init:%\w+]] = OpAccessChain %_ptr_Uniform__struct_3
831 ; CHECK: [[ac_phi:%\w+]] = OpPhi %_ptr_Uniform__struct_3 [[ac_init]] {{%\w+}} [[ac_update:%\w+]] {{%\w+}}
832 ; CHECK: [[ac_update]] = OpPtrAccessChain %_ptr_Uniform__struct_3 [[ac_phi]] %int_1
833                OpCapability Shader
834                OpMemoryModel Logical GLSL450
835                OpEntryPoint GLCompute %1 "main"
836                OpExecutionMode %1 LocalSize 1 1 1
837                OpSource HLSL 600
838                OpDecorate %2 DescriptorSet 0
839                OpDecorate %2 Binding 0
840                OpMemberDecorate %_struct_3 0 Offset 0
841                OpDecorate %_runtimearr__struct_3 ArrayStride 4
842                OpMemberDecorate %_struct_5 0 Offset 0
843                OpDecorate %_struct_5 BufferBlock
844         %int = OpTypeInt 32 1
845       %int_0 = OpConstant %int 0
846       %int_1 = OpConstant %int 1
847   %_struct_3 = OpTypeStruct %int
848   %_struct_9 = OpTypeStruct %int
849 %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
850   %_struct_5 = OpTypeStruct %_runtimearr__struct_3
851 %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
852        %void = OpTypeVoid
853          %12 = OpTypeFunction %void
854        %bool = OpTypeBool
855 %_ptr_Uniform__struct_3 = OpTypePointer Uniform %_struct_3
856 %_ptr_Function__struct_9 = OpTypePointer Function %_struct_9
857           %2 = OpVariable %_ptr_Uniform__struct_5 Uniform
858           %1 = OpFunction %void None %12
859          %16 = OpLabel
860          %17 = OpAccessChain %_ptr_Uniform__struct_3 %2 %int_0 %int_0
861                OpBranch %18
862          %18 = OpLabel
863          %20 = OpPhi %_ptr_Function__struct_9 %17 %16 %21 %22
864          %23 = OpUndef %bool
865                OpLoopMerge %24 %22 None
866                OpBranchConditional %23 %22 %24
867          %22 = OpLabel
868          %21 = OpPtrAccessChain %_ptr_Function__struct_9 %20 %int_1
869                OpBranch %18
870          %24 = OpLabel
871                OpReturn
872                OpFunctionEnd
873 )";
874 
875   SinglePassRunAndMatch<FixStorageClass>(text, false);
876 }
TEST_F(FixStorageClassTest, SupportsU64Index)877 TEST_F(FixStorageClassTest, SupportsU64Index) {
878   const std::string text = R"(
879 ; CHECK: OpAccessChain %_ptr_Uniform_float
880                OpCapability Shader
881                OpMemoryModel Logical GLSL450
882                OpEntryPoint GLCompute %1 "testMain" %gl_LocalInvocationID
883                OpExecutionMode %1 LocalSize 8 8 1
884                OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
885                OpDecorate %8 DescriptorSet 0
886                OpDecorate %8 Binding 0
887                OpDecorate %_runtimearr_float ArrayStride 4
888                OpMemberDecorate %_struct_7 0 Offset 0
889                OpDecorate %_struct_7 BufferBlock
890       %ulong = OpTypeInt 64 0
891     %ulong_0 = OpConstant %ulong 0
892       %float = OpTypeFloat 32
893   %float_123 = OpConstant %float 123
894        %uint = OpTypeInt 32 0
895     %uint_10 = OpConstant %uint 10
896 %_runtimearr_float = OpTypeRuntimeArray %float
897   %_struct_7 = OpTypeStruct %_runtimearr_float
898 %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
899      %v3uint = OpTypeVector %uint 3
900 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
901        %void = OpTypeVoid
902          %30 = OpTypeFunction %void
903 %_ptr_Uniform_float = OpTypePointer Uniform %float
904           %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
905 %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
906           %1 = OpFunction %void None %30
907          %38 = OpLabel
908          %44 = OpLoad %v3uint %gl_LocalInvocationID
909          %59 = OpCompositeExtract %uint %44 0
910          %60 = OpAccessChain %_ptr_Uniform_float %8 %ulong_0 %59
911                OpStore %60 %float_123
912                OpReturn
913                OpFunctionEnd
914 )";
915 
916   SinglePassRunAndMatch<FixStorageClass>(text, false);
917 }
918 
919 }  // namespace
920 }  // namespace opt
921 }  // namespace spvtools
922