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