• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016 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 <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 #include "source/opt/instruction.h"
22 #include "source/opt/ir_context.h"
23 #include "spirv-tools/libspirv.h"
24 #include "test/opt/pass_fixture.h"
25 #include "test/opt/pass_utils.h"
26 #include "test/unit_spirv.h"
27 
28 namespace spvtools {
29 namespace opt {
30 namespace {
31 
32 using ::testing::Eq;
33 using spvtest::MakeInstruction;
34 using DescriptorTypeTest = PassTest<::testing::Test>;
35 using OpaqueTypeTest = PassTest<::testing::Test>;
36 using GetBaseTest = PassTest<::testing::Test>;
37 using ValidBasePointerTest = PassTest<::testing::Test>;
38 using VulkanBufferTest = PassTest<::testing::Test>;
39 
TEST(InstructionTest,CreateTrivial)40 TEST(InstructionTest, CreateTrivial) {
41   Instruction empty;
42   EXPECT_EQ(SpvOpNop, empty.opcode());
43   EXPECT_EQ(0u, empty.type_id());
44   EXPECT_EQ(0u, empty.result_id());
45   EXPECT_EQ(0u, empty.NumOperands());
46   EXPECT_EQ(0u, empty.NumOperandWords());
47   EXPECT_EQ(0u, empty.NumInOperandWords());
48   EXPECT_EQ(empty.cend(), empty.cbegin());
49   EXPECT_EQ(empty.end(), empty.begin());
50 }
51 
TEST(InstructionTest,CreateWithOpcodeAndNoOperands)52 TEST(InstructionTest, CreateWithOpcodeAndNoOperands) {
53   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
54   Instruction inst(&context, SpvOpReturn);
55   EXPECT_EQ(SpvOpReturn, inst.opcode());
56   EXPECT_EQ(0u, inst.type_id());
57   EXPECT_EQ(0u, inst.result_id());
58   EXPECT_EQ(0u, inst.NumOperands());
59   EXPECT_EQ(0u, inst.NumOperandWords());
60   EXPECT_EQ(0u, inst.NumInOperandWords());
61   EXPECT_EQ(inst.cend(), inst.cbegin());
62   EXPECT_EQ(inst.end(), inst.begin());
63 }
64 
TEST(InstructionTest,OperandAsCString)65 TEST(InstructionTest, OperandAsCString) {
66   Operand::OperandData abcde{0x64636261, 0x65};
67   Operand operand(SPV_OPERAND_TYPE_LITERAL_STRING, std::move(abcde));
68   EXPECT_STREQ("abcde", operand.AsCString());
69 }
70 
TEST(InstructionTest,OperandAsString)71 TEST(InstructionTest, OperandAsString) {
72   Operand::OperandData abcde{0x64636261, 0x65};
73   Operand operand(SPV_OPERAND_TYPE_LITERAL_STRING, std::move(abcde));
74   EXPECT_EQ("abcde", operand.AsString());
75 }
76 
TEST(InstructionTest,OperandAsLiteralUint64_32bits)77 TEST(InstructionTest, OperandAsLiteralUint64_32bits) {
78   Operand::OperandData words{0x1234};
79   Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
80   EXPECT_EQ(uint64_t(0x1234), operand.AsLiteralUint64());
81 }
82 
TEST(InstructionTest,OperandAsLiteralUint64_64bits)83 TEST(InstructionTest, OperandAsLiteralUint64_64bits) {
84   Operand::OperandData words{0x1234, 0x89ab};
85   Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
86   EXPECT_EQ((uint64_t(0x89ab) << 32 | 0x1234), operand.AsLiteralUint64());
87 }
88 
89 // The words for an OpTypeInt for 32-bit signed integer resulting in Id 44.
90 uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(SpvOpTypeInt), 44,
91                                       32, 1};
92 // The operands that would be parsed from kSampleInstructionWords
93 spv_parsed_operand_t kSampleParsedOperands[] = {
94     {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0},
95     {2, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 32},
96     {3, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 1},
97 };
98 
99 // A valid parse of kSampleParsedOperands.
100 spv_parsed_instruction_t kSampleParsedInstruction = {kSampleInstructionWords,
101                                                      uint16_t(4),
102                                                      uint16_t(SpvOpTypeInt),
103                                                      SPV_EXT_INST_TYPE_NONE,
104                                                      0,   // type id
105                                                      44,  // result id
106                                                      kSampleParsedOperands,
107                                                      3};
108 
109 // The words for an OpAccessChain instruction.
110 uint32_t kSampleAccessChainInstructionWords[] = {
111     (7 << 16) | uint32_t(SpvOpAccessChain), 100, 101, 102, 103, 104, 105};
112 
113 // The operands that would be parsed from kSampleAccessChainInstructionWords.
114 spv_parsed_operand_t kSampleAccessChainOperands[] = {
115     {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0},
116     {2, 1, SPV_OPERAND_TYPE_TYPE_ID, SPV_NUMBER_NONE, 0},
117     {3, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
118     {4, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
119     {5, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
120     {6, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
121 };
122 
123 // A valid parse of kSampleAccessChainInstructionWords
124 spv_parsed_instruction_t kSampleAccessChainInstruction = {
125     kSampleAccessChainInstructionWords,
126     uint16_t(7),
127     uint16_t(SpvOpAccessChain),
128     SPV_EXT_INST_TYPE_NONE,
129     100,  // type id
130     101,  // result id
131     kSampleAccessChainOperands,
132     6};
133 
134 // The words for an OpControlBarrier instruction.
135 uint32_t kSampleControlBarrierInstructionWords[] = {
136     (4 << 16) | uint32_t(SpvOpControlBarrier), 100, 101, 102};
137 
138 // The operands that would be parsed from kSampleControlBarrierInstructionWords.
139 spv_parsed_operand_t kSampleControlBarrierOperands[] = {
140     {1, 1, SPV_OPERAND_TYPE_SCOPE_ID, SPV_NUMBER_NONE, 0},  // Execution
141     {2, 1, SPV_OPERAND_TYPE_SCOPE_ID, SPV_NUMBER_NONE, 0},  // Memory
142     {3, 1, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_NUMBER_NONE,
143      0},  // Semantics
144 };
145 
146 // A valid parse of kSampleControlBarrierInstructionWords
147 spv_parsed_instruction_t kSampleControlBarrierInstruction = {
148     kSampleControlBarrierInstructionWords,
149     uint16_t(4),
150     uint16_t(SpvOpControlBarrier),
151     SPV_EXT_INST_TYPE_NONE,
152     0,  // type id
153     0,  // result id
154     kSampleControlBarrierOperands,
155     3};
156 
TEST(InstructionTest,CreateWithOpcodeAndOperands)157 TEST(InstructionTest, CreateWithOpcodeAndOperands) {
158   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
159   Instruction inst(&context, kSampleParsedInstruction);
160   EXPECT_EQ(SpvOpTypeInt, inst.opcode());
161   EXPECT_EQ(0u, inst.type_id());
162   EXPECT_EQ(44u, inst.result_id());
163   EXPECT_EQ(3u, inst.NumOperands());
164   EXPECT_EQ(3u, inst.NumOperandWords());
165   EXPECT_EQ(2u, inst.NumInOperandWords());
166 }
167 
TEST(InstructionTest,GetOperand)168 TEST(InstructionTest, GetOperand) {
169   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
170   Instruction inst(&context, kSampleParsedInstruction);
171   EXPECT_THAT(inst.GetOperand(0).words, Eq(std::vector<uint32_t>{44}));
172   EXPECT_THAT(inst.GetOperand(1).words, Eq(std::vector<uint32_t>{32}));
173   EXPECT_THAT(inst.GetOperand(2).words, Eq(std::vector<uint32_t>{1}));
174 }
175 
TEST(InstructionTest,GetInOperand)176 TEST(InstructionTest, GetInOperand) {
177   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
178   Instruction inst(&context, kSampleParsedInstruction);
179   EXPECT_THAT(inst.GetInOperand(0).words, Eq(std::vector<uint32_t>{32}));
180   EXPECT_THAT(inst.GetInOperand(1).words, Eq(std::vector<uint32_t>{1}));
181 }
182 
TEST(InstructionTest,OperandConstIterators)183 TEST(InstructionTest, OperandConstIterators) {
184   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
185   Instruction inst(&context, kSampleParsedInstruction);
186   // Spot check iteration across operands.
187   auto cbegin = inst.cbegin();
188   auto cend = inst.cend();
189   EXPECT_NE(cend, inst.cbegin());
190 
191   auto citer = inst.cbegin();
192   for (int i = 0; i < 3; ++i, ++citer) {
193     const auto& operand = *citer;
194     EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type));
195     EXPECT_THAT(operand.words,
196                 Eq(std::vector<uint32_t>{kSampleInstructionWords[i + 1]}));
197     EXPECT_NE(cend, citer);
198   }
199   EXPECT_EQ(cend, citer);
200 
201   // Check that cbegin and cend have not changed.
202   EXPECT_EQ(cbegin, inst.cbegin());
203   EXPECT_EQ(cend, inst.cend());
204 
205   // Check arithmetic.
206   const Operand& operand2 = *(inst.cbegin() + 2);
207   EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type);
208 }
209 
TEST(InstructionTest,OperandIterators)210 TEST(InstructionTest, OperandIterators) {
211   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
212   Instruction inst(&context, kSampleParsedInstruction);
213   // Spot check iteration across operands, with mutable iterators.
214   auto begin = inst.begin();
215   auto end = inst.end();
216   EXPECT_NE(end, inst.begin());
217 
218   auto iter = inst.begin();
219   for (int i = 0; i < 3; ++i, ++iter) {
220     const auto& operand = *iter;
221     EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type));
222     EXPECT_THAT(operand.words,
223                 Eq(std::vector<uint32_t>{kSampleInstructionWords[i + 1]}));
224     EXPECT_NE(end, iter);
225   }
226   EXPECT_EQ(end, iter);
227 
228   // Check that begin and end have not changed.
229   EXPECT_EQ(begin, inst.begin());
230   EXPECT_EQ(end, inst.end());
231 
232   // Check arithmetic.
233   Operand& operand2 = *(inst.begin() + 2);
234   EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type);
235 
236   // Check mutation through an iterator.
237   operand2.type = SPV_OPERAND_TYPE_TYPE_ID;
238   EXPECT_EQ(SPV_OPERAND_TYPE_TYPE_ID, (*(inst.cbegin() + 2)).type);
239 }
240 
TEST(InstructionTest,ForInIdStandardIdTypes)241 TEST(InstructionTest, ForInIdStandardIdTypes) {
242   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
243   Instruction inst(&context, kSampleAccessChainInstruction);
244 
245   std::vector<uint32_t> ids;
246   inst.ForEachInId([&ids](const uint32_t* idptr) { ids.push_back(*idptr); });
247   EXPECT_THAT(ids, Eq(std::vector<uint32_t>{102, 103, 104, 105}));
248 
249   ids.clear();
250   inst.ForEachInId([&ids](uint32_t* idptr) { ids.push_back(*idptr); });
251   EXPECT_THAT(ids, Eq(std::vector<uint32_t>{102, 103, 104, 105}));
252 }
253 
TEST(InstructionTest,ForInIdNonstandardIdTypes)254 TEST(InstructionTest, ForInIdNonstandardIdTypes) {
255   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
256   Instruction inst(&context, kSampleControlBarrierInstruction);
257 
258   std::vector<uint32_t> ids;
259   inst.ForEachInId([&ids](const uint32_t* idptr) { ids.push_back(*idptr); });
260   EXPECT_THAT(ids, Eq(std::vector<uint32_t>{100, 101, 102}));
261 
262   ids.clear();
263   inst.ForEachInId([&ids](uint32_t* idptr) { ids.push_back(*idptr); });
264   EXPECT_THAT(ids, Eq(std::vector<uint32_t>{100, 101, 102}));
265 }
266 
TEST(InstructionTest,UniqueIds)267 TEST(InstructionTest, UniqueIds) {
268   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
269   Instruction inst1(&context);
270   Instruction inst2(&context);
271   EXPECT_NE(inst1.unique_id(), inst2.unique_id());
272 }
273 
TEST(InstructionTest,CloneUniqueIdDifferent)274 TEST(InstructionTest, CloneUniqueIdDifferent) {
275   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
276   Instruction inst(&context);
277   std::unique_ptr<Instruction> clone(inst.Clone(&context));
278   EXPECT_EQ(inst.context(), clone->context());
279   EXPECT_NE(inst.unique_id(), clone->unique_id());
280 }
281 
TEST(InstructionTest,CloneDifferentContext)282 TEST(InstructionTest, CloneDifferentContext) {
283   IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
284   IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
285   Instruction inst(&c1);
286   std::unique_ptr<Instruction> clone(inst.Clone(&c2));
287   EXPECT_EQ(&c1, inst.context());
288   EXPECT_EQ(&c2, clone->context());
289   EXPECT_NE(&c1, &c2);
290 }
291 
TEST(InstructionTest,CloneDifferentContextDifferentUniqueId)292 TEST(InstructionTest, CloneDifferentContextDifferentUniqueId) {
293   IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
294   IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
295   Instruction inst(&c1);
296   Instruction other(&c2);
297   std::unique_ptr<Instruction> clone(inst.Clone(&c2));
298   EXPECT_EQ(&c2, clone->context());
299   EXPECT_NE(other.unique_id(), clone->unique_id());
300 }
301 
TEST(InstructionTest,EqualsEqualsOperator)302 TEST(InstructionTest, EqualsEqualsOperator) {
303   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
304   Instruction i1(&context);
305   Instruction i2(&context);
306   std::unique_ptr<Instruction> clone(i1.Clone(&context));
307   EXPECT_TRUE(i1 == i1);
308   EXPECT_FALSE(i1 == i2);
309   EXPECT_FALSE(i1 == *clone);
310   EXPECT_FALSE(i2 == *clone);
311 }
312 
TEST(InstructionTest,LessThanOperator)313 TEST(InstructionTest, LessThanOperator) {
314   IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
315   Instruction i1(&context);
316   Instruction i2(&context);
317   std::unique_ptr<Instruction> clone(i1.Clone(&context));
318   EXPECT_TRUE(i1 < i2);
319   EXPECT_TRUE(i1 < *clone);
320   EXPECT_TRUE(i2 < *clone);
321 }
322 
TEST_F(DescriptorTypeTest,StorageImage)323 TEST_F(DescriptorTypeTest, StorageImage) {
324   const std::string text = R"(
325                OpCapability Shader
326           %1 = OpExtInstImport "GLSL.std.450"
327                OpMemoryModel Logical GLSL450
328                OpEntryPoint Fragment %2 "main"
329                OpExecutionMode %2 OriginUpperLeft
330                OpSource GLSL 430
331                OpName %3 "myStorageImage"
332                OpDecorate %3 DescriptorSet 0
333                OpDecorate %3 Binding 0
334           %4 = OpTypeVoid
335           %5 = OpTypeFunction %4
336           %6 = OpTypeFloat 32
337           %7 = OpTypeImage %6 2D 0 0 0 2 R32f
338           %8 = OpTypePointer UniformConstant %7
339           %3 = OpVariable %8 UniformConstant
340           %2 = OpFunction %4 None %5
341           %9 = OpLabel
342          %10 = OpCopyObject %8 %3
343                OpReturn
344                OpFunctionEnd
345 )";
346 
347   std::unique_ptr<IRContext> context =
348       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
349   Instruction* type = context->get_def_use_mgr()->GetDef(8);
350   EXPECT_TRUE(type->IsVulkanStorageImage());
351   EXPECT_FALSE(type->IsVulkanSampledImage());
352   EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
353   EXPECT_FALSE(type->IsVulkanStorageBuffer());
354   EXPECT_FALSE(type->IsVulkanUniformBuffer());
355 
356   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
357   EXPECT_FALSE(variable->IsReadOnlyPointer());
358 
359   Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
360   EXPECT_FALSE(object_copy->IsReadOnlyPointer());
361 }
362 
TEST_F(DescriptorTypeTest,SampledImage)363 TEST_F(DescriptorTypeTest, SampledImage) {
364   const std::string text = R"(
365                OpCapability Shader
366           %1 = OpExtInstImport "GLSL.std.450"
367                OpMemoryModel Logical GLSL450
368                OpEntryPoint Fragment %2 "main"
369                OpExecutionMode %2 OriginUpperLeft
370                OpSource GLSL 430
371                OpName %3 "myStorageImage"
372                OpDecorate %3 DescriptorSet 0
373                OpDecorate %3 Binding 0
374           %4 = OpTypeVoid
375           %5 = OpTypeFunction %4
376           %6 = OpTypeFloat 32
377           %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
378           %8 = OpTypePointer UniformConstant %7
379           %3 = OpVariable %8 UniformConstant
380           %2 = OpFunction %4 None %5
381           %9 = OpLabel
382          %10 = OpCopyObject %8 %3
383                OpReturn
384                OpFunctionEnd
385 )";
386 
387   std::unique_ptr<IRContext> context =
388       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
389   Instruction* type = context->get_def_use_mgr()->GetDef(8);
390   EXPECT_FALSE(type->IsVulkanStorageImage());
391   EXPECT_TRUE(type->IsVulkanSampledImage());
392   EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
393   EXPECT_FALSE(type->IsVulkanStorageBuffer());
394   EXPECT_FALSE(type->IsVulkanUniformBuffer());
395 
396   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
397   EXPECT_TRUE(variable->IsReadOnlyPointer());
398 
399   Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
400   EXPECT_TRUE(object_copy->IsReadOnlyPointer());
401 }
402 
TEST_F(DescriptorTypeTest,StorageTexelBuffer)403 TEST_F(DescriptorTypeTest, StorageTexelBuffer) {
404   const std::string text = R"(
405                OpCapability Shader
406           %1 = OpExtInstImport "GLSL.std.450"
407                OpMemoryModel Logical GLSL450
408                OpEntryPoint Fragment %2 "main"
409                OpExecutionMode %2 OriginUpperLeft
410                OpSource GLSL 430
411                OpName %3 "myStorageImage"
412                OpDecorate %3 DescriptorSet 0
413                OpDecorate %3 Binding 0
414           %4 = OpTypeVoid
415           %5 = OpTypeFunction %4
416           %6 = OpTypeFloat 32
417           %7 = OpTypeImage %6 Buffer 0 0 0 2 R32f
418           %8 = OpTypePointer UniformConstant %7
419           %3 = OpVariable %8 UniformConstant
420           %2 = OpFunction %4 None %5
421           %9 = OpLabel
422          %10 = OpCopyObject %8 %3
423                OpReturn
424                OpFunctionEnd
425 )";
426 
427   std::unique_ptr<IRContext> context =
428       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
429   Instruction* type = context->get_def_use_mgr()->GetDef(8);
430   EXPECT_FALSE(type->IsVulkanStorageImage());
431   EXPECT_FALSE(type->IsVulkanSampledImage());
432   EXPECT_TRUE(type->IsVulkanStorageTexelBuffer());
433   EXPECT_FALSE(type->IsVulkanStorageBuffer());
434   EXPECT_FALSE(type->IsVulkanUniformBuffer());
435 
436   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
437   EXPECT_FALSE(variable->IsReadOnlyPointer());
438 
439   Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
440   EXPECT_FALSE(object_copy->IsReadOnlyPointer());
441 }
442 
TEST_F(DescriptorTypeTest,StorageBuffer)443 TEST_F(DescriptorTypeTest, StorageBuffer) {
444   const std::string text = R"(
445                OpCapability Shader
446           %1 = OpExtInstImport "GLSL.std.450"
447                OpMemoryModel Logical GLSL450
448                OpEntryPoint Fragment %2 "main"
449                OpExecutionMode %2 OriginUpperLeft
450                OpSource GLSL 430
451                OpName %3 "myStorageImage"
452                OpDecorate %3 DescriptorSet 0
453                OpDecorate %3 Binding 0
454                OpDecorate %9 BufferBlock
455           %4 = OpTypeVoid
456           %5 = OpTypeFunction %4
457           %6 = OpTypeFloat 32
458           %7 = OpTypeVector %6 4
459           %8 = OpTypeRuntimeArray %7
460           %9 = OpTypeStruct %8
461          %10 = OpTypePointer Uniform %9
462           %3 = OpVariable %10 Uniform
463           %2 = OpFunction %4 None %5
464          %11 = OpLabel
465          %12 = OpCopyObject %8 %3
466                OpReturn
467                OpFunctionEnd
468 )";
469 
470   std::unique_ptr<IRContext> context =
471       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
472   Instruction* type = context->get_def_use_mgr()->GetDef(10);
473   EXPECT_FALSE(type->IsVulkanStorageImage());
474   EXPECT_FALSE(type->IsVulkanSampledImage());
475   EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
476   EXPECT_TRUE(type->IsVulkanStorageBuffer());
477   EXPECT_FALSE(type->IsVulkanUniformBuffer());
478 
479   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
480   EXPECT_FALSE(variable->IsReadOnlyPointer());
481 
482   Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
483   EXPECT_FALSE(object_copy->IsReadOnlyPointer());
484 }
485 
TEST_F(DescriptorTypeTest,UniformBuffer)486 TEST_F(DescriptorTypeTest, UniformBuffer) {
487   const std::string text = R"(
488                OpCapability Shader
489           %1 = OpExtInstImport "GLSL.std.450"
490                OpMemoryModel Logical GLSL450
491                OpEntryPoint Fragment %2 "main"
492                OpExecutionMode %2 OriginUpperLeft
493                OpSource GLSL 430
494                OpName %3 "myStorageImage"
495                OpDecorate %3 DescriptorSet 0
496                OpDecorate %3 Binding 0
497                OpDecorate %9 Block
498           %4 = OpTypeVoid
499           %5 = OpTypeFunction %4
500           %6 = OpTypeFloat 32
501           %7 = OpTypeVector %6 4
502           %8 = OpTypeRuntimeArray %7
503           %9 = OpTypeStruct %8
504          %10 = OpTypePointer Uniform %9
505           %3 = OpVariable %10 Uniform
506           %2 = OpFunction %4 None %5
507          %11 = OpLabel
508          %12 = OpCopyObject %10 %3
509                OpReturn
510                OpFunctionEnd
511 )";
512 
513   std::unique_ptr<IRContext> context =
514       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
515   Instruction* type = context->get_def_use_mgr()->GetDef(10);
516   EXPECT_FALSE(type->IsVulkanStorageImage());
517   EXPECT_FALSE(type->IsVulkanSampledImage());
518   EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
519   EXPECT_FALSE(type->IsVulkanStorageBuffer());
520   EXPECT_TRUE(type->IsVulkanUniformBuffer());
521 
522   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
523   EXPECT_TRUE(variable->IsReadOnlyPointer());
524 
525   Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
526   EXPECT_TRUE(object_copy->IsReadOnlyPointer());
527 }
528 
TEST_F(DescriptorTypeTest,NonWritableIsReadOnly)529 TEST_F(DescriptorTypeTest, NonWritableIsReadOnly) {
530   const std::string text = R"(
531                OpCapability Shader
532           %1 = OpExtInstImport "GLSL.std.450"
533                OpMemoryModel Logical GLSL450
534                OpEntryPoint Fragment %2 "main"
535                OpExecutionMode %2 OriginUpperLeft
536                OpSource GLSL 430
537                OpName %3 "myStorageImage"
538                OpDecorate %3 DescriptorSet 0
539                OpDecorate %3 Binding 0
540                OpDecorate %9 BufferBlock
541                OpDecorate %3 NonWritable
542           %4 = OpTypeVoid
543           %5 = OpTypeFunction %4
544           %6 = OpTypeFloat 32
545           %7 = OpTypeVector %6 4
546           %8 = OpTypeRuntimeArray %7
547           %9 = OpTypeStruct %8
548          %10 = OpTypePointer Uniform %9
549           %3 = OpVariable %10 Uniform
550           %2 = OpFunction %4 None %5
551          %11 = OpLabel
552          %12 = OpCopyObject %8 %3
553                OpReturn
554                OpFunctionEnd
555 )";
556 
557   std::unique_ptr<IRContext> context =
558       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
559   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
560   EXPECT_TRUE(variable->IsReadOnlyPointer());
561 
562   // This demonstrates that the check for whether a pointer is read-only is not
563   // precise: copying a NonWritable-decorated variable can yield a pointer that
564   // the check does not regard as read-only.
565   Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
566   EXPECT_FALSE(object_copy->IsReadOnlyPointer());
567 }
568 
TEST_F(DescriptorTypeTest,AccessChainIntoReadOnlyStructIsReadOnly)569 TEST_F(DescriptorTypeTest, AccessChainIntoReadOnlyStructIsReadOnly) {
570   const std::string text = R"(
571                OpCapability Shader
572           %1 = OpExtInstImport "GLSL.std.450"
573                OpMemoryModel Logical GLSL450
574                OpEntryPoint Fragment %2 "main"
575                OpExecutionMode %2 OriginUpperLeft
576                OpSource ESSL 320
577                OpMemberDecorate %3 0 Offset 0
578                OpMemberDecorate %3 1 Offset 4
579                OpDecorate %3 Block
580           %4 = OpTypeVoid
581           %5 = OpTypeFunction %4
582           %6 = OpTypeInt 32 1
583           %7 = OpTypePointer Function %6
584           %8 = OpTypeFloat 32
585           %3 = OpTypeStruct %6 %8
586           %9 = OpTypePointer PushConstant %3
587          %10 = OpVariable %9 PushConstant
588          %11 = OpConstant %6 0
589          %12 = OpTypePointer PushConstant %6
590          %13 = OpConstant %6 1
591          %14 = OpTypePointer PushConstant %8
592           %2 = OpFunction %4 None %5
593          %15 = OpLabel
594          %16 = OpVariable %7 Function
595          %17 = OpAccessChain %12 %10 %11
596          %18 = OpAccessChain %14 %10 %13
597                OpReturn
598                OpFunctionEnd
599 )";
600 
601   std::unique_ptr<IRContext> context =
602       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
603 
604   Instruction* push_constant_struct_variable =
605       context->get_def_use_mgr()->GetDef(10);
606   EXPECT_TRUE(push_constant_struct_variable->IsReadOnlyPointer());
607 
608   Instruction* push_constant_struct_field_0 =
609       context->get_def_use_mgr()->GetDef(17);
610   EXPECT_TRUE(push_constant_struct_field_0->IsReadOnlyPointer());
611 
612   Instruction* push_constant_struct_field_1 =
613       context->get_def_use_mgr()->GetDef(18);
614   EXPECT_TRUE(push_constant_struct_field_1->IsReadOnlyPointer());
615 }
616 
TEST_F(DescriptorTypeTest,ReadOnlyPointerParameter)617 TEST_F(DescriptorTypeTest, ReadOnlyPointerParameter) {
618   const std::string text = R"(
619                OpCapability Shader
620           %1 = OpExtInstImport "GLSL.std.450"
621                OpMemoryModel Logical GLSL450
622                OpEntryPoint Fragment %2 "main"
623                OpExecutionMode %2 OriginUpperLeft
624                OpSource ESSL 320
625                OpMemberDecorate %3 0 Offset 0
626                OpMemberDecorate %3 1 Offset 4
627                OpDecorate %3 Block
628           %4 = OpTypeVoid
629           %5 = OpTypeFunction %4
630           %6 = OpTypeInt 32 1
631           %7 = OpTypePointer Function %6
632           %8 = OpTypeFloat 32
633           %3 = OpTypeStruct %6 %8
634           %9 = OpTypePointer PushConstant %3
635          %10 = OpVariable %9 PushConstant
636          %11 = OpConstant %6 0
637          %12 = OpTypePointer PushConstant %6
638          %13 = OpConstant %6 1
639          %14 = OpTypePointer PushConstant %8
640          %15 = OpTypeFunction %4 %9
641           %2 = OpFunction %4 None %5
642          %16 = OpLabel
643          %17 = OpVariable %7 Function
644          %18 = OpAccessChain %12 %10 %11
645          %19 = OpAccessChain %14 %10 %13
646                OpReturn
647                OpFunctionEnd
648          %20 = OpFunction %4 None %15
649          %21 = OpFunctionParameter %9
650          %22 = OpLabel
651                OpReturn
652                OpFunctionEnd
653 )";
654 
655   std::unique_ptr<IRContext> context =
656       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
657 
658   Instruction* push_constant_struct_parameter =
659       context->get_def_use_mgr()->GetDef(21);
660   EXPECT_TRUE(push_constant_struct_parameter->IsReadOnlyPointer());
661 }
662 
TEST_F(OpaqueTypeTest,BaseOpaqueTypesShader)663 TEST_F(OpaqueTypeTest, BaseOpaqueTypesShader) {
664   const std::string text = R"(
665                OpCapability Shader
666           %1 = OpExtInstImport "GLSL.std.450"
667                OpMemoryModel Logical GLSL450
668                OpEntryPoint Fragment %2 "main"
669                OpExecutionMode %2 OriginUpperLeft
670                OpSource GLSL 430
671           %3 = OpTypeVoid
672           %4 = OpTypeFunction %3
673           %5 = OpTypeFloat 32
674           %6 = OpTypeImage %5 2D 1 0 0 1 Unknown
675           %7 = OpTypeSampler
676           %8 = OpTypeSampledImage %6
677           %9 = OpTypeRuntimeArray %5
678           %2 = OpFunction %3 None %4
679          %10 = OpLabel
680                OpReturn
681                OpFunctionEnd
682 )";
683 
684   std::unique_ptr<IRContext> context =
685       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
686   Instruction* image_type = context->get_def_use_mgr()->GetDef(6);
687   EXPECT_TRUE(image_type->IsOpaqueType());
688   Instruction* sampler_type = context->get_def_use_mgr()->GetDef(7);
689   EXPECT_TRUE(sampler_type->IsOpaqueType());
690   Instruction* sampled_image_type = context->get_def_use_mgr()->GetDef(8);
691   EXPECT_TRUE(sampled_image_type->IsOpaqueType());
692   Instruction* runtime_array_type = context->get_def_use_mgr()->GetDef(9);
693   EXPECT_TRUE(runtime_array_type->IsOpaqueType());
694   Instruction* float_type = context->get_def_use_mgr()->GetDef(5);
695   EXPECT_FALSE(float_type->IsOpaqueType());
696   Instruction* void_type = context->get_def_use_mgr()->GetDef(3);
697   EXPECT_FALSE(void_type->IsOpaqueType());
698 }
699 
TEST_F(OpaqueTypeTest,OpaqueStructTypes)700 TEST_F(OpaqueTypeTest, OpaqueStructTypes) {
701   const std::string text = R"(
702                OpCapability Shader
703           %1 = OpExtInstImport "GLSL.std.450"
704                OpMemoryModel Logical GLSL450
705                OpEntryPoint Fragment %2 "main"
706                OpExecutionMode %2 OriginUpperLeft
707                OpSource GLSL 430
708           %3 = OpTypeVoid
709           %4 = OpTypeFunction %3
710           %5 = OpTypeFloat 32
711           %6 = OpTypeRuntimeArray %5
712           %7 = OpTypeStruct %6 %6
713           %8 = OpTypeStruct %5 %6
714           %9 = OpTypeStruct %6 %5
715          %10 = OpTypeStruct %7
716           %2 = OpFunction %3 None %4
717          %11 = OpLabel
718                OpReturn
719                OpFunctionEnd
720 )";
721 
722   std::unique_ptr<IRContext> context =
723       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
724   for (int i = 7; i <= 10; i++) {
725     Instruction* type = context->get_def_use_mgr()->GetDef(i);
726     EXPECT_TRUE(type->IsOpaqueType());
727   }
728 }
729 
TEST_F(GetBaseTest,SampleImage)730 TEST_F(GetBaseTest, SampleImage) {
731   const std::string text = R"(
732                OpCapability Shader
733           %1 = OpExtInstImport "GLSL.std.450"
734                OpMemoryModel Logical GLSL450
735                OpEntryPoint Fragment %2 "main"
736                OpExecutionMode %2 OriginUpperLeft
737                OpSource GLSL 430
738                OpName %3 "myStorageImage"
739                OpDecorate %3 DescriptorSet 0
740                OpDecorate %3 Binding 0
741           %4 = OpTypeVoid
742           %5 = OpTypeFunction %4
743           %6 = OpTypeFloat 32
744           %7 = OpTypeVector %6 2
745           %8 = OpTypeVector %6 4
746           %9 = OpConstant %6 0
747          %10 = OpConstantComposite %7 %9 %9
748          %11 = OpTypeImage %6 2D 0 0 0 1 R32f
749          %12 = OpTypePointer UniformConstant %11
750           %3 = OpVariable %12 UniformConstant
751          %13 = OpTypeSampledImage %11
752          %14 = OpTypeSampler
753          %15 = OpTypePointer UniformConstant %14
754          %16 = OpVariable %15 UniformConstant
755           %2 = OpFunction %4 None %5
756          %17 = OpLabel
757          %18 = OpLoad %11 %3
758          %19 = OpLoad %14 %16
759          %20 = OpSampledImage %13 %18 %19
760          %21 = OpImageSampleImplicitLod %8 %20 %10
761                OpReturn
762                OpFunctionEnd
763 )";
764 
765   std::unique_ptr<IRContext> context =
766       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
767   Instruction* load = context->get_def_use_mgr()->GetDef(21);
768   Instruction* base = context->get_def_use_mgr()->GetDef(20);
769   EXPECT_TRUE(load->GetBaseAddress() == base);
770 }
771 
TEST_F(GetBaseTest,PtrAccessChain)772 TEST_F(GetBaseTest, PtrAccessChain) {
773   const std::string text = R"(
774                OpCapability VariablePointers
775                OpMemoryModel Logical GLSL450
776                OpEntryPoint Fragment %1 "PSMain" %2
777                OpExecutionMode %1 OriginUpperLeft
778        %void = OpTypeVoid
779           %4 = OpTypeFunction %void
780       %float = OpTypeFloat 32
781     %v4float = OpTypeVector %float 4
782         %int = OpTypeInt 32 8388353
783       %int_0 = OpConstant %int 0
784 %_ptr_Function_v4float = OpTypePointer Function %v4float
785           %2 = OpVariable %_ptr_Function_v4float Input
786           %1 = OpFunction %void None %4
787          %10 = OpLabel
788          %11 = OpPtrAccessChain %_ptr_Function_v4float %2 %int_0
789          %12 = OpLoad %v4float %11
790                OpReturn
791                OpFunctionEnd
792 )";
793 
794   std::unique_ptr<IRContext> context =
795       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
796   Instruction* load = context->get_def_use_mgr()->GetDef(12);
797   Instruction* base = context->get_def_use_mgr()->GetDef(2);
798   EXPECT_TRUE(load->GetBaseAddress() == base);
799 }
800 
TEST_F(GetBaseTest,ImageRead)801 TEST_F(GetBaseTest, ImageRead) {
802   const std::string text = R"(
803                OpCapability Shader
804           %1 = OpExtInstImport "GLSL.std.450"
805                OpMemoryModel Logical GLSL450
806                OpEntryPoint Fragment %2 "main"
807                OpExecutionMode %2 OriginUpperLeft
808                OpSource GLSL 430
809                OpName %3 "myStorageImage"
810                OpDecorate %3 DescriptorSet 0
811                OpDecorate %3 Binding 0
812           %4 = OpTypeVoid
813           %5 = OpTypeFunction %4
814           %6 = OpTypeInt 32 0
815           %7 = OpTypeVector %6 2
816           %8 = OpConstant %6 0
817           %9 = OpConstantComposite %7 %8 %8
818          %10 = OpTypeImage %6 2D 0 0 0 2 R32f
819          %11 = OpTypePointer UniformConstant %10
820           %3 = OpVariable %11 UniformConstant
821           %2 = OpFunction %4 None %5
822          %12 = OpLabel
823          %13 = OpLoad %10 %3
824          %14 = OpImageRead %6 %13 %9
825                OpReturn
826                OpFunctionEnd
827 )";
828 
829   std::unique_ptr<IRContext> context =
830       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
831   Instruction* load = context->get_def_use_mgr()->GetDef(14);
832   Instruction* base = context->get_def_use_mgr()->GetDef(13);
833   EXPECT_TRUE(load->GetBaseAddress() == base);
834 }
835 
TEST_F(ValidBasePointerTest,OpSelectBadNoVariablePointersStorageBuffer)836 TEST_F(ValidBasePointerTest, OpSelectBadNoVariablePointersStorageBuffer) {
837   const std::string text = R"(
838 OpCapability Shader
839 OpMemoryModel Logical GLSL450
840 OpEntryPoint Fragment %1 "func"
841 %2 = OpTypeVoid
842 %3 = OpTypeInt 32 0
843 %4 = OpTypePointer StorageBuffer %3
844 %5 = OpVariable %4 StorageBuffer
845 %6 = OpTypeFunction %2
846 %7 = OpTypeBool
847 %8 = OpConstantTrue %7
848 %1 = OpFunction %2 None %6
849 %9 = OpLabel
850 %10 = OpSelect %4 %8 %5 %5
851 OpReturn
852 OpFunctionEnd
853 )";
854 
855   std::unique_ptr<IRContext> context =
856       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
857   EXPECT_NE(context, nullptr);
858   Instruction* select = context->get_def_use_mgr()->GetDef(10);
859   EXPECT_NE(select, nullptr);
860   EXPECT_FALSE(select->IsValidBasePointer());
861 }
862 
TEST_F(ValidBasePointerTest,OpSelectBadNoVariablePointers)863 TEST_F(ValidBasePointerTest, OpSelectBadNoVariablePointers) {
864   const std::string text = R"(
865 OpCapability Shader
866 OpCapability VariablePointersStorageBuffer
867 OpMemoryModel Logical GLSL450
868 OpEntryPoint Fragment %1 "func"
869 %2 = OpTypeVoid
870 %3 = OpTypeInt 32 0
871 %4 = OpTypePointer Workgroup %3
872 %5 = OpVariable %4 Workgroup
873 %6 = OpTypeFunction %2
874 %7 = OpTypeBool
875 %8 = OpConstantTrue %7
876 %1 = OpFunction %2 None %6
877 %9 = OpLabel
878 %10 = OpSelect %4 %8 %5 %5
879 OpReturn
880 OpFunctionEnd
881 )";
882 
883   std::unique_ptr<IRContext> context =
884       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
885   EXPECT_NE(context, nullptr);
886   Instruction* select = context->get_def_use_mgr()->GetDef(10);
887   EXPECT_NE(select, nullptr);
888   EXPECT_FALSE(select->IsValidBasePointer());
889 }
890 
TEST_F(ValidBasePointerTest,OpSelectGoodVariablePointersStorageBuffer)891 TEST_F(ValidBasePointerTest, OpSelectGoodVariablePointersStorageBuffer) {
892   const std::string text = R"(
893 OpCapability Shader
894 OpCapability VariablePointersStorageBuffer
895 OpMemoryModel Logical GLSL450
896 OpEntryPoint Fragment %1 "func"
897 %2 = OpTypeVoid
898 %3 = OpTypeInt 32 0
899 %4 = OpTypePointer StorageBuffer %3
900 %5 = OpVariable %4 StorageBuffer
901 %6 = OpTypeFunction %2
902 %7 = OpTypeBool
903 %8 = OpConstantTrue %7
904 %1 = OpFunction %2 None %6
905 %9 = OpLabel
906 %10 = OpSelect %4 %8 %5 %5
907 OpReturn
908 OpFunctionEnd
909 )";
910 
911   std::unique_ptr<IRContext> context =
912       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
913   EXPECT_NE(context, nullptr);
914   Instruction* select = context->get_def_use_mgr()->GetDef(10);
915   EXPECT_NE(select, nullptr);
916   EXPECT_TRUE(select->IsValidBasePointer());
917 }
918 
TEST_F(ValidBasePointerTest,OpSelectGoodVariablePointers)919 TEST_F(ValidBasePointerTest, OpSelectGoodVariablePointers) {
920   const std::string text = R"(
921 OpCapability Shader
922 OpCapability VariablePointers
923 OpMemoryModel Logical GLSL450
924 OpEntryPoint Fragment %1 "func"
925 %2 = OpTypeVoid
926 %3 = OpTypeInt 32 0
927 %4 = OpTypePointer Workgroup %3
928 %5 = OpVariable %4 Workgroup
929 %6 = OpTypeFunction %2
930 %7 = OpTypeBool
931 %8 = OpConstantTrue %7
932 %1 = OpFunction %2 None %6
933 %9 = OpLabel
934 %10 = OpSelect %4 %8 %5 %5
935 OpReturn
936 OpFunctionEnd
937 )";
938 
939   std::unique_ptr<IRContext> context =
940       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
941   EXPECT_NE(context, nullptr);
942   Instruction* select = context->get_def_use_mgr()->GetDef(10);
943   EXPECT_NE(select, nullptr);
944   EXPECT_TRUE(select->IsValidBasePointer());
945 }
946 
TEST_F(ValidBasePointerTest,OpConstantNullBadNoVariablePointersStorageBuffer)947 TEST_F(ValidBasePointerTest, OpConstantNullBadNoVariablePointersStorageBuffer) {
948   const std::string text = R"(
949 OpCapability Shader
950 OpMemoryModel Logical GLSL450
951 OpEntryPoint Fragment %1 "func"
952 %2 = OpTypeVoid
953 %3 = OpTypeInt 32 0
954 %4 = OpTypePointer StorageBuffer %3
955 %5 = OpConstantNull %4
956 %6 = OpTypeFunction %2
957 %1 = OpFunction %2 None %6
958 %7 = OpLabel
959 OpReturn
960 OpFunctionEnd
961 )";
962 
963   std::unique_ptr<IRContext> context =
964       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
965   EXPECT_NE(context, nullptr);
966   Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
967   EXPECT_NE(null_inst, nullptr);
968   EXPECT_FALSE(null_inst->IsValidBasePointer());
969 }
970 
TEST_F(ValidBasePointerTest,OpConstantNullBadNoVariablePointers)971 TEST_F(ValidBasePointerTest, OpConstantNullBadNoVariablePointers) {
972   const std::string text = R"(
973 OpCapability Shader
974 OpCapability VariablePointersStorageBuffer
975 OpMemoryModel Logical GLSL450
976 OpEntryPoint Fragment %1 "func"
977 %2 = OpTypeVoid
978 %3 = OpTypeInt 32 0
979 %4 = OpTypePointer Workgroup %3
980 %5 = OpConstantNull %4
981 %6 = OpTypeFunction %2
982 %1 = OpFunction %2 None %6
983 %7 = OpLabel
984 OpReturn
985 OpFunctionEnd
986 )";
987 
988   std::unique_ptr<IRContext> context =
989       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
990   EXPECT_NE(context, nullptr);
991   Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
992   EXPECT_NE(null_inst, nullptr);
993   EXPECT_FALSE(null_inst->IsValidBasePointer());
994 }
995 
TEST_F(ValidBasePointerTest,OpConstantNullGoodVariablePointersStorageBuffer)996 TEST_F(ValidBasePointerTest, OpConstantNullGoodVariablePointersStorageBuffer) {
997   const std::string text = R"(
998 OpCapability Shader
999 OpCapability VariablePointersStorageBuffer
1000 OpMemoryModel Logical GLSL450
1001 OpEntryPoint Fragment %1 "func"
1002 %2 = OpTypeVoid
1003 %3 = OpTypeInt 32 0
1004 %4 = OpTypePointer StorageBuffer %3
1005 %5 = OpConstantNull %4
1006 %6 = OpTypeFunction %2
1007 %1 = OpFunction %2 None %6
1008 %9 = OpLabel
1009 OpReturn
1010 OpFunctionEnd
1011 )";
1012 
1013   std::unique_ptr<IRContext> context =
1014       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1015   EXPECT_NE(context, nullptr);
1016   Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
1017   EXPECT_NE(null_inst, nullptr);
1018   EXPECT_TRUE(null_inst->IsValidBasePointer());
1019 }
1020 
TEST_F(ValidBasePointerTest,OpConstantNullGoodVariablePointers)1021 TEST_F(ValidBasePointerTest, OpConstantNullGoodVariablePointers) {
1022   const std::string text = R"(
1023 OpCapability Shader
1024 OpCapability VariablePointers
1025 OpMemoryModel Logical GLSL450
1026 OpEntryPoint Fragment %1 "func"
1027 %2 = OpTypeVoid
1028 %3 = OpTypeInt 32 0
1029 %4 = OpTypePointer Workgroup %3
1030 %5 = OpConstantNull %4
1031 %6 = OpTypeFunction %2
1032 %1 = OpFunction %2 None %6
1033 %7 = OpLabel
1034 OpReturn
1035 OpFunctionEnd
1036 )";
1037 
1038   std::unique_ptr<IRContext> context =
1039       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1040   EXPECT_NE(context, nullptr);
1041   Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
1042   EXPECT_NE(null_inst, nullptr);
1043   EXPECT_TRUE(null_inst->IsValidBasePointer());
1044 }
1045 
TEST_F(ValidBasePointerTest,OpPhiBadNoVariablePointersStorageBuffer)1046 TEST_F(ValidBasePointerTest, OpPhiBadNoVariablePointersStorageBuffer) {
1047   const std::string text = R"(
1048 OpCapability Shader
1049 OpMemoryModel Logical GLSL450
1050 OpEntryPoint Fragment %1 "func"
1051 %2 = OpTypeVoid
1052 %3 = OpTypeInt 32 0
1053 %4 = OpTypePointer StorageBuffer %3
1054 %5 = OpVariable %4 StorageBuffer
1055 %6 = OpTypeFunction %2
1056 %1 = OpFunction %2 None %6
1057 %7 = OpLabel
1058 OpBranch %8
1059 %8 = OpLabel
1060 %9 = OpPhi %4 %5 %7
1061 OpReturn
1062 OpFunctionEnd
1063 )";
1064 
1065   std::unique_ptr<IRContext> context =
1066       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1067   EXPECT_NE(context, nullptr);
1068   Instruction* phi = context->get_def_use_mgr()->GetDef(9);
1069   EXPECT_NE(phi, nullptr);
1070   EXPECT_FALSE(phi->IsValidBasePointer());
1071 }
1072 
TEST_F(ValidBasePointerTest,OpPhiBadNoVariablePointers)1073 TEST_F(ValidBasePointerTest, OpPhiBadNoVariablePointers) {
1074   const std::string text = R"(
1075 OpCapability Shader
1076 OpCapability VariablePointersStorageBuffer
1077 OpMemoryModel Logical GLSL450
1078 OpEntryPoint Fragment %1 "func"
1079 %2 = OpTypeVoid
1080 %3 = OpTypeInt 32 0
1081 %4 = OpTypePointer Workgroup %3
1082 %5 = OpVariable %4 Workgroup
1083 %6 = OpTypeFunction %2
1084 %1 = OpFunction %2 None %6
1085 %7 = OpLabel
1086 OpBranch %8
1087 %8 = OpLabel
1088 %9 = OpPhi %4 %5 %7
1089 OpReturn
1090 OpFunctionEnd
1091 )";
1092 
1093   std::unique_ptr<IRContext> context =
1094       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1095   EXPECT_NE(context, nullptr);
1096   Instruction* phi = context->get_def_use_mgr()->GetDef(9);
1097   EXPECT_NE(phi, nullptr);
1098   EXPECT_FALSE(phi->IsValidBasePointer());
1099 }
1100 
TEST_F(ValidBasePointerTest,OpPhiGoodVariablePointersStorageBuffer)1101 TEST_F(ValidBasePointerTest, OpPhiGoodVariablePointersStorageBuffer) {
1102   const std::string text = R"(
1103 OpCapability Shader
1104 OpCapability VariablePointersStorageBuffer
1105 OpMemoryModel Logical GLSL450
1106 OpEntryPoint Fragment %1 "func"
1107 %2 = OpTypeVoid
1108 %3 = OpTypeInt 32 0
1109 %4 = OpTypePointer StorageBuffer %3
1110 %5 = OpVariable %4 StorageBuffer
1111 %6 = OpTypeFunction %2
1112 %1 = OpFunction %2 None %6
1113 %7 = OpLabel
1114 OpBranch %8
1115 %8 = OpLabel
1116 %9 = OpPhi %4 %5 %7
1117 OpReturn
1118 OpFunctionEnd
1119 )";
1120 
1121   std::unique_ptr<IRContext> context =
1122       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1123   EXPECT_NE(context, nullptr);
1124   Instruction* phi = context->get_def_use_mgr()->GetDef(9);
1125   EXPECT_NE(phi, nullptr);
1126   EXPECT_TRUE(phi->IsValidBasePointer());
1127 }
1128 
TEST_F(ValidBasePointerTest,OpPhiGoodVariablePointers)1129 TEST_F(ValidBasePointerTest, OpPhiGoodVariablePointers) {
1130   const std::string text = R"(
1131 OpCapability Shader
1132 OpCapability VariablePointers
1133 OpMemoryModel Logical GLSL450
1134 OpEntryPoint Fragment %1 "func"
1135 %2 = OpTypeVoid
1136 %3 = OpTypeInt 32 0
1137 %4 = OpTypePointer Workgroup %3
1138 %5 = OpVariable %4 Workgroup
1139 %6 = OpTypeFunction %2
1140 %1 = OpFunction %2 None %6
1141 %7 = OpLabel
1142 OpBranch %8
1143 %8 = OpLabel
1144 %9 = OpPhi %4 %5 %7
1145 OpReturn
1146 OpFunctionEnd
1147 )";
1148 
1149   std::unique_ptr<IRContext> context =
1150       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1151   EXPECT_NE(context, nullptr);
1152   Instruction* phi = context->get_def_use_mgr()->GetDef(9);
1153   EXPECT_NE(phi, nullptr);
1154   EXPECT_TRUE(phi->IsValidBasePointer());
1155 }
1156 
TEST_F(ValidBasePointerTest,OpFunctionCallBadNoVariablePointersStorageBuffer)1157 TEST_F(ValidBasePointerTest, OpFunctionCallBadNoVariablePointersStorageBuffer) {
1158   const std::string text = R"(
1159 OpCapability Shader
1160 OpMemoryModel Logical GLSL450
1161 OpEntryPoint Fragment %1 "func"
1162 %2 = OpTypeVoid
1163 %3 = OpTypeInt 32 0
1164 %4 = OpTypePointer StorageBuffer %3
1165 %5 = OpConstantNull %4
1166 %6 = OpTypeFunction %2
1167 %7 = OpTypeFunction %4
1168 %1 = OpFunction %2 None %6
1169 %8 = OpLabel
1170 %9 = OpFunctionCall %4 %10
1171 OpReturn
1172 OpFunctionEnd
1173 %10 = OpFunction %4 None %7
1174 %11 = OpLabel
1175 OpReturnValue %5
1176 OpFunctionEnd
1177 )";
1178 
1179   std::unique_ptr<IRContext> context =
1180       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1181   EXPECT_NE(context, nullptr);
1182   Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
1183   EXPECT_NE(null_inst, nullptr);
1184   EXPECT_FALSE(null_inst->IsValidBasePointer());
1185 }
1186 
TEST_F(ValidBasePointerTest,OpFunctionCallBadNoVariablePointers)1187 TEST_F(ValidBasePointerTest, OpFunctionCallBadNoVariablePointers) {
1188   const std::string text = R"(
1189 OpCapability Shader
1190 OpCapability VariablePointersStorageBuffer
1191 OpMemoryModel Logical GLSL450
1192 OpEntryPoint Fragment %1 "func"
1193 %2 = OpTypeVoid
1194 %3 = OpTypeInt 32 0
1195 %4 = OpTypePointer Workgroup %3
1196 %5 = OpConstantNull %4
1197 %6 = OpTypeFunction %2
1198 %7 = OpTypeFunction %4
1199 %1 = OpFunction %2 None %6
1200 %8 = OpLabel
1201 %9 = OpFunctionCall %4 %10
1202 OpReturn
1203 OpFunctionEnd
1204 %10 = OpFunction %4 None %7
1205 %11 = OpLabel
1206 OpReturnValue %5
1207 OpFunctionEnd
1208 )";
1209 
1210   std::unique_ptr<IRContext> context =
1211       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1212   EXPECT_NE(context, nullptr);
1213   Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
1214   EXPECT_NE(null_inst, nullptr);
1215   EXPECT_FALSE(null_inst->IsValidBasePointer());
1216 }
1217 
TEST_F(ValidBasePointerTest,OpFunctionCallGoodVariablePointersStorageBuffer)1218 TEST_F(ValidBasePointerTest, OpFunctionCallGoodVariablePointersStorageBuffer) {
1219   const std::string text = R"(
1220 OpCapability Shader
1221 OpCapability VariablePointersStorageBuffer
1222 OpMemoryModel Logical GLSL450
1223 OpEntryPoint Fragment %1 "func"
1224 %2 = OpTypeVoid
1225 %3 = OpTypeInt 32 0
1226 %4 = OpTypePointer StorageBuffer %3
1227 %5 = OpConstantNull %4
1228 %6 = OpTypeFunction %2
1229 %7 = OpTypeFunction %4
1230 %1 = OpFunction %2 None %6
1231 %8 = OpLabel
1232 %9 = OpFunctionCall %4 %10
1233 OpReturn
1234 OpFunctionEnd
1235 %10 = OpFunction %4 None %7
1236 %11 = OpLabel
1237 OpReturnValue %5
1238 OpFunctionEnd
1239 )";
1240 
1241   std::unique_ptr<IRContext> context =
1242       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1243   EXPECT_NE(context, nullptr);
1244   Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
1245   EXPECT_NE(null_inst, nullptr);
1246   EXPECT_TRUE(null_inst->IsValidBasePointer());
1247 }
1248 
TEST_F(ValidBasePointerTest,OpFunctionCallGoodVariablePointers)1249 TEST_F(ValidBasePointerTest, OpFunctionCallGoodVariablePointers) {
1250   const std::string text = R"(
1251 OpCapability Shader
1252 OpCapability VariablePointers
1253 OpMemoryModel Logical GLSL450
1254 OpEntryPoint Fragment %1 "func"
1255 %2 = OpTypeVoid
1256 %3 = OpTypeInt 32 0
1257 %4 = OpTypePointer Workgroup %3
1258 %5 = OpConstantNull %4
1259 %6 = OpTypeFunction %2
1260 %7 = OpTypeFunction %4
1261 %1 = OpFunction %2 None %6
1262 %8 = OpLabel
1263 %9 = OpFunctionCall %4 %10
1264 OpReturn
1265 OpFunctionEnd
1266 %10 = OpFunction %4 None %7
1267 %11 = OpLabel
1268 OpReturnValue %5
1269 OpFunctionEnd
1270 )";
1271 
1272   std::unique_ptr<IRContext> context =
1273       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1274   EXPECT_NE(context, nullptr);
1275   Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
1276   EXPECT_NE(null_inst, nullptr);
1277   EXPECT_TRUE(null_inst->IsValidBasePointer());
1278 }
1279 
TEST_F(VulkanBufferTest,VulkanStorageBuffer)1280 TEST_F(VulkanBufferTest, VulkanStorageBuffer) {
1281   const std::string text = R"(
1282 OpCapability Shader
1283 OpCapability RuntimeDescriptorArray
1284 OpMemoryModel Logical GLSL450
1285 OpEntryPoint GLCompute %1 "main"
1286 OpExecutionMode %1 LocalSize 1 1 1
1287 OpDecorate %2 Block
1288 OpMemberDecorate %2 0 Offset 0
1289 OpDecorate %3 BufferBlock
1290 OpMemberDecorate %3 0 Offset 0
1291 %4 = OpTypeVoid
1292 %5 = OpTypeInt 32 0
1293 %2 = OpTypeStruct %5
1294 %3 = OpTypeStruct %5
1295 
1296 %6 = OpTypePointer StorageBuffer %2
1297 %7 = OpTypePointer Uniform %2
1298 %8 = OpTypePointer Uniform %3
1299 
1300 %9 = OpConstant %5 1
1301 %10 = OpTypeArray %2 %9
1302 %11 = OpTypeArray %3 %9
1303 %12 = OpTypePointer StorageBuffer %10
1304 %13 = OpTypePointer Uniform %10
1305 %14 = OpTypePointer Uniform %11
1306 
1307 %15 = OpTypeRuntimeArray %2
1308 %16 = OpTypeRuntimeArray %3
1309 %17 = OpTypePointer StorageBuffer %15
1310 %18 = OpTypePointer Uniform %15
1311 %19 = OpTypePointer Uniform %16
1312 
1313 %50 = OpTypeFunction %4
1314 %1 = OpFunction %4 None %50
1315 %51 = OpLabel
1316 OpReturn
1317 OpFunctionEnd
1318 )";
1319 
1320   std::unique_ptr<IRContext> context =
1321       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1322   EXPECT_NE(context, nullptr);
1323 
1324   // Standard SSBO and UBO
1325   Instruction* inst = context->get_def_use_mgr()->GetDef(6);
1326   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1327   inst = context->get_def_use_mgr()->GetDef(7);
1328   EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
1329   inst = context->get_def_use_mgr()->GetDef(8);
1330   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1331 
1332   // Arrayed SSBO and UBO
1333   inst = context->get_def_use_mgr()->GetDef(12);
1334   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1335   inst = context->get_def_use_mgr()->GetDef(13);
1336   EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
1337   inst = context->get_def_use_mgr()->GetDef(14);
1338   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1339 
1340   // Runtime arrayed SSBO and UBO
1341   inst = context->get_def_use_mgr()->GetDef(17);
1342   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1343   inst = context->get_def_use_mgr()->GetDef(18);
1344   EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
1345   inst = context->get_def_use_mgr()->GetDef(19);
1346   EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
1347 }
1348 
TEST_F(VulkanBufferTest,VulkanUniformBuffer)1349 TEST_F(VulkanBufferTest, VulkanUniformBuffer) {
1350   const std::string text = R"(
1351 OpCapability Shader
1352 OpCapability RuntimeDescriptorArray
1353 OpMemoryModel Logical GLSL450
1354 OpEntryPoint GLCompute %1 "main"
1355 OpExecutionMode %1 LocalSize 1 1 1
1356 OpDecorate %2 Block
1357 OpMemberDecorate %2 0 Offset 0
1358 OpDecorate %3 BufferBlock
1359 OpMemberDecorate %3 0 Offset 0
1360 %4 = OpTypeVoid
1361 %5 = OpTypeInt 32 0
1362 %2 = OpTypeStruct %5
1363 %3 = OpTypeStruct %5
1364 
1365 %6 = OpTypePointer StorageBuffer %2
1366 %7 = OpTypePointer Uniform %2
1367 %8 = OpTypePointer Uniform %3
1368 
1369 %9 = OpConstant %5 1
1370 %10 = OpTypeArray %2 %9
1371 %11 = OpTypeArray %3 %9
1372 %12 = OpTypePointer StorageBuffer %10
1373 %13 = OpTypePointer Uniform %10
1374 %14 = OpTypePointer Uniform %11
1375 
1376 %15 = OpTypeRuntimeArray %2
1377 %16 = OpTypeRuntimeArray %3
1378 %17 = OpTypePointer StorageBuffer %15
1379 %18 = OpTypePointer Uniform %15
1380 %19 = OpTypePointer Uniform %16
1381 
1382 %50 = OpTypeFunction %4
1383 %1 = OpFunction %4 None %50
1384 %51 = OpLabel
1385 OpReturn
1386 OpFunctionEnd
1387 )";
1388 
1389   std::unique_ptr<IRContext> context =
1390       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1391   EXPECT_NE(context, nullptr);
1392 
1393   // Standard SSBO and UBO
1394   Instruction* inst = context->get_def_use_mgr()->GetDef(6);
1395   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1396   inst = context->get_def_use_mgr()->GetDef(7);
1397   EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
1398   inst = context->get_def_use_mgr()->GetDef(8);
1399   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1400 
1401   // Arrayed SSBO and UBO
1402   inst = context->get_def_use_mgr()->GetDef(12);
1403   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1404   inst = context->get_def_use_mgr()->GetDef(13);
1405   EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
1406   inst = context->get_def_use_mgr()->GetDef(14);
1407   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1408 
1409   // Runtime arrayed SSBO and UBO
1410   inst = context->get_def_use_mgr()->GetDef(17);
1411   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1412   inst = context->get_def_use_mgr()->GetDef(18);
1413   EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
1414   inst = context->get_def_use_mgr()->GetDef(19);
1415   EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
1416 }
1417 
TEST_F(VulkanBufferTest,ImageQueries)1418 TEST_F(VulkanBufferTest, ImageQueries) {
1419   const std::string text = R"(
1420 OpCapability Shader
1421 OpCapability ImageBuffer
1422 OpCapability RuntimeDescriptorArray
1423 OpMemoryModel Logical GLSL450
1424 OpEntryPoint GLCompute %1 "main"
1425 OpExecutionMode %1 LocalSize 1 1 1
1426 %2 = OpTypeVoid
1427 %3 = OpTypeFloat 32
1428 
1429 %4 = OpTypeImage %3 Buffer 0 0 0 1 Rgba32f
1430 %5 = OpTypeImage %3 Buffer 0 0 0 2 Rgba32f
1431 %6 = OpTypeImage %3 2D 0 0 0 1 Rgba32f
1432 %7 = OpTypeImage %3 2D 0 0 0 2 Rgba32f
1433 
1434 %8 = OpTypePointer UniformConstant %4
1435 %9 = OpTypePointer UniformConstant %5
1436 %10 = OpTypePointer UniformConstant %6
1437 %11 = OpTypePointer UniformConstant %7
1438 
1439 %12 = OpTypeInt 32 0
1440 %13 = OpConstant %12 1
1441 %14 = OpTypeArray %4 %13
1442 %15 = OpTypeArray %5 %13
1443 %16 = OpTypeArray %6 %13
1444 %17 = OpTypeArray %7 %13
1445 %18 = OpTypePointer UniformConstant %14
1446 %19 = OpTypePointer UniformConstant %15
1447 %20 = OpTypePointer UniformConstant %16
1448 %21 = OpTypePointer UniformConstant %17
1449 
1450 %22 = OpTypeRuntimeArray %4
1451 %23 = OpTypeRuntimeArray %5
1452 %24 = OpTypeRuntimeArray %6
1453 %25 = OpTypeRuntimeArray %7
1454 %26 = OpTypePointer UniformConstant %22
1455 %27 = OpTypePointer UniformConstant %23
1456 %28 = OpTypePointer UniformConstant %24
1457 %29 = OpTypePointer UniformConstant %25
1458 
1459 %50 = OpTypeFunction %4
1460 %1 = OpFunction %4 None %50
1461 %51 = OpLabel
1462 OpReturn
1463 OpFunctionEnd
1464 )";
1465 
1466   std::unique_ptr<IRContext> context =
1467       BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
1468   EXPECT_NE(context, nullptr);
1469 
1470   // Bare pointers
1471   Instruction* inst = context->get_def_use_mgr()->GetDef(8);
1472   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1473   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1474   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1475 
1476   inst = context->get_def_use_mgr()->GetDef(9);
1477   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1478   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1479   EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
1480 
1481   inst = context->get_def_use_mgr()->GetDef(10);
1482   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1483   EXPECT_EQ(true, inst->IsVulkanSampledImage());
1484   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1485 
1486   inst = context->get_def_use_mgr()->GetDef(11);
1487   EXPECT_EQ(true, inst->IsVulkanStorageImage());
1488   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1489   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1490 
1491   // Array pointers
1492   inst = context->get_def_use_mgr()->GetDef(18);
1493   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1494   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1495   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1496 
1497   inst = context->get_def_use_mgr()->GetDef(19);
1498   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1499   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1500   EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
1501 
1502   inst = context->get_def_use_mgr()->GetDef(20);
1503   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1504   EXPECT_EQ(true, inst->IsVulkanSampledImage());
1505   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1506 
1507   inst = context->get_def_use_mgr()->GetDef(21);
1508   EXPECT_EQ(true, inst->IsVulkanStorageImage());
1509   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1510   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1511 
1512   // Runtime array pointers
1513   inst = context->get_def_use_mgr()->GetDef(26);
1514   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1515   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1516   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1517 
1518   inst = context->get_def_use_mgr()->GetDef(27);
1519   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1520   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1521   EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
1522 
1523   inst = context->get_def_use_mgr()->GetDef(28);
1524   EXPECT_EQ(false, inst->IsVulkanStorageImage());
1525   EXPECT_EQ(true, inst->IsVulkanSampledImage());
1526   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1527 
1528   inst = context->get_def_use_mgr()->GetDef(29);
1529   EXPECT_EQ(true, inst->IsVulkanStorageImage());
1530   EXPECT_EQ(false, inst->IsVulkanSampledImage());
1531   EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
1532 }
1533 
1534 }  // namespace
1535 }  // namespace opt
1536 }  // namespace spvtools
1537