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