diff --git a/src/sksl/SkSLConstantFolder.cpp b/src/sksl/SkSLConstantFolder.cpp index 465a8a0072..5b78893d8b 100644 --- a/src/sksl/SkSLConstantFolder.cpp +++ b/src/sksl/SkSLConstantFolder.cpp @@ -39,6 +39,14 @@ static std::unique_ptr short_circuit_boolean(const Expression& left, return leftVal ? std::make_unique(left.fOffset, /*value=*/true, &left.type()) : right.clone(); } + if (op == Token::Kind::TK_EQEQ && leftVal) { + // (true == expr) -> (expr) + return right.clone(); + } + if (op == Token::Kind::TK_NEQ && !leftVal) { + // (false != expr) -> (expr) + return right.clone(); + } if (op == Token::Kind::TK_LOGICALXOR && !leftVal) { // (false ^^ expr) -> (expr) return right.clone(); diff --git a/tests/sksl/folding/ShortCircuitBoolFolding.sksl b/tests/sksl/folding/ShortCircuitBoolFolding.sksl index 90eca0ea55..4c672b098b 100644 --- a/tests/sksl/folding/ShortCircuitBoolFolding.sksl +++ b/tests/sksl/folding/ShortCircuitBoolFolding.sksl @@ -1,37 +1,35 @@ -void main() { - bool expr1 = sk_FragCoord.x > 0; - bool expr2 = sk_FragCoord.y > 0; +bool test() { + bool expr = sqrt(1) > 0; - if (true && expr1) { // -> if (expr1) - sk_FragColor.r = 1; - } else if (false && expr1) { // -> if (false) -> block removed - sk_FragColor.r = -2; - } else if (true ^^ expr1) { // -> if (!expr1) - sk_FragColor.r = 3; - } else if (false ^^ expr2) { // -> if (expr2) - sk_FragColor.r = 4; - } else if (false || expr2) { // -> if (expr2) - sk_FragColor.r = 5; - } else if (true || expr2) { // -> if (true) -> replaces unreachable else - sk_FragColor.r = 6; - } else { // removed - sk_FragColor.r = -7; - } + int ok = 0, bad = 0; - // Test short-circuiting of right hand side boolean literals - if (expr1 && true) { // -> if (expr1) - sk_FragColor.r = 1; - } else if (expr1 && false) { // -> if (false) -> block removed - sk_FragColor.r = -2; - } else if (expr1 ^^ true) { // -> if (!expr1) - sk_FragColor.r = 3; - } else if (expr2 ^^ false) { // -> if (expr2) - sk_FragColor.r = 4; - } else if (expr2 || false) { // -> if (expr2) - sk_FragColor.r = 5; - } else if (expr2 || true) { // -> if (true) -> replaces unreachable else - sk_FragColor.r = 6; - } else { // removed - sk_FragColor.r = -7; - } + // Test boolean short-circuiting with constants on the left side. + if (true && expr) { ++ok; } else { ++bad; } // -> (expr) + if (false && expr) { ++bad; } else { ++ok; } // -> (false) -> block removed + if (true ^^ expr) { ++bad; } else { ++ok; } // -> unchanged + if (false ^^ expr) { ++ok; } else { ++bad; } // -> (expr) + if (true || expr) { ++ok; } else { ++bad; } // -> (true) + if (false || expr) { ++ok; } else { ++bad; } // -> (expr) + if (true == expr) { ++ok; } else { ++bad; } // -> (expr) + if (false == expr) { ++bad; } else { ++ok; } // -> unchanged + if (true != expr) { ++bad; } else { ++ok; } // -> unchanged + if (false != expr) { ++ok; } else { ++bad; } // -> (expr) + + // Test boolean short-circuiting with constants on the right side. + if (expr && true ) { ++ok; } else { ++bad; } // -> (expr) + if (expr && false) { ++bad; } else { ++ok; } // -> (false) -> block removed + if (expr ^^ true ) { ++bad; } else { ++ok; } // -> unchanged + if (expr ^^ false) { ++ok; } else { ++bad; } // -> (expr) + if (expr || true ) { ++ok; } else { ++bad; } // -> (true) + if (expr || false) { ++ok; } else { ++bad; } // -> (expr) + if (expr == true ) { ++ok; } else { ++bad; } // -> (expr) + if (expr == false) { ++bad; } else { ++ok; } // -> unchanged + if (expr != true ) { ++bad; } else { ++ok; } // -> unchanged + if (expr != false) { ++ok; } else { ++bad; } // -> (expr) + + return ok == 20 && bad == 0; +} + +half4 main() { + return test() ? half4(0,1,0,1) : half4(1,0,0,1); } diff --git a/tests/sksl/folding/golden/ShortCircuitBoolFolding.glsl b/tests/sksl/folding/golden/ShortCircuitBoolFolding.glsl index 94f49d287a..0d7782366c 100644 --- a/tests/sksl/folding/golden/ShortCircuitBoolFolding.glsl +++ b/tests/sksl/folding/golden/ShortCircuitBoolFolding.glsl @@ -1,28 +1,101 @@ -out vec4 sk_FragColor; -void main() { - bool expr1 = gl_FragCoord.x > 0.0; - bool expr2 = gl_FragCoord.y > 0.0; - if (expr1) { - sk_FragColor.x = 1.0; - } else if (true ^^ expr1) { - sk_FragColor.x = 3.0; - } else if (expr2) { - sk_FragColor.x = 4.0; - } else if (expr2) { - sk_FragColor.x = 5.0; +vec4 main() { + bool _1_expr = sqrt(1.0) > 0.0; + int _2_ok = 0; + int _3_bad = 0; + + if (_1_expr) { + ++_2_ok; } else { - sk_FragColor.x = 6.0; + ++_3_bad; } - if (expr1) { - sk_FragColor.x = 1.0; - } else if (expr1 ^^ true) { - sk_FragColor.x = 3.0; - } else if (expr2) { - sk_FragColor.x = 4.0; - } else if (expr2) { - sk_FragColor.x = 5.0; + { + ++_2_ok; + } + if (true ^^ _1_expr) { + ++_3_bad; } else { - sk_FragColor.x = 6.0; + ++_2_ok; } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + { + ++_2_ok; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + if (false == _1_expr) { + ++_3_bad; + } else { + ++_2_ok; + } + if (true != _1_expr) { + ++_3_bad; + } else { + ++_2_ok; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + { + ++_2_ok; + } + if (_1_expr ^^ true) { + ++_3_bad; + } else { + ++_2_ok; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + { + ++_2_ok; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + if (_1_expr == false) { + ++_3_bad; + } else { + ++_2_ok; + } + if (_1_expr != true) { + ++_3_bad; + } else { + ++_2_ok; + } + if (_1_expr) { + ++_2_ok; + } else { + ++_3_bad; + } + return _2_ok == 20 && _3_bad == 0 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0); + }