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