1 // Copyright (c) 2017 Google Inc.
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 "gmock/gmock.h"
18 #include "source/opt/value_number_table.h"
19 #include "test/opt/assembly_builder.h"
20 #include "test/opt/pass_fixture.h"
21 #include "test/opt/pass_utils.h"
22 
23 namespace spvtools {
24 namespace opt {
25 namespace {
26 
27 using ::testing::HasSubstr;
28 using ::testing::MatchesRegex;
29 using PrivateToLocalTest = PassTest<::testing::Test>;
30 
TEST_F(PrivateToLocalTest,ChangeToLocal)31 TEST_F(PrivateToLocalTest, ChangeToLocal) {
32   // Change the private variable to a local, and change the types accordingly.
33   const std::string text = R"(
34                OpCapability Shader
35           %1 = OpExtInstImport "GLSL.std.450"
36                OpMemoryModel Logical GLSL450
37                OpEntryPoint Fragment %2 "main"
38                OpExecutionMode %2 OriginUpperLeft
39                OpSource GLSL 430
40           %3 = OpTypeVoid
41           %4 = OpTypeFunction %3
42 ; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32
43           %5 = OpTypeFloat 32
44 ; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]]
45           %6 = OpTypePointer Private %5
46 ; CHECK-NOT: OpVariable [[.+]] Private
47           %8 = OpVariable %6 Private
48 ; CHECK: OpFunction
49           %2 = OpFunction %3 None %4
50 ; CHECK: OpLabel
51           %7 = OpLabel
52 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function
53 ; CHECK: OpLoad [[float]] [[newvar]]
54           %9 = OpLoad %5 %8
55                OpReturn
56                OpFunctionEnd
57   )";
58   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
59 }
60 
TEST_F(PrivateToLocalTest,ReuseExistingType)61 TEST_F(PrivateToLocalTest, ReuseExistingType) {
62   // Change the private variable to a local, and change the types accordingly.
63   const std::string text = R"(
64                OpCapability Shader
65           %1 = OpExtInstImport "GLSL.std.450"
66                OpMemoryModel Logical GLSL450
67                OpEntryPoint Fragment %2 "main"
68                OpExecutionMode %2 OriginUpperLeft
69                OpSource GLSL 430
70           %3 = OpTypeVoid
71           %4 = OpTypeFunction %3
72 ; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32
73           %5 = OpTypeFloat 32
74         %func_ptr = OpTypePointer Function %5
75 ; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]]
76 ; CHECK-NOT: [[%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]]
77           %6 = OpTypePointer Private %5
78 ; CHECK-NOT: OpVariable [[.+]] Private
79           %8 = OpVariable %6 Private
80 ; CHECK: OpFunction
81           %2 = OpFunction %3 None %4
82 ; CHECK: OpLabel
83           %7 = OpLabel
84 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function
85 ; CHECK: OpLoad [[float]] [[newvar]]
86           %9 = OpLoad %5 %8
87                OpReturn
88                OpFunctionEnd
89   )";
90   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
91 }
92 
TEST_F(PrivateToLocalTest,UpdateAccessChain)93 TEST_F(PrivateToLocalTest, UpdateAccessChain) {
94   // Change the private variable to a local, and change the AccessChain.
95   const std::string text = R"(
96                OpCapability Shader
97           %1 = OpExtInstImport "GLSL.std.450"
98                OpMemoryModel Logical GLSL450
99                OpEntryPoint Fragment %2 "main"
100                OpExecutionMode %2 OriginUpperLeft
101                OpSource GLSL 430
102        %uint = OpTypeInt 32 0
103      %uint_0 = OpConstant %uint 0
104        %void = OpTypeVoid
105           %6 = OpTypeFunction %void
106 ; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat
107       %float = OpTypeFloat 32
108 ; CHECK: [[struct:%[a-zA-Z_\d]+]] = OpTypeStruct
109   %_struct_8 = OpTypeStruct %float
110 %_ptr_Private_float = OpTypePointer Private %float
111 ; CHECK: [[new_struct_type:%[a-zA-Z_\d]+]] = OpTypePointer Function [[struct]]
112 ; CHECK: [[new_float_type:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]]
113 %_ptr_Private__struct_8 = OpTypePointer Private %_struct_8
114 ; CHECK-NOT: OpVariable [[.+]] Private
115          %11 = OpVariable %_ptr_Private__struct_8 Private
116 ; CHECK: OpFunction
117           %2 = OpFunction %void None %6
118 ; CHECK: OpLabel
119          %12 = OpLabel
120 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[new_struct_type]] Function
121 ; CHECK: [[member:%[a-zA-Z_\d]+]] = OpAccessChain [[new_float_type]] [[newvar]]
122          %13 = OpAccessChain %_ptr_Private_float %11 %uint_0
123 ; CHECK: OpLoad [[float]] [[member]]
124          %14 = OpLoad %float %13
125                OpReturn
126                OpFunctionEnd
127   )";
128   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
129 }
130 
TEST_F(PrivateToLocalTest,UseTexelPointer)131 TEST_F(PrivateToLocalTest, UseTexelPointer) {
132   // Change the private variable to a local, and change the OpImageTexelPointer.
133   const std::string text = R"(
134 OpCapability SampledBuffer
135                OpCapability StorageImageExtendedFormats
136                OpCapability ImageBuffer
137                OpCapability Shader
138           %1 = OpExtInstImport "GLSL.std.450"
139                OpMemoryModel Logical GLSL450
140                OpEntryPoint GLCompute %2 "min" %gl_GlobalInvocationID
141                OpExecutionMode %2 LocalSize 64 1 1
142                OpSource HLSL 600
143                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
144                OpDecorate %4 DescriptorSet 4
145                OpDecorate %4 Binding 70
146        %uint = OpTypeInt 32 0
147           %6 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
148 %_ptr_UniformConstant_6 = OpTypePointer UniformConstant %6
149 %_ptr_Private_6 = OpTypePointer Private %6
150        %void = OpTypeVoid
151          %10 = OpTypeFunction %void
152      %uint_0 = OpConstant %uint 0
153      %uint_1 = OpConstant %uint 1
154      %v3uint = OpTypeVector %uint 3
155 %_ptr_Input_v3uint = OpTypePointer Input %v3uint
156 %_ptr_Image_uint = OpTypePointer Image %uint
157           %4 = OpVariable %_ptr_UniformConstant_6 UniformConstant
158          %16 = OpVariable %_ptr_Private_6 Private
159 %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
160           %2 = OpFunction %void None %10
161          %17 = OpLabel
162 ; Make sure the variable was moved.
163 ; CHECK: OpFunction
164 ; CHECK-NEXT: OpLabel
165 ; CHECK-NEXT: OpVariable %_ptr_Function_6 Function
166          %18 = OpLoad %6 %4
167                OpStore %16 %18
168          %19 = OpImageTexelPointer %_ptr_Image_uint %16 %uint_0 %uint_0
169          %20 = OpAtomicIAdd %uint %19 %uint_1 %uint_0 %uint_1
170                OpReturn
171                OpFunctionEnd
172   )";
173   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
174 }
175 
TEST_F(PrivateToLocalTest,UsedInTwoFunctions)176 TEST_F(PrivateToLocalTest, UsedInTwoFunctions) {
177   // Should not change because it is used in multiple functions.
178   const std::string text = R"(
179                OpCapability Shader
180           %1 = OpExtInstImport "GLSL.std.450"
181                OpMemoryModel Logical GLSL450
182                OpEntryPoint Fragment %2 "main"
183                OpExecutionMode %2 OriginUpperLeft
184                OpSource GLSL 430
185           %3 = OpTypeVoid
186           %4 = OpTypeFunction %3
187           %5 = OpTypeFloat 32
188           %6 = OpTypePointer Private %5
189           %8 = OpVariable %6 Private
190           %2 = OpFunction %3 None %4
191           %7 = OpLabel
192           %9 = OpLoad %5 %8
193                OpReturn
194                OpFunctionEnd
195          %10 = OpFunction %3 None %4
196          %11 = OpLabel
197          %12 = OpLoad %5 %8
198                OpReturn
199                OpFunctionEnd
200   )";
201   auto result = SinglePassRunAndDisassemble<StrengthReductionPass>(
202       text, /* skip_nop = */ true, /* do_validation = */ false);
203   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
204 }
205 
TEST_F(PrivateToLocalTest,UsedInFunctionCall)206 TEST_F(PrivateToLocalTest, UsedInFunctionCall) {
207   // Should not change because it is used in a function call.  Changing the
208   // signature of the function would require cloning the function, which is not
209   // worth it.
210   const std::string text = R"(
211                OpCapability Shader
212           %1 = OpExtInstImport "GLSL.std.450"
213                OpMemoryModel Logical GLSL450
214                OpEntryPoint Fragment %2 "main"
215                OpExecutionMode %2 OriginUpperLeft
216                OpSource GLSL 430
217        %void = OpTypeVoid
218           %4 = OpTypeFunction %void
219       %float = OpTypeFloat 32
220 %_ptr_Private_float = OpTypePointer Private %float
221           %7 = OpTypeFunction %void %_ptr_Private_float
222           %8 = OpVariable %_ptr_Private_float Private
223           %2 = OpFunction %void None %4
224           %9 = OpLabel
225          %10 = OpFunctionCall %void %11 %8
226                OpReturn
227                OpFunctionEnd
228          %11 = OpFunction %void None %7
229          %12 = OpFunctionParameter %_ptr_Private_float
230          %13 = OpLabel
231          %14 = OpLoad %float %12
232                OpReturn
233                OpFunctionEnd
234   )";
235   auto result = SinglePassRunAndDisassemble<StrengthReductionPass>(
236       text, /* skip_nop = */ true, /* do_validation = */ false);
237   EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
238 }
239 
TEST_F(PrivateToLocalTest,CreatePointerToAmbiguousStruct1)240 TEST_F(PrivateToLocalTest, CreatePointerToAmbiguousStruct1) {
241   // Test that the correct pointer type is picked up.
242   const std::string text = R"(
243 ; CHECK: [[struct1:%[a-zA-Z_\d]+]] = OpTypeStruct
244 ; CHECK: [[struct2:%[a-zA-Z_\d]+]] = OpTypeStruct
245 ; CHECK: [[priv_ptr:%[\w]+]] = OpTypePointer Private [[struct1]]
246 ; CHECK: [[fuct_ptr2:%[\w]+]] = OpTypePointer Function [[struct2]]
247 ; CHECK: [[fuct_ptr1:%[\w]+]] = OpTypePointer Function [[struct1]]
248 ; CHECK: OpFunction
249 ; CHECK: OpLabel
250 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[fuct_ptr1]] Function
251 ; CHECK: OpLoad [[struct1]] [[newvar]]
252                OpCapability Shader
253           %1 = OpExtInstImport "GLSL.std.450"
254                OpMemoryModel Logical GLSL450
255                OpEntryPoint Fragment %2 "main"
256                OpExecutionMode %2 OriginUpperLeft
257                OpSource GLSL 430
258           %3 = OpTypeVoid
259           %4 = OpTypeFunction %3
260           %5 = OpTypeFloat 32
261     %struct1 = OpTypeStruct %5
262     %struct2 = OpTypeStruct %5
263           %6 = OpTypePointer Private %struct1
264   %func_ptr2 = OpTypePointer Function %struct2
265           %8 = OpVariable %6 Private
266           %2 = OpFunction %3 None %4
267           %7 = OpLabel
268           %9 = OpLoad %struct1 %8
269                OpReturn
270                OpFunctionEnd
271   )";
272   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
273 }
274 
TEST_F(PrivateToLocalTest,CreatePointerToAmbiguousStruct2)275 TEST_F(PrivateToLocalTest, CreatePointerToAmbiguousStruct2) {
276   // Test that the correct pointer type is picked up.
277   const std::string text = R"(
278 ; CHECK: [[struct1:%[a-zA-Z_\d]+]] = OpTypeStruct
279 ; CHECK: [[struct2:%[a-zA-Z_\d]+]] = OpTypeStruct
280 ; CHECK: [[priv_ptr:%[\w]+]] = OpTypePointer Private [[struct2]]
281 ; CHECK: [[fuct_ptr1:%[\w]+]] = OpTypePointer Function [[struct1]]
282 ; CHECK: [[fuct_ptr2:%[\w]+]] = OpTypePointer Function [[struct2]]
283 ; CHECK: OpFunction
284 ; CHECK: OpLabel
285 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[fuct_ptr2]] Function
286 ; CHECK: OpLoad [[struct2]] [[newvar]]
287                OpCapability Shader
288           %1 = OpExtInstImport "GLSL.std.450"
289                OpMemoryModel Logical GLSL450
290                OpEntryPoint Fragment %2 "main"
291                OpExecutionMode %2 OriginUpperLeft
292                OpSource GLSL 430
293           %3 = OpTypeVoid
294           %4 = OpTypeFunction %3
295           %5 = OpTypeFloat 32
296     %struct1 = OpTypeStruct %5
297     %struct2 = OpTypeStruct %5
298           %6 = OpTypePointer Private %struct2
299   %func_ptr2 = OpTypePointer Function %struct1
300           %8 = OpVariable %6 Private
301           %2 = OpFunction %3 None %4
302           %7 = OpLabel
303           %9 = OpLoad %struct2 %8
304                OpReturn
305                OpFunctionEnd
306   )";
307   SinglePassRunAndMatch<PrivateToLocalPass>(text, false);
308 }
309 
TEST_F(PrivateToLocalTest,SPV14RemoveFromInterface)310 TEST_F(PrivateToLocalTest, SPV14RemoveFromInterface) {
311   const std::string text = R"(
312 ; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv
313 ; CHECK: OpEntryPoint GLCompute %foo "foo" %in
314 ; CHECK: %priv = OpVariable {{%\w+}} Function
315 OpCapability Shader
316 OpMemoryModel Logical GLSL450
317 OpEntryPoint GLCompute %foo "foo" %in %priv
318 OpExecutionMode %foo LocalSize 1 1 1
319 OpName %foo "foo"
320 OpName %in "in"
321 OpName %priv "priv"
322 %void = OpTypeVoid
323 %int = OpTypeInt 32 0
324 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
325 %ptr_private_int = OpTypePointer Private %int
326 %in = OpVariable %ptr_ssbo_int StorageBuffer
327 %priv = OpVariable %ptr_private_int Private
328 %void_fn = OpTypeFunction %void
329 %foo = OpFunction %void None %void_fn
330 %entry = OpLabel
331 %ld = OpLoad %int %in
332 OpStore %priv %ld
333 OpReturn
334 OpFunctionEnd
335 )";
336 
337   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
338   SinglePassRunAndMatch<PrivateToLocalPass>(text, true);
339 }
340 
TEST_F(PrivateToLocalTest,SPV14RemoveFromInterfaceMultipleEntryPoints)341 TEST_F(PrivateToLocalTest, SPV14RemoveFromInterfaceMultipleEntryPoints) {
342   const std::string text = R"(
343 ; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv
344 ; CHECK-NOT: OpEntryPoint GLCompute %foo "bar" %in %priv
345 ; CHECK: OpEntryPoint GLCompute %foo "foo" %in
346 ; CHECK: OpEntryPoint GLCompute %foo "bar" %in
347 ; CHECK: %priv = OpVariable {{%\w+}} Function
348 OpCapability Shader
349 OpMemoryModel Logical GLSL450
350 OpEntryPoint GLCompute %foo "foo" %in %priv
351 OpEntryPoint GLCompute %foo "bar" %in %priv
352 OpExecutionMode %foo LocalSize 1 1 1
353 OpName %foo "foo"
354 OpName %in "in"
355 OpName %priv "priv"
356 %void = OpTypeVoid
357 %int = OpTypeInt 32 0
358 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
359 %ptr_private_int = OpTypePointer Private %int
360 %in = OpVariable %ptr_ssbo_int StorageBuffer
361 %priv = OpVariable %ptr_private_int Private
362 %void_fn = OpTypeFunction %void
363 %foo = OpFunction %void None %void_fn
364 %entry = OpLabel
365 %ld = OpLoad %int %in
366 OpStore %priv %ld
367 OpReturn
368 OpFunctionEnd
369 )";
370 
371   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
372   SinglePassRunAndMatch<PrivateToLocalPass>(text, true);
373 }
374 
TEST_F(PrivateToLocalTest,SPV14RemoveFromInterfaceMultipleVariables)375 TEST_F(PrivateToLocalTest, SPV14RemoveFromInterfaceMultipleVariables) {
376   const std::string text = R"(
377 ; CHECK-NOT: OpEntryPoint GLCompute %foo "foo" %in %priv1 %priv2
378 ; CHECK: OpEntryPoint GLCompute %foo "foo" %in
379 ; CHECK: %priv1 = OpVariable {{%\w+}} Function
380 ; CHECK: %priv2 = OpVariable {{%\w+}} Function
381 OpCapability Shader
382 OpMemoryModel Logical GLSL450
383 OpEntryPoint GLCompute %foo "foo" %in %priv1 %priv2
384 OpExecutionMode %foo LocalSize 1 1 1
385 OpName %foo "foo"
386 OpName %in "in"
387 OpName %priv1 "priv1"
388 OpName %priv2 "priv2"
389 %void = OpTypeVoid
390 %int = OpTypeInt 32 0
391 %ptr_ssbo_int = OpTypePointer StorageBuffer %int
392 %ptr_private_int = OpTypePointer Private %int
393 %in = OpVariable %ptr_ssbo_int StorageBuffer
394 %priv1 = OpVariable %ptr_private_int Private
395 %priv2 = OpVariable %ptr_private_int Private
396 %void_fn = OpTypeFunction %void
397 %foo = OpFunction %void None %void_fn
398 %entry = OpLabel
399 %1 = OpFunctionCall %void %bar1
400 %2 = OpFunctionCall %void %bar2
401 OpReturn
402 OpFunctionEnd
403 %bar1 = OpFunction %void None %void_fn
404 %3 = OpLabel
405 %ld1 = OpLoad %int %in
406 OpStore %priv1 %ld1
407 OpReturn
408 OpFunctionEnd
409 %bar2 = OpFunction %void None %void_fn
410 %4 = OpLabel
411 %ld2 = OpLoad %int %in
412 OpStore %priv2 %ld2
413 OpReturn
414 OpFunctionEnd
415 )";
416 
417   SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
418   SinglePassRunAndMatch<PrivateToLocalPass>(text, true);
419 }
420 
TEST_F(PrivateToLocalTest,IdBoundOverflow1)421 TEST_F(PrivateToLocalTest, IdBoundOverflow1) {
422   const std::string text = R"(
423                OpCapability Shader
424                OpMemoryModel Logical GLSL450
425                OpEntryPoint Fragment %4 "main"
426                OpExecutionMode %4 OriginLowerLeft
427                OpSource HLSL 84
428           %2 = OpTypeVoid
429           %3 = OpTypeFunction %2
430           %6 = OpTypeFloat 32
431           %7 = OpTypeVector %6 4
432           %8 = OpTypeStruct %7
433     %4194302 = OpTypeStruct %8 %8
434           %9 = OpTypeStruct %8 %8
435          %11 = OpTypePointer Private %7
436          %18 = OpTypeStruct %6 %9
437          %12 = OpVariable %11 Private
438           %4 = OpFunction %2 None %3
439           %5 = OpLabel
440          %13 = OpLoad %7 %12
441                OpReturn
442                OpFunctionEnd
443   )";
444 
445   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
446 
447   std::vector<Message> messages = {
448       {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
449   SetMessageConsumer(GetTestMessageConsumer(messages));
450   auto result = SinglePassRunToBinary<PrivateToLocalPass>(text, true);
451   EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
452 }
453 
TEST_F(PrivateToLocalTest,DebugPrivateToLocal)454 TEST_F(PrivateToLocalTest, DebugPrivateToLocal) {
455   // Debug instructions must not have any impact on changing the private
456   // variable to a local.
457   const std::string text = R"(
458                OpCapability Shader
459           %1 = OpExtInstImport "GLSL.std.450"
460          %10 = OpExtInstImport "OpenCL.DebugInfo.100"
461                OpMemoryModel Logical GLSL450
462                OpEntryPoint Fragment %2 "main"
463                OpExecutionMode %2 OriginUpperLeft
464          %11 = OpString "test"
465                OpSource GLSL 430
466          %13 = OpTypeInt 32 0
467          %14 = OpConstant %13 32
468           %3 = OpTypeVoid
469           %4 = OpTypeFunction %3
470 ; CHECK: [[float:%[a-zA-Z_\d]+]] = OpTypeFloat 32
471           %5 = OpTypeFloat 32
472 ; CHECK: [[newtype:%[a-zA-Z_\d]+]] = OpTypePointer Function [[float]]
473           %6 = OpTypePointer Private %5
474 ; CHECK-NOT: OpVariable [[.+]] Private
475           %8 = OpVariable %6 Private
476 
477          %12 = OpExtInst %3 %10 DebugTypeBasic %11 %14 Float
478          %15 = OpExtInst %3 %10 DebugSource %11
479          %16 = OpExtInst %3 %10 DebugCompilationUnit 1 4 %15 GLSL
480 ; CHECK-NOT: DebugGlobalVariable
481 ; CHECK: [[dbg_newvar:%[a-zA-Z_\d]+]] = OpExtInst {{%\w+}} {{%\w+}} DebugLocalVariable
482          %17 = OpExtInst %3 %10 DebugGlobalVariable %11 %12 %15 0 0 %16 %11 %8 FlagIsDefinition
483 
484 ; CHECK: OpFunction
485           %2 = OpFunction %3 None %4
486 ; CHECK: OpLabel
487           %7 = OpLabel
488 ; CHECK-NEXT: [[newvar:%[a-zA-Z_\d]+]] = OpVariable [[newtype]] Function
489 ; CHECK-NEXT: DebugDeclare [[dbg_newvar]] [[newvar]]
490 ; CHECK: OpLoad [[float]] [[newvar]]
491           %9 = OpLoad %5 %8
492                OpReturn
493                OpFunctionEnd
494   )";
495   SinglePassRunAndMatch<PrivateToLocalPass>(text, true);
496 }
497 
498 }  // namespace
499 }  // namespace opt
500 }  // namespace spvtools
501