1 // Copyright (c) 2017 Google Inc.
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 <memory>
16 #include <vector>
17 
18 #include "gmock/gmock.h"
19 #include "source/opt/dominator_analysis.h"
20 #include "source/opt/pass.h"
21 #include "test/opt/assembly_builder.h"
22 #include "test/opt/function_utils.h"
23 #include "test/opt/pass_fixture.h"
24 #include "test/opt/pass_utils.h"
25 
26 namespace spvtools {
27 namespace opt {
28 namespace {
29 
30 using ::testing::UnorderedElementsAre;
31 using PassClassTest = PassTest<::testing::Test>;
32 
33 /*
34   Generated from the following GLSL
35 #version 440 core
36 void main() {
37   for (int i = 0; i < 1; i++) {
38     break;
39   }
40 }
41 */
TEST_F(PassClassTest, UnreachableNestedIfs)42 TEST_F(PassClassTest, UnreachableNestedIfs) {
43   const std::string text = R"(
44     OpCapability Shader
45     %1 = OpExtInstImport "GLSL.std.450"
46          OpMemoryModel Logical GLSL450
47          OpEntryPoint Fragment %4 "main"
48          OpExecutionMode %4 OriginUpperLeft
49          OpSource GLSL 440
50          OpName %4 "main"
51          OpName %8 "i"
52     %2 = OpTypeVoid
53     %3 = OpTypeFunction %2
54     %6 = OpTypeInt 32 1
55     %7 = OpTypePointer Function %6
56     %9 = OpConstant %6 0
57    %16 = OpConstant %6 1
58    %17 = OpTypeBool
59     %4 = OpFunction %2 None %3
60     %5 = OpLabel
61     %8 = OpVariable %7 Function
62          OpStore %8 %9
63          OpBranch %10
64    %10 = OpLabel
65          OpLoopMerge %12 %13 None
66          OpBranch %14
67    %14 = OpLabel
68    %15 = OpLoad %6 %8
69    %18 = OpSLessThan %17 %15 %16
70          OpBranchConditional %18 %11 %12
71    %11 = OpLabel
72          OpBranch %12
73    %13 = OpLabel
74    %20 = OpLoad %6 %8
75    %21 = OpIAdd %6 %20 %16
76          OpStore %8 %21
77          OpBranch %10
78    %12 = OpLabel
79          OpReturn
80          OpFunctionEnd
81 )";
82   // clang-format on
83   std::unique_ptr<IRContext> context =
84       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
85                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
86   Module* module = context->module();
87   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
88                              << text << std::endl;
89 
90   const Function* f = spvtest::GetFunction(module, 4);
91   DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
92   EXPECT_TRUE(analysis->Dominates(5, 5));
93   EXPECT_TRUE(analysis->Dominates(5, 10));
94   EXPECT_TRUE(analysis->Dominates(5, 14));
95   EXPECT_TRUE(analysis->Dominates(5, 11));
96   EXPECT_TRUE(analysis->Dominates(5, 12));
97   EXPECT_TRUE(analysis->Dominates(10, 10));
98   EXPECT_TRUE(analysis->Dominates(10, 14));
99   EXPECT_TRUE(analysis->Dominates(10, 11));
100   EXPECT_TRUE(analysis->Dominates(10, 12));
101   EXPECT_TRUE(analysis->Dominates(14, 14));
102   EXPECT_TRUE(analysis->Dominates(14, 11));
103   EXPECT_TRUE(analysis->Dominates(14, 12));
104   EXPECT_TRUE(analysis->Dominates(11, 11));
105   EXPECT_TRUE(analysis->Dominates(12, 12));
106 
107   EXPECT_TRUE(analysis->StrictlyDominates(5, 10));
108   EXPECT_TRUE(analysis->StrictlyDominates(5, 14));
109   EXPECT_TRUE(analysis->StrictlyDominates(5, 11));
110   EXPECT_TRUE(analysis->StrictlyDominates(5, 12));
111   EXPECT_TRUE(analysis->StrictlyDominates(10, 14));
112   EXPECT_TRUE(analysis->StrictlyDominates(10, 11));
113   EXPECT_TRUE(analysis->StrictlyDominates(10, 12));
114   EXPECT_TRUE(analysis->StrictlyDominates(14, 11));
115   EXPECT_TRUE(analysis->StrictlyDominates(14, 12));
116 }
117 
118 }  // namespace
119 }  // namespace opt
120 }  // namespace spvtools
121