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