diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index 8dc66fd9614..2c1a4d39e5c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -5574,6 +5574,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/subjectAny.kt"); } + @Test + @TestMetadata("whenOr.kt") + public void testWhenOr() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt"); + } + @Test @TestMetadata("withoutElse.kt") public void testWithoutElse() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/SwitchGenerator.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/SwitchGenerator.kt index c7daf2809d6..9b39d0dc7e7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/SwitchGenerator.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/SwitchGenerator.kt @@ -237,11 +237,13 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf // action // } // + // fir2ir lowers the same to an or sequence: + // + // if (((subject == a) || (subject == b)) || (subject = c)) action + // // @return true if the conditions are equality checks of constants. private fun matchConditions(condition: IrExpression): ArrayList? { - if (condition is IrCall) { - return arrayListOf(condition) - } else if (condition is IrWhen && condition.origin == IrStatementOrigin.WHEN_COMMA) { + if (condition is IrWhen && condition.origin == IrStatementOrigin.WHEN_COMMA) { assert(condition.type.isBoolean()) { "WHEN_COMMA should always be a Boolean: ${condition.dump()}" } val candidates = ArrayList() @@ -268,6 +270,15 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf } return if (candidates.isNotEmpty()) candidates else return null + } else if (condition is IrCall && condition.symbol == codegen.context.irBuiltIns.ororSymbol) { + val candidates = ArrayList() + for (i in 0 until condition.valueArgumentsCount) { + val argument = condition.getValueArgument(i)!! + candidates += matchConditions(argument) ?: return null + } + return if (candidates.isNotEmpty()) candidates else return null + } else if (condition is IrCall) { + return arrayListOf(condition) } return null diff --git a/compiler/testData/codegen/bytecodeText/when/switchOptimizationDuplicates.kt b/compiler/testData/codegen/bytecodeText/when/switchOptimizationDuplicates.kt index 34f6596cb38..a6438315fb7 100644 --- a/compiler/testData/codegen/bytecodeText/when/switchOptimizationDuplicates.kt +++ b/compiler/testData/codegen/bytecodeText/when/switchOptimizationDuplicates.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo(x: Int): Int { return when (x) { 1, 1, 2 -> 1001 diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/bigEnum.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/bigEnum.kt index 0af7d4df73c..230eae422bb 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/bigEnum.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/bigEnum.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.test.assertEquals enum class BigEnum { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/duplicatingItems.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/duplicatingItems.kt index a2131007dc3..87e9d97c05a 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/duplicatingItems.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/duplicatingItems.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.test.assertEquals enum class Season { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/expression.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/expression.kt index 39424a42746..a1c4bc676c5 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/expression.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/expression.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.test.assertEquals enum class Season { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt index 07dcac76ee5..34dad145a32 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR package abc.foo enum class Season { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/nullability.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/nullability.kt index 47dbc05e968..4a4a6cc6340 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/nullability.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/nullability.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR enum class Season { WINTER, SPRING, diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt new file mode 100644 index 00000000000..7814ae5c799 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt @@ -0,0 +1,11 @@ +// IGNORE_BACKEND: JVM + +fun test(x: Int): String { + when { + x == 1 || x == 3 || x == 5 -> "135" + x == 2 || x == 4 || x == 6 -> "246" + else -> "other" + } +} + +// 1 TABLESWITCH diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/withoutElse.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/withoutElse.kt index c89597748a1..09e8377c0b4 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/withoutElse.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/withoutElse.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.test.assertEquals enum class Season { diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/duplicatingItems.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/duplicatingItems.kt index 21d45ba9699..15a2ebde392 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/duplicatingItems.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/duplicatingItems.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.test.assertEquals fun foo(x : String) : String { diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/expression.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/expression.kt index 083d03e5351..4831cfb6df9 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/expression.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/expression.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo(x : String) : String { return when (x) { "abc", "cde" -> "abc_cde" diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/inlineStringConstInsideWhen.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/inlineStringConstInsideWhen.kt index d55753d04cc..8563b273642 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/inlineStringConstInsideWhen.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/inlineStringConstInsideWhen.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR const val y = "cde" fun foo(x : String) : String { diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/nullability.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/nullability.kt index 3461ba0bb80..52905d3a900 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/nullability.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/nullability.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo1(x : String?) : String { when (x) { "abc", "cde" -> return "abc_cde" diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/sameHashCode.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/sameHashCode.kt index 2f4e7a773b8..f5f0d55b265 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/sameHashCode.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/sameHashCode.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo(x : String) : String { assert("abz]".hashCode() == "aby|".hashCode()) diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/statement.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/statement.kt index bf3aa834ba4..7e07e9961d7 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/statement.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/statement.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo1(x : String) : String { when (x) { "abc", "cde" -> return "abc_cde" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java index 2f284b56585..ae3c56d5cfd 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BytecodeTextTestGenerated.java @@ -5442,6 +5442,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/subjectAny.kt"); } + @Test + @TestMetadata("whenOr.kt") + public void testWhenOr() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt"); + } + @Test @TestMetadata("withoutElse.kt") public void testWithoutElse() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index db61e2845a4..05696042ddd 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -5574,6 +5574,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/subjectAny.kt"); } + @Test + @TestMetadata("whenOr.kt") + public void testWhenOr() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/whenOr.kt"); + } + @Test @TestMetadata("withoutElse.kt") public void testWithoutElse() throws Exception {