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