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 <string>
16
17 #include "gmock/gmock.h"
18 #include "source/opt/licm_pass.h"
19 #include "test/opt/pass_fixture.h"
20
21 namespace spvtools {
22 namespace opt {
23 namespace {
24
25 using ::testing::UnorderedElementsAre;
26 using PassClassTest = PassTest<::testing::Test>;
27
28 /*
29 A simple test for the LICM pass
30
31 Generated from the following GLSL fragment shader
32 --eliminate-local-multi-store has also been run on the spv binary
33 #version 440 core
34 void main(){
35 int a = 1;
36 int b = 2;
37 int hoist = 0;
38 for (int i = 0; i < 10; i++) {
39 // invariant
40 hoist = a + b;
41 }
42 }
43 */
TEST_F(PassClassTest,SimpleHoist)44 TEST_F(PassClassTest, SimpleHoist) {
45 const std::string before_hoist = R"(OpCapability Shader
46 %1 = OpExtInstImport "GLSL.std.450"
47 OpMemoryModel Logical GLSL450
48 OpEntryPoint Fragment %main "main"
49 OpExecutionMode %main OriginUpperLeft
50 OpSource GLSL 440
51 OpName %main "main"
52 %void = OpTypeVoid
53 %4 = OpTypeFunction %void
54 %int = OpTypeInt 32 1
55 %_ptr_Function_int = OpTypePointer Function %int
56 %int_1 = OpConstant %int 1
57 %int_2 = OpConstant %int 2
58 %int_0 = OpConstant %int 0
59 %int_10 = OpConstant %int 10
60 %bool = OpTypeBool
61 %main = OpFunction %void None %4
62 %12 = OpLabel
63 OpBranch %13
64 %13 = OpLabel
65 %14 = OpPhi %int %int_0 %12 %15 %16
66 %17 = OpPhi %int %int_0 %12 %18 %16
67 OpLoopMerge %19 %16 None
68 OpBranch %20
69 %20 = OpLabel
70 %21 = OpSLessThan %bool %17 %int_10
71 OpBranchConditional %21 %22 %19
72 %22 = OpLabel
73 %15 = OpIAdd %int %int_1 %int_2
74 OpBranch %16
75 %16 = OpLabel
76 %18 = OpIAdd %int %17 %int_1
77 OpBranch %13
78 %19 = OpLabel
79 OpReturn
80 OpFunctionEnd
81 )";
82
83 const std::string after_hoist = R"(OpCapability Shader
84 %1 = OpExtInstImport "GLSL.std.450"
85 OpMemoryModel Logical GLSL450
86 OpEntryPoint Fragment %main "main"
87 OpExecutionMode %main OriginUpperLeft
88 OpSource GLSL 440
89 OpName %main "main"
90 %void = OpTypeVoid
91 %4 = OpTypeFunction %void
92 %int = OpTypeInt 32 1
93 %_ptr_Function_int = OpTypePointer Function %int
94 %int_1 = OpConstant %int 1
95 %int_2 = OpConstant %int 2
96 %int_0 = OpConstant %int 0
97 %int_10 = OpConstant %int 10
98 %bool = OpTypeBool
99 %main = OpFunction %void None %4
100 %12 = OpLabel
101 %15 = OpIAdd %int %int_1 %int_2
102 OpBranch %13
103 %13 = OpLabel
104 %14 = OpPhi %int %int_0 %12 %15 %16
105 %17 = OpPhi %int %int_0 %12 %18 %16
106 OpLoopMerge %19 %16 None
107 OpBranch %20
108 %20 = OpLabel
109 %21 = OpSLessThan %bool %17 %int_10
110 OpBranchConditional %21 %22 %19
111 %22 = OpLabel
112 OpBranch %16
113 %16 = OpLabel
114 %18 = OpIAdd %int %17 %int_1
115 OpBranch %13
116 %19 = OpLabel
117 OpReturn
118 OpFunctionEnd
119 )";
120
121 SinglePassRunAndCheck<LICMPass>(before_hoist, after_hoist, true);
122 }
123
124 } // namespace
125 } // namespace opt
126 } // namespace spvtools
127