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 for OpCopyMemory instruction, "
170 "but found the end of the stream."));
171 }
172
TEST_F(MemoryRoundTripTest,OpCopyMemoryTooManyArgsBad)173 TEST_F(MemoryRoundTripTest, OpCopyMemoryTooManyArgsBad) {
174 std::string spirv = "OpCopyMemory %1 %2 %3\n";
175 std::string err = CompileFailure(spirv);
176 EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%3'"));
177 }
178
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessNoneGood)179 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNoneGood) {
180 std::string spirv = "OpCopyMemory %1 %2 None\n";
181 EXPECT_THAT(CompiledInstructions(spirv),
182 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 0})));
183 std::string disassembly =
184 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
185 EXPECT_THAT(disassembly, Eq(spirv));
186 }
187
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessVolatileGood)188 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVolatileGood) {
189 std::string spirv = "OpCopyMemory %1 %2 Volatile\n";
190 EXPECT_THAT(CompiledInstructions(spirv),
191 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1})));
192 std::string disassembly =
193 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
194 EXPECT_THAT(disassembly, Eq(spirv));
195 }
196
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessAligned8Good)197 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAligned8Good) {
198 std::string spirv = "OpCopyMemory %1 %2 Aligned 8\n";
199 EXPECT_THAT(CompiledInstructions(spirv),
200 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 2, 8})));
201 std::string disassembly =
202 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
203 EXPECT_THAT(disassembly, Eq(spirv));
204 }
205
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessNontemporalGood)206 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNontemporalGood) {
207 std::string spirv = "OpCopyMemory %1 %2 Nontemporal\n";
208 EXPECT_THAT(CompiledInstructions(spirv),
209 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 4})));
210 std::string disassembly =
211 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
212 EXPECT_THAT(disassembly, Eq(spirv));
213 }
214
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessAvGood)215 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessAvGood) {
216 std::string spirv = "OpCopyMemory %1 %2 MakePointerAvailable %3\n";
217 EXPECT_THAT(CompiledInstructions(spirv),
218 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 8, 3})));
219 std::string disassembly =
220 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
221 EXPECT_THAT(disassembly, Eq(spirv));
222 }
223
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessVisGood)224 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessVisGood) {
225 std::string spirv = "OpCopyMemory %1 %2 MakePointerVisible %3\n";
226 EXPECT_THAT(CompiledInstructions(spirv),
227 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 16, 3})));
228 std::string disassembly =
229 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
230 EXPECT_THAT(disassembly, Eq(spirv));
231 }
232
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessNonPrivateGood)233 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessNonPrivateGood) {
234 std::string spirv = "OpCopyMemory %1 %2 NonPrivatePointer\n";
235 EXPECT_THAT(CompiledInstructions(spirv),
236 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 32})));
237 std::string disassembly =
238 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
239 EXPECT_THAT(disassembly, Eq(spirv));
240 }
241
TEST_F(MemoryRoundTripTest,OpCopyMemoryAccessMixedGood)242 TEST_F(MemoryRoundTripTest, OpCopyMemoryAccessMixedGood) {
243 std::string spirv =
244 "OpCopyMemory %1 %2 "
245 "Volatile|Aligned|Nontemporal|MakePointerAvailable|"
246 "MakePointerVisible|NonPrivatePointer 16 %3 %4\n";
247 EXPECT_THAT(CompiledInstructions(spirv),
248 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 63, 16, 3, 4})));
249 std::string disassembly =
250 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
251 EXPECT_THAT(disassembly, Eq(spirv));
252 }
253
TEST_F(MemoryRoundTripTest,OpCopyMemoryTwoAccessV13Good)254 TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV13Good) {
255 std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n";
256 // Note: This will assemble but should not validate for SPIR-V 1.3
257 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3),
258 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1, 1})));
259 std::string disassembly =
260 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
261 EXPECT_THAT(disassembly, Eq(spirv));
262 }
263
TEST_F(MemoryRoundTripTest,OpCopyMemoryTwoAccessV14Good)264 TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessV14Good) {
265 std::string spirv = "OpCopyMemory %1 %2 Volatile Volatile\n";
266 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
267 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 1, 1})));
268 std::string disassembly =
269 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
270 EXPECT_THAT(disassembly, Eq(spirv));
271 }
272
TEST_F(MemoryRoundTripTest,OpCopyMemoryTwoAccessMixedV14Good)273 TEST_F(MemoryRoundTripTest, OpCopyMemoryTwoAccessMixedV14Good) {
274 std::string spirv =
275 "OpCopyMemory %1 %2 Volatile|Nontemporal|"
276 "MakePointerVisible %3 "
277 "Aligned|MakePointerAvailable|NonPrivatePointer 16 %4\n";
278 EXPECT_THAT(CompiledInstructions(spirv),
279 Eq(MakeInstruction(SpvOpCopyMemory, {1, 2, 21, 3, 42, 16, 4})));
280 std::string disassembly =
281 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
282 EXPECT_THAT(disassembly, Eq(spirv));
283 }
284
285 // OpCopyMemorySized
286
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedNoMemAccessGood)287 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedNoMemAccessGood) {
288 std::string spirv = "OpCopyMemorySized %1 %2 %3\n";
289 EXPECT_THAT(CompiledInstructions(spirv),
290 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3})));
291 std::string disassembly =
292 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
293 EXPECT_THAT(disassembly, Eq(spirv));
294 }
295
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedTooFewArgsBad)296 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooFewArgsBad) {
297 std::string spirv = "OpCopyMemorySized %1 %2\n";
298 std::string err = CompileFailure(spirv);
299 EXPECT_THAT(err, HasSubstr("Expected operand for OpCopyMemorySized "
300 "instruction, but found the end of the stream."));
301 }
302
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedTooManyArgsBad)303 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTooManyArgsBad) {
304 std::string spirv = "OpCopyMemorySized %1 %2 %3 %4\n";
305 std::string err = CompileFailure(spirv);
306 EXPECT_THAT(err, HasSubstr("Invalid memory access operand '%4'"));
307 }
308
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessNoneGood)309 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNoneGood) {
310 std::string spirv = "OpCopyMemorySized %1 %2 %3 None\n";
311 EXPECT_THAT(CompiledInstructions(spirv),
312 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 0})));
313 std::string disassembly =
314 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
315 EXPECT_THAT(disassembly, Eq(spirv));
316 }
317
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessVolatileGood)318 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVolatileGood) {
319 std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile\n";
320 EXPECT_THAT(CompiledInstructions(spirv),
321 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1})));
322 std::string disassembly =
323 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
324 EXPECT_THAT(disassembly, Eq(spirv));
325 }
326
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessAligned8Good)327 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAligned8Good) {
328 std::string spirv = "OpCopyMemorySized %1 %2 %3 Aligned 8\n";
329 EXPECT_THAT(CompiledInstructions(spirv),
330 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 2, 8})));
331 std::string disassembly =
332 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
333 EXPECT_THAT(disassembly, Eq(spirv));
334 }
335
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessNontemporalGood)336 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNontemporalGood) {
337 std::string spirv = "OpCopyMemorySized %1 %2 %3 Nontemporal\n";
338 EXPECT_THAT(CompiledInstructions(spirv),
339 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 4})));
340 std::string disassembly =
341 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
342 EXPECT_THAT(disassembly, Eq(spirv));
343 }
344
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessAvGood)345 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessAvGood) {
346 std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerAvailable %4\n";
347 EXPECT_THAT(CompiledInstructions(spirv),
348 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 8, 4})));
349 std::string disassembly =
350 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
351 EXPECT_THAT(disassembly, Eq(spirv));
352 }
353
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessVisGood)354 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessVisGood) {
355 std::string spirv = "OpCopyMemorySized %1 %2 %3 MakePointerVisible %4\n";
356 EXPECT_THAT(CompiledInstructions(spirv),
357 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 16, 4})));
358 std::string disassembly =
359 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
360 EXPECT_THAT(disassembly, Eq(spirv));
361 }
362
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessNonPrivateGood)363 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessNonPrivateGood) {
364 std::string spirv = "OpCopyMemorySized %1 %2 %3 NonPrivatePointer\n";
365 EXPECT_THAT(CompiledInstructions(spirv),
366 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 32})));
367 std::string disassembly =
368 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
369 EXPECT_THAT(disassembly, Eq(spirv));
370 }
371
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedAccessMixedGood)372 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedAccessMixedGood) {
373 std::string spirv =
374 "OpCopyMemorySized %1 %2 %3 "
375 "Volatile|Aligned|Nontemporal|MakePointerAvailable|"
376 "MakePointerVisible|NonPrivatePointer 16 %4 %5\n";
377 EXPECT_THAT(
378 CompiledInstructions(spirv),
379 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 63, 16, 4, 5})));
380 std::string disassembly =
381 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
382 EXPECT_THAT(disassembly, Eq(spirv));
383 }
384
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedTwoAccessV13Good)385 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV13Good) {
386 std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n";
387 // Note: This will assemble but should not validate for SPIR-V 1.3
388 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_3),
389 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1, 1})));
390 std::string disassembly =
391 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
392 EXPECT_THAT(disassembly, Eq(spirv));
393 }
394
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedTwoAccessV14Good)395 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessV14Good) {
396 std::string spirv = "OpCopyMemorySized %1 %2 %3 Volatile Volatile\n";
397 EXPECT_THAT(CompiledInstructions(spirv, SPV_ENV_UNIVERSAL_1_4),
398 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 1, 1})));
399 std::string disassembly =
400 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
401 EXPECT_THAT(disassembly, Eq(spirv));
402 }
403
TEST_F(MemoryRoundTripTest,OpCopyMemorySizedTwoAccessMixedV14Good)404 TEST_F(MemoryRoundTripTest, OpCopyMemorySizedTwoAccessMixedV14Good) {
405 std::string spirv =
406 "OpCopyMemorySized %1 %2 %3 Volatile|Nontemporal|"
407 "MakePointerVisible %4 "
408 "Aligned|MakePointerAvailable|NonPrivatePointer 16 %5\n";
409 EXPECT_THAT(
410 CompiledInstructions(spirv),
411 Eq(MakeInstruction(SpvOpCopyMemorySized, {1, 2, 3, 21, 4, 42, 16, 5})));
412 std::string disassembly =
413 EncodeAndDecodeSuccessfully(spirv, SPV_BINARY_TO_TEXT_OPTION_NONE);
414 EXPECT_THAT(disassembly, Eq(spirv));
415 }
416
417 // TODO(dneto): OpVariable with initializers
418 // TODO(dneto): OpImageTexelPointer
419 // TODO(dneto): OpLoad
420 // TODO(dneto): OpStore
421 // TODO(dneto): OpAccessChain
422 // TODO(dneto): OpInBoundsAccessChain
423 // TODO(dneto): OpPtrAccessChain
424 // TODO(dneto): OpArrayLength
425 // TODO(dneto): OpGenercPtrMemSemantics
426
427 } // namespace
428 } // namespace spvtools
429