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 */ 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