// // Copyright 2024 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // SimplifyLoopConditions_test.cpp: // Tests that loop conditions are simplified. // #include "GLSLANG/ShaderLang.h" #include "angle_gl.h" #include "gtest/gtest.h" #include "tests/test_utils/compiler_test.h" using namespace sh; namespace { class SimplifyLoopConditionsTest : public MatchOutputCodeTest { public: SimplifyLoopConditionsTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_ESSL_OUTPUT) { ShCompileOptions defaultCompileOptions = {}; defaultCompileOptions.simplifyLoopConditions = true; defaultCompileOptions.validateAST = true; setDefaultCompileOptions(defaultCompileOptions); } }; TEST_F(SimplifyLoopConditionsTest, For) { const char kShader[] = R"(#version 300 es void main() { for (;;) { } })"; const char kExpected[] = R"(#version 300 es void main(){ { bool sbba = true; while (sbba) { { } } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForExprConstant) { const char kShader[] = R"(#version 300 es void main() { for (;true;) { } })"; const char kExpected[] = R"(#version 300 es void main(){ { bool sbba = true; while (sbba) { { } } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForExprSymbol) { const char kShader[] = R"(#version 300 es void main() { bool b = true; for (;b;) { } })"; const char kExpected[] = R"(#version 300 es void main(){ bool _ub = true; { while (_ub) { { } } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForExpr) { const char kShader[] = R"(#version 300 es void main() { bool b = true; for (;b == true;) { } })"; const char kExpected[] = R"(#version 300 es void main(){ bool _ub = true; { bool sbbb = (_ub == true); while (sbbb) { { } (sbbb = (_ub == true)); } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForInitExprSymbol) { const char kShader[] = R"(#version 300 es void main() { for (bool b = true; b;) { } })"; const char kExpected[] = R"(#version 300 es void main(){ { bool _ub = true; while (_ub) { { } } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForInitExprSymbolExpr2) { const char kShader[] = R"(#version 300 es void main() { for (bool b = true; b; b = false) { } })"; const char kExpected[] = R"(#version 300 es void main(){ { bool _ub = true; while (_ub) { { } (_ub = false); } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2) { const char kShader[] = R"(#version 300 es void main() { for (highp int i; i < 100; ++i) { } })"; const char kExpected[] = R"(#version 300 es void main(){ { highp int _ui; bool sbbb = (_ui < 100); while (sbbb) { { } (++_ui); (sbbb = (_ui < 100)); } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2Break) { const char kShader[] = R"(#version 300 es uniform highp int u; void main() { for (highp int i; i < 100; ++i) { if (i < u) break; } })"; const char kExpected[] = R"(#version 300 es uniform highp int _uu; void main(){ { highp int _ui; bool sbbc = (_ui < 100); while (sbbc) { { if ((_ui < _uu)) { break; } } (++_ui); (sbbc = (_ui < 100)); } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } TEST_F(SimplifyLoopConditionsTest, ForInitExprExpr2Continue) { const char kShader[] = R"(#version 300 es uniform highp int u; void main() { for (highp int i; i < 100; ++i) { if (i < u) continue; ++i; } })"; const char kExpected[] = R"(#version 300 es uniform highp int _uu; void main(){ { highp int _ui; bool sbbc = (_ui < 100); while (sbbc) { { if ((_ui < _uu)) { (++_ui); (sbbc = (_ui < 100)); continue; } (++_ui); } (++_ui); (sbbc = (_ui < 100)); } } } )"; compile(kShader); EXPECT_EQ(kExpected, outputCode(SH_ESSL_OUTPUT)); } } // namespace