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 1491427a738..a356bcfb615 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 @@ -1234,6 +1234,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/arrays/forInReversed"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("reversedArray.kt") + public void testReversedArray() throws Exception { + runTest("compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt"); + } + @Test @TestMetadata("reversedArrayOriginalUpdatedInLoopBody.kt") public void testReversedArrayOriginalUpdatedInLoopBody() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt index 5c1aaaf61fc..c5ce749257c 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/handlers/IndexedGetIterationHandlers.kt @@ -10,12 +10,15 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.loops.ExpressionHandler import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo import org.jetbrains.kotlin.backend.common.lower.loops.IndexedGetHeaderInfo +import org.jetbrains.kotlin.backend.common.lower.matchers.Quantifier import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher +import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irInt import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* @@ -75,7 +78,21 @@ internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGet private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays override fun matchIterable(expression: IrExpression) = - expression.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) } + expression.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) } || + expression.run { + this is IrCall && reversedArrayMatcher(this) + } + + private val reversedArrayMatcher = + createIrCallMatcher(Quantifier.ANY) { + callee { + fqName { it == FqName("kotlin.collections.reversed") } + extensionReceiver { + it != null && it.type.run { isArray() || isPrimitiveArray() } + } + parameterCount { it == 0 } + } + } override val IrType.sizePropertyGetter get() = getClass()!!.getPropertyGetter("size")!!.owner diff --git a/compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt b/compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt new file mode 100644 index 00000000000..a9558493100 --- /dev/null +++ b/compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt @@ -0,0 +1,33 @@ +// TARGET_BACKEND: JVM_IR +// WITH_STDLIB +import kotlin.test.* + +fun box(): String { + testReversed() + testReversedArray() + return "OK" +} + +fun testReversed() { + val arr = intArrayOf(6, 7, 8, 9) + var result = "" + for (i in arr.reversed()) { + arr[0] = 0 + result += i + } + assertEquals("9876", result) +} + +fun testReversedArray() { + val arr = intArrayOf(6, 7, 8, 9) + var result = "" + for (i in arr.reversedArray()) { + arr[0] = 0 + result += i + } + assertEquals("9876", result) +} + +// CHECK_BYTECODE_TEXT +// 0 java/util/List.iterator +// 2 IINC \ No newline at end of file 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 5b7acbf9434..a7041d3efc0 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 @@ -1234,6 +1234,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/arrays/forInReversed"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("reversedArray.kt") + public void testReversedArray() throws Exception { + runTest("compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt"); + } + @Test @TestMetadata("reversedArrayOriginalUpdatedInLoopBody.kt") public void testReversedArrayOriginalUpdatedInLoopBody() throws Exception {