From f9d2ca68ce2af9ae805eebcf83698eec5c4a3ad3 Mon Sep 17 00:00:00 2001 From: Andi Wenger Date: Wed, 28 Apr 2021 18:32:27 +0200 Subject: [PATCH] KJS IR: Fix KT-45738 - Consider recursive checkForPrimitiveOrPattern Recursive results from checkForPrimitiveOrPattern were ignored. If it found a case/condition that could not be optimized the resulting "false" was not propagated. This would lead to a "optimized" when without all conditions. - see KT-45738 - The return is now lifted out of the when to make it more obvious what is going on. - New test for mixed multiple conditions in when --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../js/transformers/irToJs/SwitchOptimizer.kt | 15 ++++++------- ...itchOptimizationMultipleMixedConditions.kt | 21 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++++ 10 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 4278b2f793b..6a91191e7c0 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -41640,6 +41640,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @Test + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @Test @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt index e2df0e276ff..1dbd6d2fa41 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/SwitchOptimizer.kt @@ -69,16 +69,17 @@ class SwitchOptimizer(private val context: JsGenerationContext, private val last if (constExpr !is IrConst<*>) return false if (!constExpr.isTrueConstant()) return false - when (branchExpr) { + return when (branchExpr) { is IrWhen -> checkForPrimitiveOrPattern(branchExpr, constants) - is IrCall -> { - val constant = tryToExtractEqeqeqConst(branchExpr) ?: return false - constants += constant + is IrCall -> when (val constant = tryToExtractEqeqeqConst(branchExpr)) { + null -> false + else -> { + constants += constant + true + } } - else -> return false + else -> false } - - return true } if (!checkBranchIsOrPattern(thenBranch.result, thenBranch.condition)) return false diff --git a/compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt b/compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt new file mode 100644 index 00000000000..d600955f52a --- /dev/null +++ b/compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt @@ -0,0 +1,21 @@ +private fun parse(text: String) = when (text) { + Numbers.One.name, "one", "1" -> 1 + Numbers.Two.name, "two", "2" -> 2 + else -> -1 +} + +enum class Numbers { + One, + Two, +} + +fun box(): String { + + val oneParsed = parse("one") + if (oneParsed != 1) return "'one' should map to '1' but was $oneParsed" + + val OneParsed = parse("One") + if (OneParsed != 1) return "'One' should map to '1' but was $OneParsed" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 89ed7329b02..9fdf84b679f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -41616,6 +41616,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @Test + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @Test @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index bf06950b4f1..36a21add5b3 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -41640,6 +41640,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @Test + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @Test @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4de37d7755f..2960a9cb411 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -33494,6 +33494,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { runTest("compiler/testData/codegen/box/when/switchOptimizationSingleStatementCase.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 84547c33d1f..9882a9fafe2 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -28124,6 +28124,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { runTest("compiler/testData/codegen/box/when/switchOptimizationSingleStatementCase.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 84a5e6c6981..f34764eb6b6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -27535,6 +27535,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { runTest("compiler/testData/codegen/box/when/switchOptimizationSingleStatementCase.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 98f03a63f13..37a11816b3a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -27495,6 +27495,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleConditions.kt"); } + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { runTest("compiler/testData/codegen/box/when/switchOptimizationSingleStatementCase.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index d67b61f2574..82c78baefe3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -15568,6 +15568,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/when/switchOptimizationDuplicates.kt"); } + @TestMetadata("switchOptimizationMultipleMixedConditions.kt") + public void testSwitchOptimizationMultipleMixedConditions() throws Exception { + runTest("compiler/testData/codegen/box/when/switchOptimizationMultipleMixedConditions.kt"); + } + @TestMetadata("switchOptimizationSingleStatementCase.kt") public void testSwitchOptimizationSingleStatementCase() throws Exception { runTest("compiler/testData/codegen/box/when/switchOptimizationSingleStatementCase.kt");