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