diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt index b8fd0bf4318..3fd9b7912bd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InplaceArgumentsMethodTransformer.kt @@ -52,11 +52,15 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { val argStartMarker: AbstractInsnNode, val argEndMarker: AbstractInsnNode, val calls: List, - val storeInsn: VarInsnNode + val storeInsn: VarInsnNode? ) { - val loadOpcode = storeInsn.opcode - Opcodes.ISTORE + Opcodes.ILOAD + val loadOpcode = + if (storeInsn != null) + storeInsn.opcode - Opcodes.ISTORE + Opcodes.ILOAD + else + -1 - val varIndex = storeInsn.`var` + val varIndex = storeInsn?.`var` ?: -1 } private fun parseMethodOrNull(methodNode: MethodNode): MethodContext? { @@ -114,11 +118,19 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() { calls.add(parseCall(methodNode, insn, iter)) insn.isInplaceArgumentEndMarker() -> { val next = insn.next - if (next is VarInsnNode && next.opcode in Opcodes.ISTORE..Opcodes.ASTORE) { - iter.next() - return ArgContext(start, insn, calls, next) - } else { - throw ParseErrorException() + return when { + next is VarInsnNode && next.opcode in Opcodes.ISTORE..Opcodes.ASTORE -> { + iter.next() + ArgContext(start, insn, calls, next) + } + insn.previous.isInplaceArgumentStartMarker() -> { + // Empty argument - a remapped variable. + // For such argument varIndex would be '-1', so it would not be associated with any LOAD instruction. + ArgContext(start, insn, calls, null) + } + else -> { + throw ParseErrorException() + } } } insn.isInplaceCallEndMarker() || insn.isInplaceArgumentStartMarker() -> 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 8a59aa02aaf..9e6a0da7691 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 @@ -3428,6 +3428,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("kotlinMathMax.kt") + public void testKotlinMathMax() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt"); + } + @Test @TestMetadata("println.kt") public void testPrintln() throws Exception { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt index ae877a7b5b9..166d3d7eaad 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt @@ -32,8 +32,8 @@ fun box(): String { // 0 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl -// 21 ILOAD -// 13 ISTORE +// 15 ILOAD +// 7 ISTORE // 1 IADD // 0 ISUB // 0 IINC diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt index 9d15f53cffc..21c1165ae07 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt @@ -42,8 +42,8 @@ fun box(): String { // 1 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl -// 25 ILOAD -// 15 ISTORE +// 19 ILOAD +// 9 ISTORE // 1 IADD // 0 ISUB // 0 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt index b17e587dd76..f916dac4b5f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt @@ -40,8 +40,8 @@ fun box(): String { // 0 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl -// 12 ILOAD -// 9 ISTORE +// 8 ILOAD +// 5 ISTORE // 0 IADD // 0 ISUB // 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt b/compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt new file mode 100644 index 00000000000..b32e0e9267a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +fun vectorReductionMax(vA: DoubleArray): Double { + val n = vA.size + var x = Double.NEGATIVE_INFINITY + for (i in 0 until n) { + x = kotlin.math.max(x, vA[i]) + } + return x +} + +// JVM_IR_TEMPLATES +// Make sure there's no intermediate variable created for 'vA[i]' argument of kotlin.math.max. +// 2 DLOAD +// 2 DSTORE 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 7e18d81788d..4bd40099333 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 @@ -3284,6 +3284,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @Test + @TestMetadata("kotlinMathMax.kt") + public void testKotlinMathMax() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt"); + } + @Test @TestMetadata("println.kt") public void testPrintln() 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 e111da59da3..0e6dcc48f74 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 @@ -3428,6 +3428,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("kotlinMathMax.kt") + public void testKotlinMathMax() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt"); + } + @Test @TestMetadata("println.kt") public void testPrintln() throws Exception {