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