1 // Copyright 2020 The Tint Authors.
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 #include "gmock/gmock.h"
16 #include "src/reader/spirv/parser_impl_test_helper.h"
17 #include "src/reader/spirv/spirv_tools_helpers_test.h"
18
19 namespace tint {
20 namespace reader {
21 namespace spirv {
22 namespace {
23
24 using ::testing::ElementsAre;
25 using ::testing::Eq;
26 using ::testing::HasSubstr;
27 using ::testing::Not;
28 using ::testing::UnorderedElementsAre;
29
30 using SpvParserImportTest = SpvParserTest;
31
TEST_F(SpvParserImportTest,Import_NoImport)32 TEST_F(SpvParserImportTest, Import_NoImport) {
33 auto p = parser(test::Assemble("%1 = OpTypeVoid"));
34 EXPECT_TRUE(p->BuildAndParseInternalModule());
35 EXPECT_TRUE(p->error().empty());
36 const auto program_ast = test::ToString(p->program());
37 EXPECT_THAT(program_ast, Not(HasSubstr("Import")));
38
39 p->DeliberatelyInvalidSpirv();
40 }
41
TEST_F(SpvParserImportTest,Import_ImportGlslStd450)42 TEST_F(SpvParserImportTest, Import_ImportGlslStd450) {
43 auto p = parser(test::Assemble(R"(%1 = OpExtInstImport "GLSL.std.450")"));
44 EXPECT_TRUE(p->BuildAndParseInternalModule());
45 EXPECT_TRUE(p->error().empty());
46 EXPECT_THAT(p->glsl_std_450_imports(), ElementsAre(1));
47
48 p->DeliberatelyInvalidSpirv();
49 }
50
TEST_F(SpvParserImportTest,Import_NonSemantic_IgnoredImport)51 TEST_F(SpvParserImportTest, Import_NonSemantic_IgnoredImport) {
52 auto p = parser(test::Assemble(
53 R"(%40 = OpExtInstImport "NonSemantic.ClspvReflection.1")"));
54 EXPECT_TRUE(p->BuildAndParseInternalModule());
55 EXPECT_TRUE(p->error().empty());
56
57 p->DeliberatelyInvalidSpirv();
58 }
59
TEST_F(SpvParserImportTest,Import_NonSemantic_IgnoredExtInsts)60 TEST_F(SpvParserImportTest, Import_NonSemantic_IgnoredExtInsts) {
61 // This is the clspv-compiled output of this OpenCL C:
62 // kernel void foo(global int*A) { A=A; }
63 // It emits NonSemantic.ClspvReflection.1 extended instructions.
64 // But *tweaked*:
65 // - to remove gl_WorkgroupSize
66 // - to add LocalSize execution mode
67 // - to move one of the ExtInsts into the globals-and-constants
68 // section
69 // - to move one of the ExtInsts into the function body.
70 auto p = parser(test::Assemble(R"(
71 OpCapability Shader
72 OpExtension "SPV_KHR_storage_buffer_storage_class"
73 OpExtension "SPV_KHR_non_semantic_info"
74 %20 = OpExtInstImport "NonSemantic.ClspvReflection.1"
75 OpMemoryModel Logical GLSL450
76 OpEntryPoint GLCompute %15 "foo"
77 OpExecutionMode %15 LocalSize 1 1 1
78 OpSource OpenCL_C 120
79 %21 = OpString "foo"
80 %23 = OpString "A"
81 OpDecorate %_runtimearr_uint ArrayStride 4
82 OpMemberDecorate %_struct_3 0 Offset 0
83 OpDecorate %_struct_3 Block
84 OpDecorate %12 DescriptorSet 0
85 OpDecorate %12 Binding 0
86 OpDecorate %7 SpecId 0
87 OpDecorate %8 SpecId 1
88 OpDecorate %9 SpecId 2
89 %void = OpTypeVoid
90 %24 = OpExtInst %void %20 ArgumentInfo %23
91 %uint = OpTypeInt 32 0
92 %_runtimearr_uint = OpTypeRuntimeArray %uint
93 %_struct_3 = OpTypeStruct %_runtimearr_uint
94 %_ptr_StorageBuffer__struct_3 = OpTypePointer StorageBuffer %_struct_3
95 %v3uint = OpTypeVector %uint 3
96 %_ptr_Private_v3uint = OpTypePointer Private %v3uint
97 %7 = OpSpecConstant %uint 1
98 %8 = OpSpecConstant %uint 1
99 %9 = OpSpecConstant %uint 1
100 %14 = OpTypeFunction %void
101 %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
102 %uint_0 = OpConstant %uint 0
103 %uint_1 = OpConstant %uint 1
104 %uint_2 = OpConstant %uint 2
105 %12 = OpVariable %_ptr_StorageBuffer__struct_3 StorageBuffer
106 %15 = OpFunction %void Const %14
107 %16 = OpLabel
108 %19 = OpAccessChain %_ptr_StorageBuffer_uint %12 %uint_0 %uint_0
109 %22 = OpExtInst %void %20 Kernel %15 %21
110 OpReturn
111 OpFunctionEnd
112 %25 = OpExtInst %void %20 ArgumentStorageBuffer %22 %uint_0 %uint_0 %uint_0 %24
113 %28 = OpExtInst %void %20 SpecConstantWorkgroupSize %uint_0 %uint_1 %uint_2
114 )"));
115 EXPECT_TRUE(p->BuildAndParseInternalModule());
116 EXPECT_TRUE(p->error().empty());
117
118 p->SkipDumpingPending(
119 "crbug.com/tint/1041 track access mode in spirv-reader parser type");
120 }
121
122 // TODO(dneto): We don't currently support other kinds of extended instruction
123 // imports.
124
125 } // namespace
126 } // namespace spirv
127 } // namespace reader
128 } // namespace tint
129