• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/function.h"
17 #include "src/reader/spirv/parser_impl_test_helper.h"
18 #include "src/reader/spirv/spirv_tools_helpers_test.h"
19 
20 namespace tint {
21 namespace reader {
22 namespace spirv {
23 namespace {
24 
25 using ::testing::Eq;
26 using ::testing::HasSubstr;
27 
Preamble()28 std::string Preamble() {
29   return R"(
30      OpCapability Shader
31      OpMemoryModel Logical Simple
32      OpEntryPoint Fragment %100 "x_100"
33      OpExecutionMode %100 OriginUpperLeft
34 )";
35 }
36 
TEST_F(SpvParserTest,EmitStatement_VoidCallNoParams)37 TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
38   auto p = parser(test::Assemble(Preamble() + R"(
39      %void = OpTypeVoid
40      %voidfn = OpTypeFunction %void
41 
42      %50 = OpFunction %void None %voidfn
43      %entry_50 = OpLabel
44      OpReturn
45      OpFunctionEnd
46 
47      %100 = OpFunction %void None %voidfn
48      %entry = OpLabel
49      %1 = OpFunctionCall %void %50
50      OpReturn
51      OpFunctionEnd
52   )"));
53   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error();
54   const auto got = test::ToString(p->program());
55   const char* expect = R"(fn x_50() {
56   return;
57 }
58 
59 fn x_100_1() {
60   x_50();
61   return;
62 }
63 
64 [[stage(fragment)]]
65 fn x_100() {
66   x_100_1();
67 }
68 )";
69   EXPECT_EQ(expect, got);
70 }
71 
TEST_F(SpvParserTest,EmitStatement_ScalarCallNoParams)72 TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParams) {
73   auto p = parser(test::Assemble(Preamble() + R"(
74      %void = OpTypeVoid
75      %voidfn = OpTypeFunction %void
76      %uint = OpTypeInt 32 0
77      %uintfn = OpTypeFunction %uint
78      %val = OpConstant %uint 42
79 
80      %50 = OpFunction %uint None %uintfn
81      %entry_50 = OpLabel
82      OpReturnValue %val
83      OpFunctionEnd
84 
85      %100 = OpFunction %void None %voidfn
86      %entry = OpLabel
87      %1 = OpFunctionCall %uint %50
88      OpReturn
89      OpFunctionEnd
90   )"));
91   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
92   ast::StatementList f100;
93   {
94     auto fe = p->function_emitter(100);
95     EXPECT_TRUE(fe.EmitBody()) << p->error();
96     f100 = fe.ast_body();
97   }
98   ast::StatementList f50;
99   {
100     auto fe = p->function_emitter(50);
101     EXPECT_TRUE(fe.EmitBody()) << p->error();
102     f50 = fe.ast_body();
103   }
104   auto program = p->program();
105   EXPECT_THAT(test::ToString(program, f100),
106               HasSubstr("let x_1 : u32 = x_50();\nreturn;"));
107   EXPECT_THAT(test::ToString(program, f50), HasSubstr("return 42u;"));
108 }
109 
TEST_F(SpvParserTest,EmitStatement_ScalarCallNoParamsUsedTwice)110 TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) {
111   auto p = parser(test::Assemble(Preamble() + R"(
112      %void = OpTypeVoid
113      %voidfn = OpTypeFunction %void
114      %uint = OpTypeInt 32 0
115      %uintfn = OpTypeFunction %uint
116      %val = OpConstant %uint 42
117      %ptr_uint = OpTypePointer Function %uint
118 
119      %50 = OpFunction %uint None %uintfn
120      %entry_50 = OpLabel
121      OpReturnValue %val
122      OpFunctionEnd
123 
124      %100 = OpFunction %void None %voidfn
125      %entry = OpLabel
126      %10 = OpVariable %ptr_uint Function
127      %1 = OpFunctionCall %uint %50
128      OpStore %10 %1
129      OpStore %10 %1
130      OpReturn
131      OpFunctionEnd
132   )"));
133   ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
134   ast::StatementList f100;
135   {
136     auto fe = p->function_emitter(100);
137     EXPECT_TRUE(fe.EmitBody()) << p->error();
138     f100 = fe.ast_body();
139   }
140   ast::StatementList f50;
141   {
142     auto fe = p->function_emitter(50);
143     EXPECT_TRUE(fe.EmitBody()) << p->error();
144     f50 = fe.ast_body();
145   }
146   auto program = p->program();
147   EXPECT_EQ(test::ToString(program, f100), R"(var x_10 : u32;
148 let x_1 : u32 = x_50();
149 x_10 = x_1;
150 x_10 = x_1;
151 return;
152 )");
153   EXPECT_THAT(test::ToString(program, f50), HasSubstr("return 42u;"));
154 }
155 
TEST_F(SpvParserTest,EmitStatement_CallWithParams)156 TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
157   auto p = parser(test::Assemble(Preamble() + R"(
158      %void = OpTypeVoid
159      %voidfn = OpTypeFunction %void
160      %uint = OpTypeInt 32 0
161      %uintfn_uint_uint = OpTypeFunction %uint %uint %uint
162      %val = OpConstant %uint 42
163      %val2 = OpConstant %uint 84
164 
165      %50 = OpFunction %uint None %uintfn_uint_uint
166      %51 = OpFunctionParameter %uint
167      %52 = OpFunctionParameter %uint
168      %entry_50 = OpLabel
169      %sum = OpIAdd %uint %51 %52
170      OpReturnValue %sum
171      OpFunctionEnd
172 
173      %100 = OpFunction %void None %voidfn
174      %entry = OpLabel
175      %1 = OpFunctionCall %uint %50 %val %val2
176      OpReturn
177      OpFunctionEnd
178   )"));
179   ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error();
180   EXPECT_TRUE(p->error().empty());
181   const auto program_ast_str = test::ToString(p->program());
182   const std::string expected = R"(fn x_50(x_51 : u32, x_52 : u32) -> u32 {
183   return (x_51 + x_52);
184 }
185 
186 fn x_100_1() {
187   let x_1 : u32 = x_50(42u, 84u);
188   return;
189 }
190 
191 [[stage(fragment)]]
192 fn x_100() {
193   x_100_1();
194 }
195 )";
196   EXPECT_EQ(program_ast_str, expected);
197 }
198 
199 }  // namespace
200 }  // namespace spirv
201 }  // namespace reader
202 }  // namespace tint
203