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 layout(location = 0) out vec4 v;
38 layout(location = 1) in vec4 in_val;
39 void main() {
40 int i;
41 switch (int(in_val.x)) {
42 case 0:
43 i = 0;
44 case 1:
45 i = 1;
46 break;
47 case 2:
48 i = 2;
49 case 3:
50 i = 3;
51 case 4:
52 i = 4;
53 break;
54 default:
55 i = 0;
56 }
57 v = vec4(i, i, i, i);
58 }
59 */
TEST_F(PassClassTest,UnreachableNestedIfs)60 TEST_F(PassClassTest, UnreachableNestedIfs) {
61 const std::string text = R"(
62 OpCapability Shader
63 %1 = OpExtInstImport "GLSL.std.450"
64 OpMemoryModel Logical GLSL450
65 OpEntryPoint Fragment %4 "main" %9 %35
66 OpExecutionMode %4 OriginUpperLeft
67 OpSource GLSL 440
68 OpName %4 "main"
69 OpName %9 "in_val"
70 OpName %25 "i"
71 OpName %35 "v"
72 OpDecorate %9 Location 1
73 OpDecorate %35 Location 0
74 %2 = OpTypeVoid
75 %3 = OpTypeFunction %2
76 %6 = OpTypeFloat 32
77 %7 = OpTypeVector %6 4
78 %8 = OpTypePointer Input %7
79 %9 = OpVariable %8 Input
80 %10 = OpTypeInt 32 0
81 %11 = OpConstant %10 0
82 %12 = OpTypePointer Input %6
83 %15 = OpTypeInt 32 1
84 %24 = OpTypePointer Function %15
85 %26 = OpConstant %15 0
86 %27 = OpConstant %15 1
87 %29 = OpConstant %15 2
88 %30 = OpConstant %15 3
89 %31 = OpConstant %15 4
90 %34 = OpTypePointer Output %7
91 %35 = OpVariable %34 Output
92 %4 = OpFunction %2 None %3
93 %5 = OpLabel
94 %25 = OpVariable %24 Function
95 %13 = OpAccessChain %12 %9 %11
96 %14 = OpLoad %6 %13
97 %16 = OpConvertFToS %15 %14
98 OpSelectionMerge %23 None
99 OpSwitch %16 %22 0 %17 1 %18 2 %19 3 %20 4 %21
100 %22 = OpLabel
101 OpStore %25 %26
102 OpBranch %23
103 %17 = OpLabel
104 OpStore %25 %26
105 OpBranch %18
106 %18 = OpLabel
107 OpStore %25 %27
108 OpBranch %23
109 %19 = OpLabel
110 OpStore %25 %29
111 OpBranch %20
112 %20 = OpLabel
113 OpStore %25 %30
114 OpBranch %21
115 %21 = OpLabel
116 OpStore %25 %31
117 OpBranch %23
118 %23 = OpLabel
119 %36 = OpLoad %15 %25
120 %37 = OpConvertSToF %6 %36
121 %38 = OpLoad %15 %25
122 %39 = OpConvertSToF %6 %38
123 %40 = OpLoad %15 %25
124 %41 = OpConvertSToF %6 %40
125 %42 = OpLoad %15 %25
126 %43 = OpConvertSToF %6 %42
127 %44 = OpCompositeConstruct %7 %37 %39 %41 %43
128 OpStore %35 %44
129 OpReturn
130 OpFunctionEnd
131 )";
132 // clang-format on
133 std::unique_ptr<IRContext> context =
134 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
135 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
136 Module* module = context->module();
137 EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
138 << text << std::endl;
139
140 const Function* f = spvtest::GetFunction(module, 4);
141 DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
142
143 EXPECT_TRUE(analysis->Dominates(5, 5));
144 EXPECT_TRUE(analysis->Dominates(5, 17));
145 EXPECT_TRUE(analysis->Dominates(5, 18));
146 EXPECT_TRUE(analysis->Dominates(5, 19));
147 EXPECT_TRUE(analysis->Dominates(5, 20));
148 EXPECT_TRUE(analysis->Dominates(5, 21));
149 EXPECT_TRUE(analysis->Dominates(5, 22));
150 EXPECT_TRUE(analysis->Dominates(5, 23));
151
152 EXPECT_TRUE(analysis->StrictlyDominates(5, 17));
153 EXPECT_TRUE(analysis->StrictlyDominates(5, 18));
154 EXPECT_TRUE(analysis->StrictlyDominates(5, 19));
155 EXPECT_TRUE(analysis->StrictlyDominates(5, 20));
156 EXPECT_TRUE(analysis->StrictlyDominates(5, 21));
157 EXPECT_TRUE(analysis->StrictlyDominates(5, 22));
158 EXPECT_TRUE(analysis->StrictlyDominates(5, 23));
159 }
160
161 } // namespace
162 } // namespace opt
163 } // namespace spvtools
164