Home | History | Annotate | Download | only in loop_optimizations
      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