1fd4e5da5Sopenharmony_ci// Copyright (c) 2015-2016 The Khronos Group 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// Assembler tests for instructions in the "Memory Instructions" section of 16fd4e5da5Sopenharmony_ci// the SPIR-V spec. 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include <sstream> 19fd4e5da5Sopenharmony_ci#include <string> 20fd4e5da5Sopenharmony_ci#include <vector> 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 23fd4e5da5Sopenharmony_ci#include "test/test_fixture.h" 24fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h" 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_cinamespace spvtools { 27fd4e5da5Sopenharmony_cinamespace { 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciusing spvtest::EnumCase; 30fd4e5da5Sopenharmony_ciusing spvtest::MakeInstruction; 31fd4e5da5Sopenharmony_ciusing spvtest::TextToBinaryTest; 32fd4e5da5Sopenharmony_ciusing ::testing::Eq; 33fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 34fd4e5da5Sopenharmony_ci 35fd4e5da5Sopenharmony_ci// Test assembly of Memory Access masks 36fd4e5da5Sopenharmony_ci 37fd4e5da5Sopenharmony_ciusing MemoryAccessTest = spvtest::TextToBinaryTestBase< 38fd4e5da5Sopenharmony_ci ::testing::TestWithParam<EnumCase<spv::MemoryAccessMask>>>; 39fd4e5da5Sopenharmony_ci 40fd4e5da5Sopenharmony_ciTEST_P(MemoryAccessTest, AnySingleMemoryAccessMask) { 41fd4e5da5Sopenharmony_ci std::stringstream input; 42fd4e5da5Sopenharmony_ci input << "OpStore %ptr %value " << GetParam().name(); 43fd4e5da5Sopenharmony_ci for (auto operand : GetParam().operands()) input << " " << operand; 44fd4e5da5Sopenharmony_ci EXPECT_THAT( 45fd4e5da5Sopenharmony_ci CompiledInstructions(input.str()), 46fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpStore, {1, 2, (uint32_t)GetParam().value()}, 47fd4e5da5Sopenharmony_ci GetParam().operands()))); 48fd4e5da5Sopenharmony_ci} 49fd4e5da5Sopenharmony_ci 50fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 51fd4e5da5Sopenharmony_ci TextToBinaryMemoryAccessTest, MemoryAccessTest, 52fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::MemoryAccessMask>>{ 53fd4e5da5Sopenharmony_ci {spv::MemoryAccessMask::MaskNone, "None", {}}, 54fd4e5da5Sopenharmony_ci {spv::MemoryAccessMask::Volatile, "Volatile", {}}, 55fd4e5da5Sopenharmony_ci {spv::MemoryAccessMask::Aligned, "Aligned", {16}}, 56fd4e5da5Sopenharmony_ci {spv::MemoryAccessMask::Nontemporal, "Nontemporal", {}}, 57fd4e5da5Sopenharmony_ci })); 58fd4e5da5Sopenharmony_ci 59fd4e5da5Sopenharmony_ciTEST_F(TextToBinaryTest, CombinedMemoryAccessMask) { 60fd4e5da5Sopenharmony_ci const std::string input = "OpStore %ptr %value Volatile|Aligned 16"; 61fd4e5da5Sopenharmony_ci const uint32_t expected_mask = uint32_t(spv::MemoryAccessMask::Volatile | 62fd4e5da5Sopenharmony_ci spv::MemoryAccessMask::Aligned); 63fd4e5da5Sopenharmony_ci EXPECT_THAT(expected_mask, Eq(3u)); 64fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), 65fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpStore, {1, 2, expected_mask, 16}))); 66fd4e5da5Sopenharmony_ci} 67fd4e5da5Sopenharmony_ci 68fd4e5da5Sopenharmony_ci// Test Storage Class enum values 69fd4e5da5Sopenharmony_ci 70fd4e5da5Sopenharmony_ciusing StorageClassTest = spvtest::TextToBinaryTestBase< 71fd4e5da5Sopenharmony_ci ::testing::TestWithParam<EnumCase<spv::StorageClass>>>; 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ciTEST_P(StorageClassTest, AnyStorageClass) { 74fd4e5da5Sopenharmony_ci const std::string input = "%1 = OpVariable %2 " + GetParam().name(); 75fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(input), 76fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpVariable, 77fd4e5da5Sopenharmony_ci {1, 2, (uint32_t)GetParam().value()}))); 78fd4e5da5Sopenharmony_ci} 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci// clang-format off 81fd4e5da5Sopenharmony_ci#define CASE(NAME) { spv::StorageClass::NAME, #NAME, {} } 82fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P( 83fd4e5da5Sopenharmony_ci TextToBinaryStorageClassTest, StorageClassTest, 84fd4e5da5Sopenharmony_ci ::testing::ValuesIn(std::vector<EnumCase<spv::StorageClass>>{ 85fd4e5da5Sopenharmony_ci CASE(UniformConstant), 86fd4e5da5Sopenharmony_ci CASE(Input), 87fd4e5da5Sopenharmony_ci CASE(Uniform), 88fd4e5da5Sopenharmony_ci CASE(Output), 89fd4e5da5Sopenharmony_ci CASE(Workgroup), 90fd4e5da5Sopenharmony_ci CASE(CrossWorkgroup), 91fd4e5da5Sopenharmony_ci CASE(Private), 92fd4e5da5Sopenharmony_ci CASE(Function), 93fd4e5da5Sopenharmony_ci CASE(Generic), 94fd4e5da5Sopenharmony_ci CASE(PushConstant), 95fd4e5da5Sopenharmony_ci CASE(AtomicCounter), 96fd4e5da5Sopenharmony_ci CASE(Image), 97fd4e5da5Sopenharmony_ci })); 98fd4e5da5Sopenharmony_ci#undef CASE 99fd4e5da5Sopenharmony_ci// clang-format on 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ciusing MemoryRoundTripTest = RoundTripTest; 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci// OpPtrEqual appeared in SPIR-V 1.4 104fd4e5da5Sopenharmony_ci 105fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrEqualGood) { 106fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrEqual %1 %3 %4\n"; 107fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), 108fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpPtrEqual, {1, 2, 3, 4}))); 109fd4e5da5Sopenharmony_ci std::string disassembly = EncodeAndDecodeSuccessfully( 110fd4e5da5Sopenharmony_ci spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); 111fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 112fd4e5da5Sopenharmony_ci} 113fd4e5da5Sopenharmony_ci 114fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrEqualV13Bad) { 115fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrEqual %1 %3 %4\n"; 116fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv, SPV_ENV_UNIVERSAL_1_3); 117fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Invalid Opcode name 'OpPtrEqual'")); 118fd4e5da5Sopenharmony_ci} 119fd4e5da5Sopenharmony_ci 120fd4e5da5Sopenharmony_ci// OpPtrNotEqual appeared in SPIR-V 1.4 121fd4e5da5Sopenharmony_ci 122fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrNotEqualGood) { 123fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrNotEqual %1 %3 %4\n"; 124fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), 125fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpPtrNotEqual, {1, 2, 3, 4}))); 126fd4e5da5Sopenharmony_ci std::string disassembly = EncodeAndDecodeSuccessfully( 127fd4e5da5Sopenharmony_ci spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); 128fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 129fd4e5da5Sopenharmony_ci} 130fd4e5da5Sopenharmony_ci 131fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrNotEqualV13Bad) { 132fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrNotEqual %1 %3 %4\n"; 133fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv, SPV_ENV_UNIVERSAL_1_3); 134fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Invalid Opcode name 'OpPtrNotEqual'")); 135fd4e5da5Sopenharmony_ci} 136fd4e5da5Sopenharmony_ci 137fd4e5da5Sopenharmony_ci// OpPtrDiff appeared in SPIR-V 1.4 138fd4e5da5Sopenharmony_ci 139fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrDiffGood) { 140fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrDiff %1 %3 %4\n"; 141fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), 142fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpPtrDiff, {1, 2, 3, 4}))); 143fd4e5da5Sopenharmony_ci std::string disassembly = EncodeAndDecodeSuccessfully( 144fd4e5da5Sopenharmony_ci spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); 145fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 146fd4e5da5Sopenharmony_ci} 147fd4e5da5Sopenharmony_ci 148fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpPtrDiffV13Good) { 149fd4e5da5Sopenharmony_ci // OpPtrDiff is enabled by a capability as well, so we can assemble 150fd4e5da5Sopenharmony_ci // it even in older SPIR-V environments. We do that so we can 151fd4e5da5Sopenharmony_ci // write tests. 152fd4e5da5Sopenharmony_ci std::string spirv = "%2 = OpPtrDiff %1 %3 %4\n"; 153fd4e5da5Sopenharmony_ci std::string disassembly = EncodeAndDecodeSuccessfully( 154fd4e5da5Sopenharmony_ci spirv, SPV_BINARY_TO_TEXT_OPTION_NONE, SPV_ENV_UNIVERSAL_1_4); 155fd4e5da5Sopenharmony_ci} 156fd4e5da5Sopenharmony_ci 157fd4e5da5Sopenharmony_ci// OpCopyMemory 158fd4e5da5Sopenharmony_ci 159fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryNoMemAccessGood) { 160fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2\n"; 161fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 162fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2}))); 163fd4e5da5Sopenharmony_ci std::string disassembly = 164fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 165fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 166fd4e5da5Sopenharmony_ci} 167fd4e5da5Sopenharmony_ci 168fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryTooFewArgsBad) { 169fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1\n"; 170fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv); 171fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Expected operand for OpCopyMemory instruction, " 172fd4e5da5Sopenharmony_ci "but found the end of the stream.")); 173fd4e5da5Sopenharmony_ci} 174fd4e5da5Sopenharmony_ci 175fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryTooManyArgsBad) { 176fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 %3\n"; 177fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv); 178fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%3'")); 179fd4e5da5Sopenharmony_ci} 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNoneGood) { 182fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 None\n"; 183fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 184fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 0}))); 185fd4e5da5Sopenharmony_ci std::string disassembly = 186fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 187fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 188fd4e5da5Sopenharmony_ci} 189fd4e5da5Sopenharmony_ci 190fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVolatileGood) { 191fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 Volatile\n"; 192fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 193fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1}))); 194fd4e5da5Sopenharmony_ci std::string disassembly = 195fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 196fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 197fd4e5da5Sopenharmony_ci} 198fd4e5da5Sopenharmony_ci 199fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAligned8Good) { 200fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 Aligned 8\n"; 201fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 202fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 2, 8}))); 203fd4e5da5Sopenharmony_ci std::string disassembly = 204fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 205fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 206fd4e5da5Sopenharmony_ci} 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) { 209fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 Nontemporal\n"; 210fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 211fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 4}))); 212fd4e5da5Sopenharmony_ci std::string disassembly = 213fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 214fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 215fd4e5da5Sopenharmony_ci} 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) { 218fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailable %3\n"; 219fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 220fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 8, 3}))); 221fd4e5da5Sopenharmony_ci std::string disassembly = 222fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 223fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 224fd4e5da5Sopenharmony_ci} 225fd4e5da5Sopenharmony_ci 226fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) { 227fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 MakePointerVisible %3\n"; 228fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 229fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 16, 3}))); 230fd4e5da5Sopenharmony_ci std::string disassembly = 231fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 232fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 233fd4e5da5Sopenharmony_ci} 234fd4e5da5Sopenharmony_ci 235fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) { 236fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointer\n"; 237fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 238fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 32}))); 239fd4e5da5Sopenharmony_ci std::string disassembly = 240fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 241fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 242fd4e5da5Sopenharmony_ci} 243fd4e5da5Sopenharmony_ci 244fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryAccessMixedGood) { 245fd4e5da5Sopenharmony_ci std::string spirv = 246fd4e5da5Sopenharmony_ci "OpCopyMemory %1 %2 " 247fd4e5da5Sopenharmony_ci "Volatile|Aligned|Nontemporal|MakePointerAvailable|" 248fd4e5da5Sopenharmony_ci "MakePointerVisible|NonPrivatePointer 16 %3 %4\n"; 249fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 250fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 63, 16, 3, 4}))); 251fd4e5da5Sopenharmony_ci std::string disassembly = 252fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 253fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 254fd4e5da5Sopenharmony_ci} 255fd4e5da5Sopenharmony_ci 256fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV13Good) { 257fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n"; 258fd4e5da5Sopenharmony_ci // Note: This will assemble but should not validate for SPIR-V 1.3 259fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3), 260fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1}))); 261fd4e5da5Sopenharmony_ci std::string disassembly = 262fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 263fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 264fd4e5da5Sopenharmony_ci} 265fd4e5da5Sopenharmony_ci 266fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV14Good) { 267fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n"; 268fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), 269fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 1, 1}))); 270fd4e5da5Sopenharmony_ci std::string disassembly = 271fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 272fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 273fd4e5da5Sopenharmony_ci} 274fd4e5da5Sopenharmony_ci 275fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) { 276fd4e5da5Sopenharmony_ci std::string spirv = 277fd4e5da5Sopenharmony_ci "OpCopyMemory %1 %2 Volatile|Nontemporal|" 278fd4e5da5Sopenharmony_ci "MakePointerVisible %3 " 279fd4e5da5Sopenharmony_ci "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4\n"; 280fd4e5da5Sopenharmony_ci EXPECT_THAT( 281fd4e5da5Sopenharmony_ci CompiledInstructions(spirv), 282fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemory, {1, 2, 21, 3, 42, 16, 4}))); 283fd4e5da5Sopenharmony_ci std::string disassembly = 284fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 285fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 286fd4e5da5Sopenharmony_ci} 287fd4e5da5Sopenharmony_ci 288fd4e5da5Sopenharmony_ci// OpCopyMemorySized 289fd4e5da5Sopenharmony_ci 290fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedNoMemAccessGood) { 291fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3\n"; 292fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 293fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3}))); 294fd4e5da5Sopenharmony_ci std::string disassembly = 295fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 296fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 297fd4e5da5Sopenharmony_ci} 298fd4e5da5Sopenharmony_ci 299fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooFewArgsBad) { 300fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2\n"; 301fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv); 302fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Expected operand for OpCopyMemorySized " 303fd4e5da5Sopenharmony_ci "instruction, but found the end of the stream.")); 304fd4e5da5Sopenharmony_ci} 305fd4e5da5Sopenharmony_ci 306fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooManyArgsBad) { 307fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 %4\n"; 308fd4e5da5Sopenharmony_ci std::string err = CompileFailure(spirv); 309fd4e5da5Sopenharmony_ci EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%4'")); 310fd4e5da5Sopenharmony_ci} 311fd4e5da5Sopenharmony_ci 312fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNoneGood) { 313fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 None\n"; 314fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 315fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 0}))); 316fd4e5da5Sopenharmony_ci std::string disassembly = 317fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 318fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 319fd4e5da5Sopenharmony_ci} 320fd4e5da5Sopenharmony_ci 321fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVolatileGood) { 322fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile\n"; 323fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 324fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1}))); 325fd4e5da5Sopenharmony_ci std::string disassembly = 326fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 327fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 328fd4e5da5Sopenharmony_ci} 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAligned8Good) { 331fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 Aligned 8\n"; 332fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 333fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 2, 8}))); 334fd4e5da5Sopenharmony_ci std::string disassembly = 335fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 336fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 337fd4e5da5Sopenharmony_ci} 338fd4e5da5Sopenharmony_ci 339fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) { 340fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 Nontemporal\n"; 341fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 342fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 4}))); 343fd4e5da5Sopenharmony_ci std::string disassembly = 344fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 345fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 346fd4e5da5Sopenharmony_ci} 347fd4e5da5Sopenharmony_ci 348fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) { 349fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailable %4\n"; 350fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 351fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 8, 4}))); 352fd4e5da5Sopenharmony_ci std::string disassembly = 353fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 354fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 355fd4e5da5Sopenharmony_ci} 356fd4e5da5Sopenharmony_ci 357fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) { 358fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisible %4\n"; 359fd4e5da5Sopenharmony_ci EXPECT_THAT( 360fd4e5da5Sopenharmony_ci CompiledInstructions(spirv), 361fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 16, 4}))); 362fd4e5da5Sopenharmony_ci std::string disassembly = 363fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 364fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 365fd4e5da5Sopenharmony_ci} 366fd4e5da5Sopenharmony_ci 367fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) { 368fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointer\n"; 369fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 370fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 32}))); 371fd4e5da5Sopenharmony_ci std::string disassembly = 372fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 373fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 374fd4e5da5Sopenharmony_ci} 375fd4e5da5Sopenharmony_ci 376fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessMixedGood) { 377fd4e5da5Sopenharmony_ci std::string spirv = 378fd4e5da5Sopenharmony_ci "OpCopyMemorySized %1 %2 %3 " 379fd4e5da5Sopenharmony_ci "Volatile|Aligned|Nontemporal|MakePointerAvailable|" 380fd4e5da5Sopenharmony_ci "MakePointerVisible|NonPrivatePointer 16 %4 %5\n"; 381fd4e5da5Sopenharmony_ci EXPECT_THAT( 382fd4e5da5Sopenharmony_ci CompiledInstructions(spirv), 383fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5}))); 384fd4e5da5Sopenharmony_ci std::string disassembly = 385fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 386fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 387fd4e5da5Sopenharmony_ci} 388fd4e5da5Sopenharmony_ci 389fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV13Good) { 390fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n"; 391fd4e5da5Sopenharmony_ci // Note: This will assemble but should not validate for SPIR-V 1.3 392fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3), 393fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1}))); 394fd4e5da5Sopenharmony_ci std::string disassembly = 395fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 396fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 397fd4e5da5Sopenharmony_ci} 398fd4e5da5Sopenharmony_ci 399fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV14Good) { 400fd4e5da5Sopenharmony_ci std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n"; 401fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4), 402fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, {1, 2, 3, 1, 1}))); 403fd4e5da5Sopenharmony_ci std::string disassembly = 404fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 405fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 406fd4e5da5Sopenharmony_ci} 407fd4e5da5Sopenharmony_ci 408fd4e5da5Sopenharmony_ciTEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessMixedV14Good) { 409fd4e5da5Sopenharmony_ci std::string spirv = 410fd4e5da5Sopenharmony_ci "OpCopyMemorySized %1 %2 %3 Volatile|Nontemporal|" 411fd4e5da5Sopenharmony_ci "MakePointerVisible %4 " 412fd4e5da5Sopenharmony_ci "Aligned|MakePointerAvailable|NonPrivatePointer 16 %5\n"; 413fd4e5da5Sopenharmony_ci EXPECT_THAT(CompiledInstructions(spirv), 414fd4e5da5Sopenharmony_ci Eq(MakeInstruction(spv::Op::OpCopyMemorySized, 415fd4e5da5Sopenharmony_ci {1, 2, 3, 21, 4, 42, 16, 5}))); 416fd4e5da5Sopenharmony_ci std::string disassembly = 417fd4e5da5Sopenharmony_ci EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE); 418fd4e5da5Sopenharmony_ci EXPECT_THAT(disassembly, Eq(spirv)); 419fd4e5da5Sopenharmony_ci} 420fd4e5da5Sopenharmony_ci 421fd4e5da5Sopenharmony_ci// TODO(dneto): OpVariable with initializers 422fd4e5da5Sopenharmony_ci// TODO(dneto): OpImageTexelPointer 423fd4e5da5Sopenharmony_ci// TODO(dneto): OpLoad 424fd4e5da5Sopenharmony_ci// TODO(dneto): OpStore 425fd4e5da5Sopenharmony_ci// TODO(dneto): OpAccessChain 426fd4e5da5Sopenharmony_ci// TODO(dneto): OpInBoundsAccessChain 427fd4e5da5Sopenharmony_ci// TODO(dneto): OpPtrAccessChain 428fd4e5da5Sopenharmony_ci// TODO(dneto): OpArrayLength 429fd4e5da5Sopenharmony_ci// TODO(dneto): OpGenercPtrMemSemantics 430fd4e5da5Sopenharmony_ci 431fd4e5da5Sopenharmony_ci} // namespace 432fd4e5da5Sopenharmony_ci} // namespace spvtools 433