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