diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java index 9022174f85b..e9d6c4eae4f 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java @@ -2112,6 +2112,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt"); } + @TestMetadata("iincGeneration.kt") + public void testIincGeneration() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt"); + } + @TestMetadata("intrinsicArrayConstructorsUseCounterLoop.kt") public void testIntrinsicArrayConstructorsUseCounterLoop() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt"); diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index 658545d39e5..30bfaaacdab 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrLoop +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl import org.jetbrains.kotlin.ir.expressions.impl.IrWhileLoopImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -145,8 +146,8 @@ internal abstract class NumericForLoopHeader( inductionVariable.symbol, irCallOp( plusFun.symbol, plusFun.returnType, irGet(inductionVariable), - stepExpression - ) + stepExpression, IrStatementOrigin.PLUSEQ + ), IrStatementOrigin.PLUSEQ ) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt index c4e268088cb..ac4c18b8f92 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt @@ -152,8 +152,8 @@ fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) = fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type, variable.symbol) -fun IrBuilderWithScope.irSet(variable: IrValueSymbol, value: IrExpression) = - IrSetValueImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ) +fun IrBuilderWithScope.irSet(variable: IrValueSymbol, value: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.EQ) = + IrSetValueImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, origin) fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) = IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver) @@ -241,12 +241,14 @@ fun IrBuilderWithScope.irCall( callee: IrSimpleFunctionSymbol, type: IrType, valueArgumentsCount: Int = callee.owner.valueParameters.size, - typeArgumentsCount: Int = callee.owner.typeParameters.size + typeArgumentsCount: Int = callee.owner.typeParameters.size, + origin: IrStatementOrigin? = null ): IrCall = IrCallImpl( startOffset, endOffset, type, callee, typeArgumentsCount = typeArgumentsCount, - valueArgumentsCount = valueArgumentsCount + valueArgumentsCount = valueArgumentsCount, + origin = origin ) fun IrBuilderWithScope.irCall( @@ -298,9 +300,10 @@ fun IrBuilderWithScope.irCallOp( callee: IrSimpleFunctionSymbol, type: IrType, dispatchReceiver: IrExpression, - argument: IrExpression? = null + argument: IrExpression? = null, + origin: IrStatementOrigin? = null ): IrMemberAccessExpression<*> = - irCall(callee, type, valueArgumentsCount = if (argument != null) 1 else 0, typeArgumentsCount = 0).apply { + irCall(callee, type, valueArgumentsCount = if (argument != null) 1 else 0, typeArgumentsCount = 0, origin = origin).apply { this.dispatchReceiver = dispatchReceiver if (argument != null) putValueArgument(0, argument) diff --git a/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt b/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt new file mode 100644 index 00000000000..4a6c0e74ded --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME + +fun intRangeTo(a: Int, b: Int) { for (i in a .. b) {} } +fun intRangeToStep(a: Int, b: Int) { for (i in a .. b step 127) {} } // Uses IADD in non-IR +fun intDownTo(a: Int, b: Int) { for (i in a downTo b) {} } +fun intDownToStep(a: Int, b: Int) { for (i in a downTo b step 128) {} } // Uses IADD in non-IR +fun intUntil(a: Int, b: Int) { for (i in a until b) {} } + +fun byteRangeToByte(a: Byte, b: Byte) { for (i in a .. b) {} } +fun byteRangeToShort(a: Byte, b: Short) { for (i in a .. b) {} } +fun byteRangeToInt(a: Byte, b: Int) { for (i in a .. b) {} } +fun shortRangeToByte(a: Short, b: Byte) { for (i in a .. b) {} } +fun shortRangeToShort(a: Short, b: Short) { for (i in a .. b) {} } +fun shortRangeToInt(a: Short, b: Int) { for (i in a .. b) {} } +fun intRangeToByte(a: Int, b: Byte) { for (i in a .. b) {} } +fun intRangeToShort(a: Int, b: Short) { for (i in a .. b) {} } + +fun uIntRangeTo(a: UInt, b: UInt) { for (i in a .. b) {} } +fun uIntRangeToStep(a: UInt, b: UInt) { for (i in a .. b step 127) {} } // Uses IADD in non-IR +fun uIntDownTo(a: UInt, b: UInt) { for (i in a downTo b) {} } +fun uIntDownToStep(a: UInt, b: UInt) { for (i in a downTo b step 128) {} } // Uses IADD in non-IR +fun uIntUntil(a: UInt, b: UInt) { for (i in a until b) {} } + +fun uByteRangeTo(a: UByte, b: UByte) { for (i in a .. b) {} } +fun uShortRangeTo(a: UShort, b: UShort) { for (i in a .. b) {} } + +// 0 ISUB + +// JVM_TEMPLATES +// 4 IADD +// 16 IINC + +// JVM_IR_TEMPLATES +// 0 IADD +// 20 IINC diff --git a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt index f9ae02237c2..58773c2cae0 100644 --- a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt +++ b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt @@ -17,13 +17,5 @@ fun foo() { // 3 LLOAD // 1 MAXLOCALS = 10 // 0 InlineMarker - -// JVM_TEMPLATES -// fake inline variables occupy 7 ISTOREs. // 16 ISTORE // 11 ILOAD - -// JVM_IR_TEMPLATES -// JVM_IR generates an extra induction variable in 'for (i in 1..2)' (see KT-36837) -// 19 ISTORE -// 14 ILOAD diff --git a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt index 0d0438efde6..c050e0eb37b 100644 --- a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt +++ b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt @@ -18,13 +18,5 @@ fun test() { // 1 MAXLOCALS = 3 // 1 MAXLOCALS = 4 // 0 InlineMarker - -// JVM_TEMPLATES -// fake inline variables occupy 7 ISTOREs. // 14 ISTORE // 7 ILOAD - -// JVM_IR_TEMPLATES -// JVM_IR generates an extra induction variable in 'for (i in 1..2)' (see KT-36837) -// 17 ISTORE -// 10 ILOAD diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 50b8a261cb1..ca25a035116 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -2157,6 +2157,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt"); } + @TestMetadata("iincGeneration.kt") + public void testIincGeneration() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt"); + } + @TestMetadata("intrinsicArrayConstructorsUseCounterLoop.kt") public void testIntrinsicArrayConstructorsUseCounterLoop() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index ffa893a4e05..4e956cf706d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -2112,6 +2112,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt"); } + @TestMetadata("iincGeneration.kt") + public void testIincGeneration() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt"); + } + @TestMetadata("intrinsicArrayConstructorsUseCounterLoop.kt") public void testIntrinsicArrayConstructorsUseCounterLoop() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt");