1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SimplifyLoopConditions_test.cpp:
7 // Tests that loop conditions are simplified.
8 //
9
10 #include "GLSLANG/ShaderLang.h"
11 #include "angle_gl.h"
12 #include "gtest/gtest.h"
13 #include "tests/test_utils/compiler_test.h"
14
15 using namespace sh;
16
17 namespace
18 {
19
20 class SimplifyLoopConditionsTest : public MatchOutputCodeTest
21 {
22 public:
SimplifyLoopConditionsTest()23 SimplifyLoopConditionsTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT)
24 {
25 ShCompileOptions defaultCompileOptions = {};
26 defaultCompileOptions.simplifyLoopConditions = true;
27 defaultCompileOptions.validateAST = true;
28 setDefaultCompileOptions(defaultCompileOptions);
29 }
30 };
31
TEST_F(SimplifyLoopConditionsTest,For)32 TEST_F(SimplifyLoopConditionsTest, For)
33 {
34 const char kShader[] = R"(#version 300 es
35 void main() {
36 for (;;) { }
37 })";
38 const char kExpected[] = R"(#version 300 es
39 void main(){
40 {
41 bool sbba = true;
42 while (sbba)
43 {
44 {
45 }
46 }
47 }
48 }
49 )";
50 compile(kShader);
51 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
52 }
53
TEST_F(SimplifyLoopConditionsTest,ForExprConstant)54 TEST_F(SimplifyLoopConditionsTest, ForExprConstant)
55 {
56 const char kShader[] = R"(#version 300 es
57 void main() {
58 for (;true;) { }
59 })";
60 const char kExpected[] = R"(#version 300 es
61 void main(){
62 {
63 bool sbba = true;
64 while (sbba)
65 {
66 {
67 }
68 }
69 }
70 }
71 )";
72 compile(kShader);
73 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
74 }
75
TEST_F(SimplifyLoopConditionsTest,ForExprSymbol)76 TEST_F(SimplifyLoopConditionsTest, ForExprSymbol)
77 {
78 const char kShader[] = R"(#version 300 es
79 void main() {
80 bool b = true;
81 for (;b;) { }
82 })";
83 const char kExpected[] = R"(#version 300 es
84 void main(){
85 bool _ub = true;
86 {
87 while (_ub)
88 {
89 {
90 }
91 }
92 }
93 }
94 )";
95 compile(kShader);
96 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
97 }
98
TEST_F(SimplifyLoopConditionsTest,ForExpr)99 TEST_F(SimplifyLoopConditionsTest, ForExpr)
100 {
101 const char kShader[] = R"(#version 300 es
102 void main() {
103 bool b = true;
104 for (;b == true;) { }
105 })";
106 const char kExpected[] = R"(#version 300 es
107 void main(){
108 bool _ub = true;
109 {
110 bool sbbb = (_ub == true);
111 while (sbbb)
112 {
113 {
114 }
115 (sbbb = (_ub == true));
116 }
117 }
118 }
119 )";
120 compile(kShader);
121 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
122 }
123
TEST_F(SimplifyLoopConditionsTest,ForInitExprSymbol)124 TEST_F(SimplifyLoopConditionsTest, ForInitExprSymbol)
125 {
126 const char kShader[] = R"(#version 300 es
127 void main() {
128 for (bool b = true; b;) { }
129 })";
130 const char kExpected[] = R"(#version 300 es
131 void main(){
132 {
133 bool _ub = true;
134 while (_ub)
135 {
136 {
137 }
138 }
139 }
140 }
141 )";
142 compile(kShader);
143 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
144 }
145
TEST_F(SimplifyLoopConditionsTest,ForInitExprSymbolExpr2)146 TEST_F(SimplifyLoopConditionsTest, ForInitExprSymbolExpr2)
147 {
148 const char kShader[] = R"(#version 300 es
149 void main() {
150 for (bool b = true; b; b = false) { }
151 })";
152 const char kExpected[] = R"(#version 300 es
153 void main(){
154 {
155 bool _ub = true;
156 while (_ub)
157 {
158 {
159 }
160 (_ub = false);
161 }
162 }
163 }
164 )";
165 compile(kShader);
166 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
167 }
168
TEST_F(SimplifyLoopConditionsTest,ForInitExprExpr2)169 TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2)
170 {
171 const char kShader[] = R"(#version 300 es
172 void main() {
173 for (highp int i; i < 100; ++i) { }
174 })";
175 const char kExpected[] = R"(#version 300 es
176 void main(){
177 {
178 highp int _ui;
179 bool sbbb = (_ui < 100);
180 while (sbbb)
181 {
182 {
183 }
184 (++_ui);
185 (sbbb = (_ui < 100));
186 }
187 }
188 }
189 )";
190 compile(kShader);
191 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
192 }
193
TEST_F(SimplifyLoopConditionsTest,ForInitExprExpr2Break)194 TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2Break)
195 {
196 const char kShader[] = R"(#version 300 es
197 uniform highp int u;
198 void main() {
199 for (highp int i; i < 100; ++i) { if (i < u) break; }
200 })";
201 const char kExpected[] = R"(#version 300 es
202 uniform highp int _uu;
203 void main(){
204 {
205 highp int _ui;
206 bool sbbc = (_ui < 100);
207 while (sbbc)
208 {
209 {
210 if ((_ui < _uu))
211 {
212 break;
213 }
214 }
215 (++_ui);
216 (sbbc = (_ui < 100));
217 }
218 }
219 }
220 )";
221 compile(kShader);
222 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
223 }
224
TEST_F(SimplifyLoopConditionsTest,ForInitExprExpr2Continue)225 TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2Continue)
226 {
227 const char kShader[] = R"(#version 300 es
228 uniform highp int u;
229 void main() {
230 for (highp int i; i < 100; ++i) { if (i < u) continue; ++i; }
231 })";
232 const char kExpected[] = R"(#version 300 es
233 uniform highp int _uu;
234 void main(){
235 {
236 highp int _ui;
237 bool sbbc = (_ui < 100);
238 while (sbbc)
239 {
240 {
241 if ((_ui < _uu))
242 {
243 (++_ui);
244 (sbbc = (_ui < 100));
245 continue;
246 }
247 (++_ui);
248 }
249 (++_ui);
250 (sbbc = (_ui < 100));
251 }
252 }
253 }
254 )";
255 compile(kShader);
256 EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT));
257 }
258
259 } // namespace