• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 Google LLC
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 "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
16 
17 #include "source/opt/build_module.h"
18 #include "source/reduce/reduction_opportunity.h"
19 #include "test/reduce/reduce_test_util.h"
20 
21 namespace spvtools {
22 namespace reduce {
23 namespace {
24 
TEST(OperandToUndefReductionPassTest,BasicCheck)25 TEST(OperandToUndefReductionPassTest, BasicCheck) {
26   // The following shader has 10 opportunities for replacing with undef.
27 
28   //    #version 310 es
29   //
30   //    precision highp float;
31   //
32   //    layout(location=0) out vec4 _GLF_color;
33   //
34   //    layout(set = 0, binding = 0) uniform buf0 {
35   //        vec2 uniform1;
36   //    };
37   //
38   //    void main()
39   //    {
40   //        _GLF_color =
41   //            vec4(                          // opportunity
42   //                uniform1.x / 2.0,          // opportunity x2 (2.0 is const)
43   //                uniform1.y / uniform1.x,   // opportunity x3
44   //                uniform1.x + uniform1.x,   // opportunity x3
45   //                uniform1.y);               // opportunity
46   //    }
47 
48   std::string original = R"(
49                OpCapability Shader
50           %1 = OpExtInstImport "GLSL.std.450"
51                OpMemoryModel Logical GLSL450
52                OpEntryPoint Fragment %4 "main" %9
53                OpExecutionMode %4 OriginUpperLeft
54                OpSource ESSL 310
55                OpName %4 "main"
56                OpName %9 "_GLF_color"
57                OpName %11 "buf0"
58                OpMemberName %11 0 "uniform1"
59                OpName %13 ""
60                OpDecorate %9 Location 0
61                OpMemberDecorate %11 0 Offset 0
62                OpDecorate %11 Block
63                OpDecorate %13 DescriptorSet 0
64                OpDecorate %13 Binding 0
65           %2 = OpTypeVoid
66           %3 = OpTypeFunction %2
67           %6 = OpTypeFloat 32
68           %7 = OpTypeVector %6 4
69           %8 = OpTypePointer Output %7
70           %9 = OpVariable %8 Output
71          %10 = OpTypeVector %6 2
72          %11 = OpTypeStruct %10
73          %12 = OpTypePointer Uniform %11
74          %13 = OpVariable %12 Uniform
75          %14 = OpTypeInt 32 1
76          %15 = OpConstant %14 0
77          %16 = OpTypeInt 32 0
78          %17 = OpConstant %16 0
79          %18 = OpTypePointer Uniform %6
80          %21 = OpConstant %6 2
81          %23 = OpConstant %16 1
82           %4 = OpFunction %2 None %3
83           %5 = OpLabel
84          %19 = OpAccessChain %18 %13 %15 %17
85          %20 = OpLoad %6 %19
86          %22 = OpFDiv %6 %20 %21                         ; opportunity %20 (%21 is const)
87          %24 = OpAccessChain %18 %13 %15 %23
88          %25 = OpLoad %6 %24
89          %26 = OpAccessChain %18 %13 %15 %17
90          %27 = OpLoad %6 %26
91          %28 = OpFDiv %6 %25 %27                         ; opportunity %25 %27
92          %29 = OpAccessChain %18 %13 %15 %17
93          %30 = OpLoad %6 %29
94          %31 = OpAccessChain %18 %13 %15 %17
95          %32 = OpLoad %6 %31
96          %33 = OpFAdd %6 %30 %32                         ; opportunity %30 %32
97          %34 = OpAccessChain %18 %13 %15 %23
98          %35 = OpLoad %6 %34
99          %36 = OpCompositeConstruct %7 %22 %28 %33 %35   ; opportunity %22 %28 %33 %35
100                OpStore %9 %36                            ; opportunity %36
101                OpReturn
102                OpFunctionEnd
103   )";
104 
105   // This is the same as original, except where noted.
106   std::string expected = R"(
107                OpCapability Shader
108           %1 = OpExtInstImport "GLSL.std.450"
109                OpMemoryModel Logical GLSL450
110                OpEntryPoint Fragment %4 "main" %9
111                OpExecutionMode %4 OriginUpperLeft
112                OpSource ESSL 310
113                OpName %4 "main"
114                OpName %9 "_GLF_color"
115                OpName %11 "buf0"
116                OpMemberName %11 0 "uniform1"
117                OpName %13 ""
118                OpDecorate %9 Location 0
119                OpMemberDecorate %11 0 Offset 0
120                OpDecorate %11 Block
121                OpDecorate %13 DescriptorSet 0
122                OpDecorate %13 Binding 0
123           %2 = OpTypeVoid
124           %3 = OpTypeFunction %2
125           %6 = OpTypeFloat 32
126           %7 = OpTypeVector %6 4
127           %8 = OpTypePointer Output %7
128           %9 = OpVariable %8 Output
129          %10 = OpTypeVector %6 2
130          %11 = OpTypeStruct %10
131          %12 = OpTypePointer Uniform %11
132          %13 = OpVariable %12 Uniform
133          %14 = OpTypeInt 32 1
134          %15 = OpConstant %14 0
135          %16 = OpTypeInt 32 0
136          %17 = OpConstant %16 0
137          %18 = OpTypePointer Uniform %6
138          %21 = OpConstant %6 2
139          %23 = OpConstant %16 1
140          %37 = OpUndef %6                            ; Added undef float as %37
141           %4 = OpFunction %2 None %3
142           %5 = OpLabel
143          %19 = OpAccessChain %18 %13 %15 %17
144          %20 = OpLoad %6 %19
145          %22 = OpFDiv %6 %37 %21                     ; Replaced with %37
146          %24 = OpAccessChain %18 %13 %15 %23
147          %25 = OpLoad %6 %24
148          %26 = OpAccessChain %18 %13 %15 %17
149          %27 = OpLoad %6 %26
150          %28 = OpFDiv %6 %37 %37                     ; Replaced with %37 twice
151          %29 = OpAccessChain %18 %13 %15 %17
152          %30 = OpLoad %6 %29
153          %31 = OpAccessChain %18 %13 %15 %17
154          %32 = OpLoad %6 %31
155          %33 = OpFAdd %6 %30 %32
156          %34 = OpAccessChain %18 %13 %15 %23
157          %35 = OpLoad %6 %34
158          %36 = OpCompositeConstruct %7 %22 %28 %33 %35
159                OpStore %9 %36
160                OpReturn
161                OpFunctionEnd
162   )";
163 
164   const auto env = SPV_ENV_UNIVERSAL_1_3;
165   const auto consumer = nullptr;
166   const auto context =
167       BuildModule(env, consumer, original, kReduceAssembleOption);
168   const auto ops =
169       OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
170           context.get(), 0);
171 
172   ASSERT_EQ(10, ops.size());
173 
174   // Apply first three opportunities.
175   ASSERT_TRUE(ops[0]->PreconditionHolds());
176   ops[0]->TryToApply();
177   ASSERT_TRUE(ops[1]->PreconditionHolds());
178   ops[1]->TryToApply();
179   ASSERT_TRUE(ops[2]->PreconditionHolds());
180   ops[2]->TryToApply();
181 
182   CheckEqual(env, expected, context.get());
183 }
184 
TEST(OperandToUndefReductionPassTest,WithCalledFunction)185 TEST(OperandToUndefReductionPassTest, WithCalledFunction) {
186   // The following shader has no opportunities.
187   // Most importantly, the noted function operand is not changed.
188 
189   std::string shader = R"(
190                OpCapability Shader
191           %1 = OpExtInstImport "GLSL.std.450"
192                OpMemoryModel Logical GLSL450
193                OpEntryPoint Fragment %4 "main" %10 %12
194                OpExecutionMode %4 OriginUpperLeft
195                OpSource ESSL 310
196           %2 = OpTypeVoid
197           %3 = OpTypeFunction %2
198           %6 = OpTypeFloat 32
199           %7 = OpTypeVector %6 4
200           %8 = OpTypeFunction %7
201           %9 = OpTypePointer Output %7
202          %10 = OpVariable %9 Output
203          %11 = OpTypePointer Input %7
204          %12 = OpVariable %11 Input
205          %13 = OpConstant %6 0
206          %14 = OpConstantComposite %7 %13 %13 %13 %13
207           %4 = OpFunction %2 None %3
208           %5 = OpLabel
209          %15 = OpFunctionCall %7 %16            ; do not replace %16 with undef
210                OpReturn
211                OpFunctionEnd
212          %16 = OpFunction %7 None %8
213          %17 = OpLabel
214                OpReturnValue %14
215                OpFunctionEnd
216   )";
217 
218   const auto env = SPV_ENV_UNIVERSAL_1_3;
219   const auto consumer = nullptr;
220   const auto context =
221       BuildModule(env, consumer, shader, kReduceAssembleOption);
222   const auto ops =
223       OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
224           context.get(), 0);
225   ASSERT_EQ(0, ops.size());
226 }
227 
228 }  // namespace
229 }  // namespace reduce
230 }  // namespace spvtools
231