diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt index d9abad199c8..67986deb18b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt @@ -44,22 +44,24 @@ val forLoopsPhase = makeIrFilePhase( * } * ``` * We transform it into one of the following loops: - * * ``` * // 1. If the induction variable cannot overflow, i.e., `B` is const and != MAX_VALUE (if increasing, or MIN_VALUE if decreasing). * * var inductionVar = A - * var last = B - * while (inductionVar <= last) { // (`inductionVar >= last` if the progression is decreasing) - * val loopVar = inductionVar - * inductionVar++ // (`inductionVar--` if the progression is decreasing) - * // Loop body + * val last = B + * if (inductionVar <= last) { // (`inductionVar >= last` if the progression is decreasing) + * // Loop is not empty + * do { + * val loopVar = inductionVar + * inductionVar++ // (`inductionVar--` if the progression is decreasing) + * // Loop body + * } while (inductionVar <= last) * } * * // 2. If the induction variable CAN overflow, i.e., `last` is not const or is MAX/MIN_VALUE: * * var inductionVar = A - * var last = B + * val last = B * if (inductionVar <= last) { // (`inductionVar >= last` if the progression is decreasing) * // Loop is not empty * do { @@ -68,15 +70,18 @@ val forLoopsPhase = makeIrFilePhase( * // Loop body * } while (loopVar != last) * } - * - * // 3. If loop is an until loop (e.g., `for (i in A until B)`), it cannot overflow and we use `<` for comparisons: - * + * ``` + * If loop is an until loop (e.g., `for (i in A until B)`), it is transformed into: + * ``` * var inductionVar = A - * var last = B - * while (inductionVar < last) { - * val loopVar = inductionVar - * inductionVar++ - * // Loop body + * val last = B - 1 + * if (inductionVar <= last && B != MIN_VALUE) { + * // Loop is not empty + * do { + * val loopVar = inductionVar + * inductionVar++ + * // Loop body + * } while (inductionVar <= last) * } * ``` * In case of iteration over an array (e.g., `for (i in array)`), we transform it into the following: @@ -221,7 +226,7 @@ private class RangeLoopTransformer( // inductionVariable = inductionVariable + step return with(context.createIrBuilder(getScopeOwnerSymbol(), initializer.startOffset, initializer.endOffset)) { variable.initializer = forLoopInfo.initializeLoopVariable(symbols, this) - val increment = forLoopInfo.buildIncrementInductionVariableExpression(this) + val increment = forLoopInfo.incrementInductionVariable(this) IrCompositeImpl( variable.startOffset, variable.endOffset, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt index bc618843165..e2c542bb505 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt @@ -12,16 +12,10 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrConst -import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isSubtypeOfClass -import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -31,7 +25,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult // TODO: Handle UIntProgression, ULongProgression /** Represents a progression type in the Kotlin stdlib. */ -enum class ProgressionType(val elementCastFunctionName: Name, val stepCastFunctionName: Name) { +internal enum class ProgressionType(val elementCastFunctionName: Name, val stepCastFunctionName: Name) { INT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt")), LONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong")), CHAR_PROGRESSION(Name.identifier("toChar"), Name.identifier("toInt")); @@ -59,7 +53,19 @@ enum class ProgressionType(val elementCastFunctionName: Name, val stepCastFuncti } } -internal enum class ProgressionDirection { DECREASING, INCREASING, UNKNOWN } +internal enum class ProgressionDirection { + DECREASING { + override fun asReversed() = INCREASING + }, + INCREASING { + override fun asReversed() = DECREASING + }, + UNKNOWN { + override fun asReversed() = UNKNOWN + }; + + abstract fun asReversed(): ProgressionDirection +} /** Information about a loop that is required by [HeaderProcessor] to build a [ForLoopHeader]. */ internal sealed class HeaderInfo( @@ -67,25 +73,13 @@ internal sealed class HeaderInfo( val first: IrExpression, val last: IrExpression, val step: IrExpression, - val isFirstInclusive: Boolean, - val isLastInclusive: Boolean, - val isReversed: Boolean + val isReversed: Boolean, + val direction: ProgressionDirection, + val additionalNotEmptyCondition: IrExpression? ) { - val direction: ProgressionDirection by lazy { - // If step is a constant (either Int or Long), then we can determine the direction. - val stepValue = (step as? IrConst<*>)?.value as? Number - val stepValueAsLong = stepValue?.toLong() - when { - stepValueAsLong == null -> ProgressionDirection.UNKNOWN - stepValueAsLong < 0L -> ProgressionDirection.DECREASING - stepValueAsLong > 0L -> ProgressionDirection.INCREASING - else -> ProgressionDirection.UNKNOWN - } - } - /** * Returns a copy of this [HeaderInfo] with the values reversed. - * I.e., first and last (and their inclusiveness) are swapped, step is negated. + * I.e., first and last are swapped, step is negated. * Returns null if the iterable cannot be iterated in reverse. */ abstract fun asReversed(): HeaderInfo? @@ -97,23 +91,18 @@ internal class ProgressionHeaderInfo( first: IrExpression, last: IrExpression, step: IrExpression, - isFirstInclusive: Boolean = true, - isLastInclusive: Boolean = true, isReversed: Boolean = false, + canOverflow: Boolean? = null, + direction: ProgressionDirection, + additionalNotEmptyCondition: IrExpression? = null, val additionalVariables: List = listOf() -) : HeaderInfo(progressionType, first, last, step, isFirstInclusive, isLastInclusive, isReversed) { +) : HeaderInfo(progressionType, first, last, step, isReversed, direction, additionalNotEmptyCondition) { val canOverflow: Boolean by lazy { - // Last-exclusive progressions can never overflow. - if (!isLastInclusive) return@lazy false + if (canOverflow != null) return@lazy canOverflow // Induction variable can overflow if it is not a const, or is MAX/MIN_VALUE (depending on direction). - val lastValue = (last as? IrConst<*>)?.value - val lastValueAsLong = when (lastValue) { - is Number -> lastValue.toLong() - is Char -> lastValue.toLong() - else -> return@lazy true // If "last" is not a const Number or Char. - } + val lastValueAsLong = last.constLongValue ?: return@lazy true // If "last" is not a const Number or Char. val constLimitAsLong = when (direction) { ProgressionDirection.UNKNOWN -> // If we don't know the direction, we can't be sure which limit to use. @@ -139,9 +128,9 @@ internal class ProgressionHeaderInfo( first = last, last = first, step = step.negate(), - isFirstInclusive = isLastInclusive, - isLastInclusive = isFirstInclusive, isReversed = !isReversed, + direction = direction.asReversed(), + additionalNotEmptyCondition = additionalNotEmptyCondition, additionalVariables = additionalVariables ) } @@ -157,9 +146,9 @@ internal class ArrayHeaderInfo( first, last, step, - isFirstInclusive = true, - isLastInclusive = false, - isReversed = false + isReversed = false, + direction = ProgressionDirection.INCREASING, + additionalNotEmptyCondition = null ) { // Technically one can easily iterate over an array in reverse by swapping first/last and // negating the step. However, Array.reversed() and Array.reversedArray() return a collection @@ -177,21 +166,6 @@ internal class ArrayHeaderInfo( override fun asReversed(): HeaderInfo? = null } -/** Return the negated value if the expression is const, otherwise call unaryMinus(). */ -private fun IrExpression.negate(): IrExpression { - val stepValue = (this as? IrConst<*>)?.value as? Number - return when (stepValue) { - is Int -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Int, -stepValue) - is Long -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Long, -stepValue) - else -> { - val unaryMinusFun = type.getClass()!!.functions.first { it.name.asString() == "unaryMinus" } - IrCallImpl(startOffset, endOffset, type, unaryMinusFun.symbol, unaryMinusFun.descriptor).apply { - dispatchReceiver = this@negate - } - } - } -} - /** Matches an iterable expression and builds a [HeaderInfo] from the expression. */ internal interface HeaderInfoHandler { /** Returns true if the handler can build a [HeaderInfo] from the expression. */ @@ -227,7 +201,13 @@ internal class HeaderInfoBuilder(context: CommonBackendContext, private val scop private val symbols = context.ir.symbols // TODO: Include unsigned types - private val progressionElementTypes = symbols.integerClassesTypes + context.irBuiltIns.char + private val progressionElementTypes = listOf( + context.irBuiltIns.byteType, + context.irBuiltIns.shortType, + context.irBuiltIns.intType, + context.irBuiltIns.longType, + context.irBuiltIns.charType + ) private val progressionHandlers = listOf( IndicesHandler(context), 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 8bf208eb239..b6782491c38 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 @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.common.lower.irComposite import org.jetbrains.kotlin.backend.common.lower.irIfThen import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* @@ -18,13 +17,11 @@ 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.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl import org.jetbrains.kotlin.ir.expressions.impl.IrWhileLoopImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.functions -import org.jetbrains.kotlin.name.Name /** * Contains the loop and expression to replace the old loop. @@ -44,7 +41,8 @@ internal sealed class ForLoopHeader( val inductionVariable: IrVariable, val last: IrVariable, val step: IrVariable, - var loopVariable: IrVariable? = null + var loopVariable: IrVariable? = null, + val isLastInclusive: Boolean ) { /** Expression used to initialize the loop variable at the beginning of the loop. */ abstract fun initializeLoopVariable(symbols: Symbols, builder: DeclarationIrBuilder): IrExpression @@ -55,17 +53,34 @@ internal sealed class ForLoopHeader( /** Builds a new loop from the old loop. */ abstract fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement + /** Statement used to increment the induction variable. */ + fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) { + // inductionVariable = inductionVariable + step + val plusFun = inductionVariable.type.getClass()!!.functions.first { + it.name.asString() == "plus" && + it.valueParameters.size == 1 && + it.valueParameters[0].type == step.type + } + irSetVar( + inductionVariable.symbol, irCallOp( + plusFun.symbol, plusFun.returnType, + irGet(inductionVariable), + irGet(step) + ) + ) + } + protected fun buildLoopCondition(builder: DeclarationIrBuilder): IrExpression = with(builder) { val builtIns = context.irBuiltIns val progressionType = headerInfo.progressionType val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType() val compFun = - if (headerInfo.isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!! + if (isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!! else builtIns.lessFunByOperandType[progressionKotlinType]!! // The default condition depends on the direction. - return when (headerInfo.direction) { + when (headerInfo.direction) { ProgressionDirection.DECREASING -> // last <= inductionVar (use `<` if last is exclusive) irCall(compFun).apply { @@ -114,7 +129,7 @@ internal class ProgressionLoopHeader( inductionVariable: IrVariable, last: IrVariable, step: IrVariable -) : ForLoopHeader(headerInfo, inductionVariable, last, step) { +) : ForLoopHeader(headerInfo, inductionVariable, last, step, isLastInclusive = true) { override fun initializeLoopVariable(symbols: Symbols, builder: DeclarationIrBuilder) = with(builder) { // loopVariable = inductionVariable @@ -135,9 +150,9 @@ internal class ProgressionLoopHeader( (if (headerInfo.isReversed) listOf(last, inductionVariable) else listOf(inductionVariable, last)) + step - override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement { + override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?) = with(builder) { - var (newLoop, replacementExpression) = if (headerInfo.canOverflow) { + val newLoop = if (headerInfo.canOverflow) { // If the induction variable CAN overflow, we cannot use it in the loop condition. Loop is lowered into something like: // // if (inductionVar <= last) { @@ -148,46 +163,37 @@ internal class ProgressionLoopHeader( // // Loop body // } while (loopVar != last) // } - assert(loopVariable != null) - val booleanNotFun = context.irBuiltIns.booleanClass.functions.first { it.owner.name.asString() == "not" } - val newCondition = irCallOp(booleanNotFun, booleanNotFun.owner.returnType, irCall(context.irBuiltIns.eqeqSymbol).apply { - putValueArgument(0, irGet(loopVariable!!)) - putValueArgument(1, irGet(last)) - }) - val newLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { + IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { label = oldLoop.label - condition = newCondition + condition = irNotEquals(irGet(loopVariable!!), irGet(last)) body = newBody } - val notEmptyCheck = irIfThen(buildLoopCondition(builder), newLoop) - LoopReplacement(newLoop, notEmptyCheck) } else { - // If the induction variable can NOT overflow, use a simple while loop. Loop is lowered into something like: + // If the induction variable can NOT overflow, use a do-while loop. Loop is lowered into something like: // - // while (inductionVar <= last) { - // val loopVar = inductionVar - // inductionVar += step - // // Loop body + // if (inductionVar <= last) { + // do { + // val loopVar = inductionVar + // inductionVar += step + // // Loop body + // } while (inductionVar <= last) // } - val newLoop = IrWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { + // + // Even though this can be simplified into a simpler while loop, using if + do-while (i.e., doing a loop inversion) + // performs better in benchmarks. In cases where `last` is a constant, the `if` may be optimized away. + IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { label = oldLoop.label condition = buildLoopCondition(this@with) body = newBody } - LoopReplacement(newLoop, newLoop) } - if (!headerInfo.isFirstInclusive) { - // Pre-increment the induction variable. - replacementExpression = irComposite(replacementExpression) { - +buildIncrementInductionVariableExpression(this@with) - +replacementExpression - } - } - - return LoopReplacement(newLoop, replacementExpression) + val loopCondition = buildLoopCondition(this@with) + // Combine with the additional "not empty" condition, if any. + val notEmptyCheck = + irIfThen(headerInfo.additionalNotEmptyCondition?.let { context.andand(it, loopCondition) } ?: loopCondition, newLoop) + LoopReplacement(newLoop, notEmptyCheck) } - } } internal class ArrayLoopHeader( @@ -195,7 +201,7 @@ internal class ArrayLoopHeader( inductionVariable: IrVariable, last: IrVariable, step: IrVariable -) : ForLoopHeader(headerInfo, inductionVariable, last, step) { +) : ForLoopHeader(headerInfo, inductionVariable, last, step, isLastInclusive = false) { override fun initializeLoopVariable(symbols: Symbols, builder: DeclarationIrBuilder) = with(builder) { // inductionVar = loopVar[inductionVariable] @@ -224,14 +230,7 @@ internal class ArrayLoopHeader( condition = buildLoopCondition(this@with) body = newBody } - val replacementExpression = if (!headerInfo.isFirstInclusive) { - // Pre-increment the induction variable. - irComposite(newLoop) { - +buildIncrementInductionVariableExpression(this@with) - +newLoop - } - } else newLoop - LoopReplacement(newLoop, replacementExpression) + LoopReplacement(newLoop, newLoop) } } @@ -340,30 +339,4 @@ internal class HeaderProcessor( } else { expression } - - private fun IrExpression.castIfNecessary(targetType: IrType, numberCastFunctionName: Name): IrExpression { - return if (type.toKotlinType() == targetType.toKotlinType()) { - this - } else { - val function = type.getClass()!!.functions.first { it.name == numberCastFunctionName } - IrCallImpl(startOffset, endOffset, function.returnType, function.symbol) - .apply { dispatchReceiver = this@castIfNecessary } - } - } } - -internal fun ForLoopHeader.buildIncrementInductionVariableExpression(builder: DeclarationIrBuilder): IrExpression = with(builder) { - // inductionVariable = inductionVariable + step - val plusFun = inductionVariable.type.getClass()!!.functions.first { - it.name.asString() == "plus" && - it.valueParameters.size == 1 && - it.valueParameters[0].type.toKotlinType() == step.type.toKotlinType() - } - irSetVar( - inductionVariable.symbol, irCallOp( - plusFun.symbol, plusFun.returnType, - irGet(inductionVariable), - irGet(step) - ) - ) -} \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt index 37e12f6b228..ef98d335bab 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt @@ -11,31 +11,31 @@ 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.backend.common.lower.matchers.singleArgumentExtension -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -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.builders.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +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.symbols.IrSymbol +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.getClass +import org.jetbrains.kotlin.ir.types.isArray import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.util.properties import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.SimpleType /** Builds a [HeaderInfo] for progressions built using the `rangeTo` function. */ -internal class RangeToHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : +internal class RangeToHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : ProgressionHandler { override val matcher = SimpleCalleeMatcher { - dispatchReceiver { it != null && it.type.toKotlinType() in progressionElementTypes } + dispatchReceiver { it != null && it.type in progressionElementTypes } fqName { it.pathSegments().last() == Name.identifier("rangeTo") } parameterCount { it == 1 } - parameter(0) { it.type.toKotlinType() in progressionElementTypes } + parameter(0) { it.type in progressionElementTypes } } override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol) = @@ -44,19 +44,20 @@ internal class RangeToHandler(private val context: CommonBackendContext, private data, first = expression.dispatchReceiver!!, last = expression.getValueArgument(0)!!, - step = irInt(1) + step = irInt(1), + direction = ProgressionDirection.INCREASING ) } } /** Builds a [HeaderInfo] for progressions built using the `downTo` extension function. */ -internal class DownToHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : +internal class DownToHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : ProgressionHandler { override val matcher = SimpleCalleeMatcher { singleArgumentExtension(FqName("kotlin.ranges.downTo"), progressionElementTypes) parameterCount { it == 1 } - parameter(0) { it.type.toKotlinType() in progressionElementTypes } + parameter(0) { it.type in progressionElementTypes } } override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = @@ -65,64 +66,193 @@ internal class DownToHandler(private val context: CommonBackendContext, private data, first = expression.extensionReceiver!!, last = expression.getValueArgument(0)!!, - step = irInt(-1) + step = irInt(-1), + direction = ProgressionDirection.DECREASING ) } } /** Builds a [HeaderInfo] for progressions built using the `until` extension function. */ -internal class UntilHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : +internal class UntilHandler(private val context: CommonBackendContext, private val progressionElementTypes: Collection) : ProgressionHandler { override val matcher = SimpleCalleeMatcher { singleArgumentExtension(FqName("kotlin.ranges.until"), progressionElementTypes) parameterCount { it == 1 } - parameter(0) { it.type.toKotlinType() in progressionElementTypes } + parameter(0) { it.type in progressionElementTypes } } override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { + // `A until B` is essentially the same as `A .. (B-1)`. However, B could be MIN_VALUE and hence `(B-1)` could underflow. + // If B is MIN_VALUE, then `A until B` is an empty range. We handle this special case be adding an additional "not empty" + // condition in the lowered for-loop. Therefore the following for-loop: + // + // for (i in A until B) { // Loop body } + // + // is lowered into: + // + // var inductionVar = A + // val last = B - 1 + // if (inductionVar <= last && B != MIN_VALUE) { + // // Loop is not empty + // do { + // val loopVar = inductionVar + // inductionVar++ + // // Loop body + // } while (inductionVar <= last) + // } + // + // However, `B` may be an expression with side-effects that should only be evaluated once, and `A` may also have side-effects. + // They are evaluated once and in the correct order (`A` then `B`), the final lowered form is: + // + // // Additional variables + // val untilReceiverValue = A + // val untilArg = B + // // Standard form of loop over progression + // var inductionVar = untilReceiverValue + // val last = untilArg - 1 + // if (inductionVar <= last && untilFunArg != MIN_VALUE) { + // // Loop is not empty + // do { + // val loopVar = inductionVar + // inductionVar++ + // // Loop body + // } while (inductionVar <= last) + // } + val receiverValue = expression.extensionReceiver!! + val untilArg = expression.getValueArgument(0)!! + + // Ensure that the argument conforms to the progression type before we decrement. + val untilArgCasted = untilArg.castIfNecessary( + data.elementType(context.irBuiltIns), + data.elementCastFunctionName + ) + + // To reduce local variable usage, we create and use temporary variables only if necessary. + var receiverValueVar: IrVariable? = null + var untilArgVar: IrVariable? = null + var additionalVariables = emptyList() + if (untilArg.canHaveSideEffects) { + if (receiverValue.canHaveSideEffects) { + receiverValueVar = scope.createTemporaryVariable(receiverValue, nameHint = "untilReceiverValue") + } + untilArgVar = scope.createTemporaryVariable(untilArgCasted, nameHint = "untilArg") + additionalVariables = listOfNotNull(receiverValueVar, untilArgVar) + } + + val first = if (receiverValueVar == null) receiverValue else irGet(receiverValueVar) + val untilArgExpression = if (untilArgVar == null) untilArgCasted else irGet(untilArgVar) + val last = untilArgExpression.decrement() + + val (minValueAsLong, minValueIrConst) = + when (data) { + ProgressionType.INT_PROGRESSION -> Pair(Int.MIN_VALUE.toLong(), irInt(Int.MIN_VALUE)) + ProgressionType.CHAR_PROGRESSION -> Pair(Char.MIN_VALUE.toLong(), irChar(Char.MIN_VALUE)) + ProgressionType.LONG_PROGRESSION -> Pair(Long.MIN_VALUE, irLong(Long.MIN_VALUE)) + } + val additionalNotEmptyCondition = untilArg.constLongValue.let { + when { + it == null && isAdditionalNotEmptyConditionNeeded(receiverValue.type, untilArg.type) -> + // Condition is needed and untilArg is non-const. + // Build the additional "not empty" condition: `untilArg != MIN_VALUE`. + irNotEquals(untilArgExpression, minValueIrConst) + it == minValueAsLong -> + // Hardcode "false" as additional condition so that the progression is considered empty. + // The entire lowered loop becomes a candidate for dead code elimination, depending on backend. + irFalse() + else -> + // We know that untilArg != MIN_VALUE, so the additional condition is not necessary. + null + } + } + ProgressionHeaderInfo( data, - first = expression.extensionReceiver!!, - last = expression.getValueArgument(0)!!, + first = first, + last = last, step = irInt(1), - isLastInclusive = false + canOverflow = false, + additionalVariables = additionalVariables, + additionalNotEmptyCondition = additionalNotEmptyCondition, + direction = ProgressionDirection.INCREASING ) } + + private fun isAdditionalNotEmptyConditionNeeded(receiverType: IrType, argType: IrType): Boolean { + // Here are the available `until` extension functions: + // + // infix fun Char.until(to: Char): CharRange + // infix fun Byte.until(to: Byte): IntRange + // infix fun Byte.until(to: Short): IntRange + // infix fun Byte.until(to: Int): IntRange + // infix fun Byte.until(to: Long): LongRange + // infix fun Short.until(to: Byte): IntRange + // infix fun Short.until(to: Short): IntRange + // infix fun Short.until(to: Int): IntRange + // infix fun Short.until(to: Long): LongRange + // infix fun Int.until(to: Byte): IntRange + // infix fun Int.until(to: Short): IntRange + // infix fun Int.until(to: Int): IntRange + // infix fun Int.until(to: Long): LongRange + // infix fun Long.until(to: Byte): LongRange + // infix fun Long.until(to: Short): LongRange + // infix fun Long.until(to: Int): LongRange + // infix fun Long.until(to: Long): LongRange + // + // The combinations where the range element type is strictly larger than the argument type do NOT need the additional condition. + // In such combinations, there is no possibility of underflow when the argument (casted to the range element type) is decremented. + // For unexpected combinations that currently don't exist (e.g., Int until Char), we assume the check is needed to be safe. + // TODO: Include unsigned types + return with(context.irBuiltIns) { + when (receiverType) { + charType -> true + byteType, shortType, intType -> when (argType) { + byteType, shortType -> false + else -> true + } + longType -> when (argType) { + byteType, shortType, intType -> false + else -> true + } + else -> true + } + } + } } /** Builds a [HeaderInfo] for progressions built using the `indices` extension property. */ -internal class IndicesHandler(val context: CommonBackendContext) : ProgressionHandler { +internal class IndicesHandler(private val context: CommonBackendContext) : ProgressionHandler { override val matcher = SimpleCalleeMatcher { // TODO: Handle Collection<*>.indices // TODO: Handle CharSequence.indices - extensionReceiver { it != null && KotlinBuiltIns.isArrayOrPrimitiveArray(it.type.toKotlinType()) } + extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() } } fqName { it == FqName("kotlin.collections.") } parameterCount { it == 0 } } override fun build(expression: IrCall, data: ProgressionType, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { - // `last = array.size` for the loop `for (i in array.indices)`. + // `last = array.size - 1` (last is inclusive) for the loop `for (i in array.indices)`. val arraySizeProperty = expression.extensionReceiver!!.type.getClass()!!.properties.first { it.name.asString() == "size" } val last = irCall(arraySizeProperty.getter!!).apply { dispatchReceiver = expression.extensionReceiver - } + }.decrement() ProgressionHeaderInfo( data, first = irInt(0), last = last, step = irInt(1), - isLastInclusive = false + canOverflow = false, + direction = ProgressionDirection.INCREASING ) } } /** Builds a [HeaderInfo] for calls to reverse an iterable. */ -internal class ReversedHandler(context: CommonBackendContext, val visitor: IrElementVisitor) : +internal class ReversedHandler(context: CommonBackendContext, private val visitor: IrElementVisitor) : HeaderInfoFromCallHandler { private val symbols = context.ir.symbols @@ -154,7 +284,7 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { // Directly use the `first/last/step` properties of the progression. - val progression = scope.createTemporaryVariable(expression) + val progression = scope.createTemporaryVariable(expression, nameHint = "progression") val progressionClass = progression.type.getClass()!! val firstProperty = progressionClass.properties.first { it.name.asString() == "first" } val first = irCall(firstProperty.getter!!).apply { @@ -174,7 +304,8 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte first, last, step, - additionalVariables = listOf(progression) + additionalVariables = listOf(progression), + direction = ProgressionDirection.UNKNOWN ) } } @@ -182,7 +313,7 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte /** Builds a [HeaderInfo] for arrays. */ internal class ArrayIterationHandler(private val context: CommonBackendContext) : ExpressionHandler { - override fun match(expression: IrExpression) = KotlinBuiltIns.isArrayOrPrimitiveArray(expression.type.toKotlinType()) + override fun match(expression: IrExpression) = expression.type.run { isArray() || isPrimitiveArray() } override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? = with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) { @@ -206,7 +337,7 @@ internal class ArrayIterationHandler(private val context: CommonBackendContext) origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE ) - // `last = array.size` for the loop `for (i in array.indices)`. + // `last = array.size` (last is exclusive) for the loop `for (i in array.indices)`. val arraySizeProperty = arrayReference.type.getClass()!!.properties.first { it.name.asString() == "size" } val last = irCall(arraySizeProperty.getter!!).apply { dispatchReceiver = irGet(arrayReference) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt new file mode 100644 index 00000000000..108102e6b3b --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.lower.loops + +import org.jetbrains.kotlin.ir.expressions.IrConst +import org.jetbrains.kotlin.ir.expressions.IrConstKind +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetValue +import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.getClass +import org.jetbrains.kotlin.ir.util.functions +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.OperatorNameConventions + +internal fun IrExpression.castIfNecessary(targetType: IrType, numberCastFunctionName: Name): IrExpression { + return if (type == targetType) { + this + } else { + val function = type.getClass()!!.functions.first { it.name == numberCastFunctionName } + IrCallImpl(startOffset, endOffset, function.returnType, function.symbol) + .apply { dispatchReceiver = this@castIfNecessary } + } +} + +/** Return the negated value if the expression is const, otherwise call unaryMinus(). */ +internal fun IrExpression.negate(): IrExpression { + val value = (this as? IrConst<*>)?.value as? Number + return when (value) { + is Int -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Int, -value) + is Long -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Long, -value) + else -> { + val unaryMinusFun = type.getClass()!!.functions.first { it.name == OperatorNameConventions.UNARY_MINUS } + IrCallImpl(startOffset, endOffset, type, unaryMinusFun.symbol, unaryMinusFun.descriptor).apply { + dispatchReceiver = this@negate + } + } + } +} + +/** Return `this - 1` if the expression is const, otherwise call dec(). */ +internal fun IrExpression.decrement(): IrExpression { + val thisValue = (this as? IrConst<*>)?.value + return when (thisValue) { + is Int -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Int, thisValue - 1) + is Long -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Long, thisValue - 1) + is Char -> IrConstImpl(startOffset, endOffset, type, IrConstKind.Char, thisValue - 1) + else -> { + val decFun = type.getClass()!!.functions.first { it.name == OperatorNameConventions.DEC } + IrCallImpl(startOffset, endOffset, type, decFun.symbol, decFun.descriptor).apply { + dispatchReceiver = this@decrement + } + } + } +} + +internal val IrExpression.canHaveSideEffects: Boolean + get() = this !is IrConst<*> && this !is IrGetValue + +internal val IrExpression.constLongValue: Long? + get() = if (this is IrConst<*>) { + val value = this.value + when (value) { + is Number -> value.toLong() + is Char -> value.toLong() + else -> null + } + } else null \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/matchers/IrFunctionMatcher.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/matchers/IrFunctionMatcher.kt index 986ffd2fd70..587a9cdc2c1 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/matchers/IrFunctionMatcher.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/matchers/IrFunctionMatcher.kt @@ -7,10 +7,9 @@ package org.jetbrains.kotlin.backend.common.lower.matchers import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrValueParameter -import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.types.SimpleType internal interface IrFunctionMatcher : (IrFunction) -> Boolean @@ -91,9 +90,9 @@ internal fun createIrFunctionRestrictions(restrictions: IrFunctionMatcherContain internal fun IrFunctionMatcherContainer.singleArgumentExtension( fqName: FqName, - types: Collection + types: Collection ): IrFunctionMatcherContainer { - extensionReceiver { it != null && it.type.toKotlinType() in types } + extensionReceiver { it != null && it.type in types } parameterCount { it == 1 } fqName { it == fqName } return this diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt new file mode 100644 index 00000000000..6dc1db94367 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in (logged("start;", 4) downTo logged("end;", 1)).reversed().reversed()) { + sum = sum * 10 + i + } + + assertEquals(4321, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt new file mode 100644 index 00000000000..6a2397628b4 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in (logged("start;", 1)..logged("end;", 4)).reversed().reversed()) { + sum = sum * 10 + i + } + + assertEquals(1234, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt new file mode 100644 index 00000000000..0a6f11dc70c --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in (logged("start;", 1) until logged("end;", 5)).reversed().reversed()) { + sum = sum * 10 + i + } + + assertEquals(1234, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt similarity index 74% rename from compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt rename to compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt index 5b7357ba109..3aabce5cc85 100644 --- a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt @@ -3,7 +3,7 @@ import kotlin.test.assertEquals fun box(): String { - for (ch in (-10).toChar() until '\u0000') { + for (i in Char.MAX_VALUE until Char.MAX_VALUE) { throw AssertionError("This loop shoud not be executed") } return "OK" diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt new file mode 100644 index 00000000000..3771a28b0aa --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + for (ch in (-10).toChar() until Char.MIN_VALUE) { + throw AssertionError("This loop shoud not be executed") + } + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt new file mode 100644 index 00000000000..1e1590e66ef --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var bound = Char.MIN_VALUE + for (ch in (-10).toChar() until bound) { + throw AssertionError("This loop shoud not be executed") + } + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt rename to compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt rename to compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt new file mode 100644 index 00000000000..c57d55a4b43 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var bound = Int.MIN_VALUE + for (i in 0 until bound) { + throw AssertionError("This loop shoud not be executed") + } + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt new file mode 100644 index 00000000000..902452e4a34 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + for (i in Long.MAX_VALUE until Long.MAX_VALUE) { + throw AssertionError("This loop shoud not be executed") + } + return "OK" +} diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt similarity index 100% rename from compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt rename to compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt diff --git a/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt new file mode 100644 index 00000000000..9d770d043a8 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var bound = Long.MIN_VALUE + for (i in 0 until bound) { + throw AssertionError("This loop shoud not be executed") + } + return "OK" +} diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt index 92b3bc15d4f..8fae10a597e 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR fun test() { var sum = 0 for (i in arrayOf("", "", "", "").indices) { @@ -5,10 +6,20 @@ fun test() { } } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd // 0 getFirst // 0 getLast + +// JVM_TEMPLATES // 1 IF_ICMPGE -// 1 IF \ No newline at end of file +// 1 IF + +// JVM_IR_TEMPLATES +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt new file mode 100644 index 00000000000..f9413cdc680 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt @@ -0,0 +1,19 @@ +// TARGET_BACKEND: JVM_IR +fun test() { + var sum = 0 + for (i in arrayOf("", "", "", "").indices) { + sum += i + } +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt index 078097cab9b..b3ace9719fc 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR fun test() { var sum = 0 for (i in intArrayOf(0, 0, 0, 0).indices) { @@ -5,6 +6,9 @@ fun test() { } } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt new file mode 100644 index 00000000000..4c9359c7cd5 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt @@ -0,0 +1,19 @@ +// TARGET_BACKEND: JVM_IR +fun test() { + var sum = 0 + for (i in intArrayOf(0, 0, 0, 0).indices) { + sum += i + } +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt index e53f7e27720..47c263ad6cf 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val N = 'Z' fun test(): Int { @@ -8,6 +9,9 @@ fun test(): Int { return sum } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt new file mode 100644 index 00000000000..4733996e9be --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +const val N = 'Z' + +fun test(): Int { + var sum = 0 + for (i in 'A' .. N) { + sum += i.toInt() + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPLE +// 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt index cdd36c9731f..bb07da6f11a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val N = 42 fun test(): Int { @@ -8,6 +9,9 @@ fun test(): Int { return sum } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt new file mode 100644 index 00000000000..9542bf8f770 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +const val N = 42 + +fun test(): Int { + var sum = 0 + for (i in 1 .. N) { + sum += i + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPLE +// 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt index 2332246c148..6fbfa6d2d7d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val N = 42L fun test(): Long { @@ -8,6 +9,9 @@ fun test(): Long { return sum } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt new file mode 100644 index 00000000000..990f6579768 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM_IR +const val N = 42L + +fun test(): Long { + var sum = 0L + for (i in 1L .. N) { + sum += i + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 LCMP +// 1 IFGT +// 1 IFLE +// 2 IF +// 0 L2I +// 0 I2L \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt index ec1771aaf8e..e2424d670a5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR object Host { const val M = 1 const val N = 4 @@ -11,6 +12,9 @@ fun test(): Int { return s } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt new file mode 100644 index 00000000000..402cdfc74d1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt @@ -0,0 +1,25 @@ +// TARGET_BACKEND: JVM_IR +object Host { + const val M = 1 + const val N = 4 +} + +fun test(): Int { + var s = 0 + for (i in Host.M .. Host.N) { + s += i + } + return s +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPLE +// 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt index 9efd068097c..57fc218c230 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -11,6 +12,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 reversed // 0 iterator // 0 getStart @@ -18,5 +22,5 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 1 IF(_ICMPG|L)T +// 1 IFLT // 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt new file mode 100644 index 00000000000..afabd225b71 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt @@ -0,0 +1,27 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + val arr = intArrayOf(1, 1, 1, 1) + var sum = 0 + for (i in arr.indices.reversed()) { + sum = sum * 10 + i + arr[i] + } + assertEquals(4321, sum) + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt index 34530ee0a13..7c413c816fc 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -22,6 +23,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + // 0 reversed // 0 iterator // 0 getStart @@ -29,7 +33,7 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 2 IF_ICMP[LG]T -// 1 IF[LG]T +// 2 IF_ICMPGT +// 1 IFGT // 3 IF // 1 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt new file mode 100644 index 00000000000..3f9cc896c2e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt @@ -0,0 +1,40 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + var sum = 0 + for (i in (4 downTo 1).reversed()) { + sum = sum * 10 + i + } + assertEquals(1234, sum) + + var sumL = 0L + for (i in (4L downTo 1L).reversed()) { + sumL = sumL * 10 + i + } + assertEquals(1234L, sumL) + + var sumC = 0 + for (i in ('4' downTo '1').reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + assertEquals(1234, sumC) + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 IF_ICMPLE +// 1 IFGT +// 1 IFLE +// 4 IF +// 2 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt index 665f0d1820e..2c4ed6cda59 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -22,6 +23,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + // 0 reversed // 0 iterator // 0 getStart @@ -29,7 +33,7 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 2 IF_ICMP[LG]T -// 1 IF[LG]T +// 2 IF_ICMPLT +// 1 IFLT // 3 IF // 1 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt new file mode 100644 index 00000000000..f428448ca5e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt @@ -0,0 +1,40 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + var sum = 0 + for (i in (1 .. 4).reversed()) { + sum = sum * 10 + i + } + assertEquals(4321, sum) + + var sumL = 0L + for (i in (1L .. 4L).reversed()) { + sumL = sumL * 10 + i + } + assertEquals(4321L, sumL) + + var sumC = 0 + for (i in ('1' .. '4').reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + assertEquals(4321, sumC) + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 IF_ICMPLE +// 1 IFGT +// 1 IFLE +// 4 IF +// 2 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt index b313b5ea990..8cb65b82f60 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -22,6 +23,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + // 0 reversed // 0 iterator // 0 getStart @@ -29,7 +33,7 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 2 IF_ICMP[LG]T -// 1 IF[LG]T +// 2 IF_ICMPLT +// 1 IFLT // 3 IF // 1 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt new file mode 100644 index 00000000000..3322955e748 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt @@ -0,0 +1,40 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + var sum = 0 + for (i in (4 downTo 1).reversed().reversed()) { + sum = sum * 10 + i + } + assertEquals(1234, sum) + + var sumL = 0L + for (i in (4L downTo 1L).reversed().reversed()) { + sumL = sumL * 10 + i + } + assertEquals(1234L, sumL) + + var sumC = 0 + for (i in ('4' downTo '1').reversed().reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + assertEquals(1234, sumC) + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 IF_ICMPLE +// 1 IFGT +// 1 IFLE +// 4 IF +// 2 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt index b0984bb5706..7cb02422f7a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -19,6 +20,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + // 0 reversed // 0 iterator // 0 getStart @@ -26,7 +30,7 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 2 IF_ICMP[LG]E -// 1 IF[LG]E +// 2 IF_ICMPGE +// 1 IFGE // 3 IF // 1 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt new file mode 100644 index 00000000000..ed009c4b4c0 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt @@ -0,0 +1,37 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + var sum = 0 + for (i in (1 until 5).reversed().reversed()) { + sum = sum * 10 + i + } + + var sumL = 0L + for (i in (1L until 5L).reversed().reversed()) { + sumL = sumL * 10 + i + } + + var sumC = 0 + for (i in ('1' until '5').reversed().reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 IF_ICMPLE +// 1 IFGT +// 1 IFLE +// 4 IF +// 2 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt index e10f91cab87..4e335fd1478 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR import kotlin.test.* fun box(): String { @@ -19,6 +20,9 @@ fun box(): String { return "OK" } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + // 0 reversed // 0 iterator // 0 getStart @@ -26,7 +30,7 @@ fun box(): String { // 0 getFirst // 0 getLast // 0 getStep -// 2 IF_ICMP[LG]T -// 1 IF[LG]T +// 2 IF_ICMPLT +// 1 IFLT // 3 IF // 1 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt new file mode 100644 index 00000000000..a33cc2541b3 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt @@ -0,0 +1,37 @@ +// TARGET_BACKEND: JVM_IR +import kotlin.test.* + +fun box(): String { + var sum = 0 + for (i in (1 until 5).reversed()) { + sum = sum * 10 + i + } + + var sumL = 0L + for (i in (1L until 5L).reversed()) { + sumL = sumL * 10 + i + } + + var sumC = 0 + for (i in ('1' until '5').reversed()) { + sumC = sumC * 10 + i.toInt() - '0'.toInt() + } + + return "OK" +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long. + +// 0 reversed +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 IF_ICMPLE +// 1 IFGT +// 1 IFLE +// 4 IF +// 2 LCMP \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt new file mode 100644 index 00000000000..70822f131f9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt @@ -0,0 +1,20 @@ +// IGNORE_BACKEND: JVM_IR +fun test(a: Char, b: Char): String { + var s = "" + for (i in a until b) { + s += i + } + return s +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPGE +// 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt new file mode 100644 index 00000000000..42b70af688a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +fun test(a: Char, b: Char): String { + var s = "" + for (i in a until b) { + s += i + } + return s +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IFEQ +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 3 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilCharMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt similarity index 73% rename from compiler/testData/codegen/bytecodeText/forLoop/forInUntilCharMaxValue.kt rename to compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt index 085aff42891..f0908901f75 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilCharMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val M = Char.MAX_VALUE fun f(a: Char): Int { @@ -8,6 +9,9 @@ fun f(a: Char): Int { return n } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt new file mode 100644 index 00000000000..f4585043343 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM_IR +const val M = Char.MAX_VALUE + +fun f(a: Char): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt new file mode 100644 index 00000000000..1a2c10f0bbc --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +const val M = Char.MIN_VALUE + +fun f(a: Char): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE. +// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 0 IF +// 0 LINENUMBER 7 \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt similarity index 54% rename from compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt rename to compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt index f6fd56234c6..43853e7fd4b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR fun test(a: Int, b: Int): Int { var sum = 0 for (i in a until b) { @@ -6,6 +7,9 @@ fun test(a: Int, b: Int): Int { return sum } +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt new file mode 100644 index 00000000000..94920dd9f3c --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM_IR +fun test(a: Int, b: Int): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 LDC -2147483648 +// 1 IF_ICMPEQ +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 3 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt similarity index 73% rename from compiler/testData/codegen/bytecodeText/forLoop/forInUntilIntMaxValue.kt rename to compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt index 6b58ef852a7..fb2a630b3e4 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val M = Int.MAX_VALUE fun f(a: Int): Int { @@ -8,6 +9,9 @@ fun f(a: Int): Int { return n } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt new file mode 100644 index 00000000000..737347d6f4f --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM_IR +const val M = Int.MAX_VALUE + +fun f(a: Int): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPGT +// 1 IF_ICMPLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt new file mode 100644 index 00000000000..a51f01e502a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +const val M = Int.MIN_VALUE + +fun f(a: Int): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE. +// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 0 IF +// 0 LINENUMBER 7 \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt new file mode 100644 index 00000000000..789d8fedb8c --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt @@ -0,0 +1,21 @@ +// IGNORE_BACKEND: JVM_IR +fun test(a: Long, b: Long): Long { + var sum = 0L + for (i in a until b) { + sum = sum * 10L + i + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 LCMP +// 1 IFGE +// 1 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt new file mode 100644 index 00000000000..117bb03bb18 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM_IR +fun test(a: Long, b: Long): Long { + var sum = 0L + for (i in a until b) { + sum = sum * 10L + i + } + return sum +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 LDC -9223372036854775808 +// 3 LCMP +// 1 IFEQ +// 1 IFGT +// 1 IFLE +// 3 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilLongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt similarity index 73% rename from compiler/testData/codegen/bytecodeText/forLoop/forInUntilLongMaxValue.kt rename to compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt index d45ddcc1318..feb6558d173 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntilLongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND: JVM_IR const val M = Long.MAX_VALUE fun f(a: Long): Int { @@ -8,6 +9,9 @@ fun f(a: Long): Int { return n } +// JVM non-IR uses while. +// JVM IR uses if + do-while. + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt new file mode 100644 index 00000000000..efef772bfdd --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM_IR +const val M = Long.MAX_VALUE + +fun f(a: Long): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 LCMP +// 1 IFGT +// 1 IFLE +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt new file mode 100644 index 00000000000..3a3063a3897 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR +const val M = Long.MIN_VALUE + +fun f(a: Long): Int { + var n = 0 + for (i in a until M) { + n++ + } + return n +} + +// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE. +// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code. + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 0 IF +// 0 LINENUMBER 7 \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt new file mode 100644 index 00000000000..bb3ab9d799a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt @@ -0,0 +1,41 @@ +// TARGET_BACKEND: JVM_IR +fun testByteUntilInt(a: Byte, b: Int): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testShortUntilInt(a: Short, b: Int): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE. +// However, this check is not needed when the upper bound is smaller than the range element type. +// Here are the available `until` extension functions with mixed bounds that return IntRange: +// +// infix fun Byte.until(to: Byte): IntRange +// infix fun Byte.until(to: Short): IntRange +// infix fun Byte.until(to: Int): IntRange // Bound check needed +// infix fun Short.until(to: Byte): IntRange +// infix fun Short.until(to: Short): IntRange +// infix fun Short.until(to: Int): IntRange // Bound check needed +// infix fun Int.until(to: Byte): IntRange +// infix fun Int.until(to: Short): IntRange + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 2 LDC -2147483648 +// 2 IF_ICMPEQ +// 2 IF_ICMPGT +// 2 IF_ICMPLE +// 6 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR.kt new file mode 100644 index 00000000000..886dbe6b8a6 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR.kt @@ -0,0 +1,72 @@ +// TARGET_BACKEND: JVM_IR +fun testByteUntilByte(a: Byte, b: Byte): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testByteUntilShort(a: Byte, b: Short): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testShortUntilByte(a: Short, b: Byte): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testShortUntilShort(a: Short, b: Short): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testIntUntilByte(a: Int, b: Byte): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +fun testIntUntilShort(a: Int, b: Short): Int { + var sum = 0 + for (i in a until b) { + sum = sum * 10 + i + } + return sum +} + +// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE. +// However, this check is not needed when the upper bound is smaller than the range element type. +// Here are the available `until` extension functions with mixed bounds that return IntRange: +// +// infix fun Byte.until(to: Byte): IntRange // NO bound check needed +// infix fun Byte.until(to: Short): IntRange // NO bound check needed +// infix fun Byte.until(to: Int): IntRange +// infix fun Short.until(to: Byte): IntRange // NO bound check needed +// infix fun Short.until(to: Short): IntRange // NO bound check needed +// infix fun Short.until(to: Int): IntRange +// infix fun Int.until(to: Byte): IntRange // NO bound check needed +// infix fun Int.until(to: Short): IntRange // NO bound check needed + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 0 LDC -2147483648 +// 6 IF_ICMPGT +// 6 IF_ICMPLE +// 12 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR.kt new file mode 100644 index 00000000000..74f48a2623a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR.kt @@ -0,0 +1,44 @@ +// TARGET_BACKEND: JVM_IR +fun testLongUntilByte(a: Long, b: Byte): Long { + var sum = 0L + for (i in a until b) { + sum = sum * 10L + i + } + return sum +} + +fun testLongUntilShort(a: Long, b: Short): Long { + var sum = 0L + for (i in a until b) { + sum = sum * 10L + i + } + return sum +} + +fun testLongUntilInt(a: Long, b: Int): Long { + var sum = 0L + for (i in a until b) { + sum = sum * 10L + i + } + return sum +} + +// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE. +// However, this check is not needed when the upper bound is smaller than the range element type. +// Here are the available `until` extension functions with mixed bounds that return LongRange: +// +// infix fun Long.until(to: Byte): LongRange // NO bound check needed +// infix fun Long.until(to: Short): LongRange // NO bound check needed +// infix fun Long.until(to: Int): LongRange // NO bound check needed + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 0 LDC -9223372036854775808 +// 6 LCMP +// 3 IFGT +// 3 IFLE +// 6 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt index 656f1b21e38..9a174007375 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt @@ -1,8 +1,12 @@ +// IGNORE_BACKEND: JVM_IR fun f() { for (i in 1..2) { } } +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + // 0 iterator // 0 getStart // 0 getEnd diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt new file mode 100644 index 00000000000..eb3978868d4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM_IR +fun f() { + for (i in 1..2) { + } +} + +// JVM non-IR uses while. +// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition). + +// 0 iterator +// 0 getStart +// 0 getEnd +// 0 getFirst +// 0 getLast +// 0 getStep +// 1 IF_ICMPLE +// 1 IF \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index bb6917eaf15..682a8cf7bfc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18867,34 +18867,49 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } - @TestMetadata("forInDownToEvaluationOrder.kt") - public void testForInDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + @TestMetadata("forInDownTo.kt") + public void testForInDownTo() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt"); } - @TestMetadata("forInRangeLiteralEvaluationOrder.kt") - public void testForInRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInDownToReversed.kt") + public void testForInDownToReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt"); } - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + @TestMetadata("forInDownToReversedReversed.kt") + public void testForInDownToReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt"); } - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteral.kt") + public void testForInRangeLiteral() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt"); } - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversed.kt") + public void testForInRangeLiteralReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt"); } - @TestMetadata("forInUntilEvaluationOrder.kt") - public void testForInUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversedReversed.kt") + public void testForInRangeLiteralReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt"); + } + + @TestMetadata("forInUntil.kt") + public void testForInUntil() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt"); + } + + @TestMetadata("forInUntilReversed.kt") + public void testForInUntilReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt"); + } + + @TestMetadata("forInUntilReversedReversed.kt") + public void testForInUntilReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt"); } } @@ -19312,9 +19327,19 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar.kt"); } - @TestMetadata("forInUntilChar0.kt") - public void testForInUntilChar0() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt"); + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMinValue.kt") + public void testForInUntilCharMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt"); + } + + @TestMetadata("forInUntilCharMinValueNonConst.kt") + public void testForInUntilCharMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt"); } @TestMetadata("forInUntilInt.kt") @@ -19322,6 +19347,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilInt.kt"); } + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMinValue.kt") + public void testForInUntilIntMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt"); + } + + @TestMetadata("forInUntilIntMinValueNonConst.kt") + public void testForInUntilIntMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt"); + } + @TestMetadata("forInUntilLesserInt.kt") public void testForInUntilLesserInt() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLesserInt.kt"); @@ -19332,19 +19372,19 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLong.kt"); } - @TestMetadata("forInUntilMaxint.kt") - public void testForInUntilMaxint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt"); + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt"); } - @TestMetadata("forInUntilMinint.kt") - public void testForInUntilMinint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt"); + @TestMetadata("forInUntilLongMinValue.kt") + public void testForInUntilLongMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt"); } - @TestMetadata("forInUntilMinlong.kt") - public void testForInUntilMinlong() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt"); + @TestMetadata("forInUntilLongMinValueNonConst.kt") + public void testForInUntilLongMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt"); } @TestMetadata("forIntInIntUntilSmartcastInt.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index dcf4b40c98c..7d28e3aea50 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1742,26 +1742,6 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt"); } - @TestMetadata("forInUntil.kt") - public void testForInUntil() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt"); - } - - @TestMetadata("forInUntilCharMaxValue.kt") - public void testForInUntilCharMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilCharMaxValue.kt"); - } - - @TestMetadata("forInUntilIntMaxValue.kt") - public void testForInUntilIntMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilIntMaxValue.kt"); - } - - @TestMetadata("forInUntilLongMaxValue.kt") - public void testForInUntilLongMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilLongMaxValue.kt"); - } - @TestMetadata("forIntInDownTo.kt") public void testForIntInDownTo() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt"); @@ -2079,6 +2059,49 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt"); } } + + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInUntil") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInUntil extends AbstractBytecodeTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInForInUntil() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInUntil"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInUntilChar.kt") + public void testForInUntilChar() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt"); + } + + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilInt.kt") + public void testForInUntilInt() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt"); + } + + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilLong.kt") + public void testForInUntilLong() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt"); + } + + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt"); + } + } } @TestMetadata("compiler/testData/codegen/bytecodeText/hashCode") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 878d89a9634..33283f66a99 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18867,34 +18867,49 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } - @TestMetadata("forInDownToEvaluationOrder.kt") - public void testForInDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + @TestMetadata("forInDownTo.kt") + public void testForInDownTo() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt"); } - @TestMetadata("forInRangeLiteralEvaluationOrder.kt") - public void testForInRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInDownToReversed.kt") + public void testForInDownToReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt"); } - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + @TestMetadata("forInDownToReversedReversed.kt") + public void testForInDownToReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt"); } - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteral.kt") + public void testForInRangeLiteral() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt"); } - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversed.kt") + public void testForInRangeLiteralReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt"); } - @TestMetadata("forInUntilEvaluationOrder.kt") - public void testForInUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversedReversed.kt") + public void testForInRangeLiteralReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt"); + } + + @TestMetadata("forInUntil.kt") + public void testForInUntil() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt"); + } + + @TestMetadata("forInUntilReversed.kt") + public void testForInUntilReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt"); + } + + @TestMetadata("forInUntilReversedReversed.kt") + public void testForInUntilReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt"); } } @@ -19312,9 +19327,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar.kt"); } - @TestMetadata("forInUntilChar0.kt") - public void testForInUntilChar0() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt"); + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMinValue.kt") + public void testForInUntilCharMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt"); + } + + @TestMetadata("forInUntilCharMinValueNonConst.kt") + public void testForInUntilCharMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt"); } @TestMetadata("forInUntilInt.kt") @@ -19322,6 +19347,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilInt.kt"); } + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMinValue.kt") + public void testForInUntilIntMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt"); + } + + @TestMetadata("forInUntilIntMinValueNonConst.kt") + public void testForInUntilIntMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt"); + } + @TestMetadata("forInUntilLesserInt.kt") public void testForInUntilLesserInt() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLesserInt.kt"); @@ -19332,19 +19372,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLong.kt"); } - @TestMetadata("forInUntilMaxint.kt") - public void testForInUntilMaxint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt"); + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt"); } - @TestMetadata("forInUntilMinint.kt") - public void testForInUntilMinint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt"); + @TestMetadata("forInUntilLongMinValue.kt") + public void testForInUntilLongMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt"); } - @TestMetadata("forInUntilMinlong.kt") - public void testForInUntilMinlong() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt"); + @TestMetadata("forInUntilLongMinValueNonConst.kt") + public void testForInUntilLongMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt"); } @TestMetadata("forIntInIntUntilSmartcastInt.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 143807a628b..45049d3babd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17757,34 +17757,49 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } - @TestMetadata("forInDownToEvaluationOrder.kt") - public void testForInDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + @TestMetadata("forInDownTo.kt") + public void testForInDownTo() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt"); } - @TestMetadata("forInRangeLiteralEvaluationOrder.kt") - public void testForInRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInDownToReversed.kt") + public void testForInDownToReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt"); } - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + @TestMetadata("forInDownToReversedReversed.kt") + public void testForInDownToReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt"); } - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteral.kt") + public void testForInRangeLiteral() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt"); } - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversed.kt") + public void testForInRangeLiteralReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt"); } - @TestMetadata("forInUntilEvaluationOrder.kt") - public void testForInUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversedReversed.kt") + public void testForInRangeLiteralReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt"); + } + + @TestMetadata("forInUntil.kt") + public void testForInUntil() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt"); + } + + @TestMetadata("forInUntilReversed.kt") + public void testForInUntilReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt"); + } + + @TestMetadata("forInUntilReversedReversed.kt") + public void testForInUntilReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt"); } } @@ -18202,9 +18217,19 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar.kt"); } - @TestMetadata("forInUntilChar0.kt") - public void testForInUntilChar0() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt"); + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMinValue.kt") + public void testForInUntilCharMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt"); + } + + @TestMetadata("forInUntilCharMinValueNonConst.kt") + public void testForInUntilCharMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt"); } @TestMetadata("forInUntilInt.kt") @@ -18212,6 +18237,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilInt.kt"); } + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMinValue.kt") + public void testForInUntilIntMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt"); + } + + @TestMetadata("forInUntilIntMinValueNonConst.kt") + public void testForInUntilIntMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt"); + } + @TestMetadata("forInUntilLesserInt.kt") public void testForInUntilLesserInt() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLesserInt.kt"); @@ -18222,19 +18262,19 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLong.kt"); } - @TestMetadata("forInUntilMaxint.kt") - public void testForInUntilMaxint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt"); + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt"); } - @TestMetadata("forInUntilMinint.kt") - public void testForInUntilMinint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt"); + @TestMetadata("forInUntilLongMinValue.kt") + public void testForInUntilLongMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt"); } - @TestMetadata("forInUntilMinlong.kt") - public void testForInUntilMinlong() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt"); + @TestMetadata("forInUntilLongMinValueNonConst.kt") + public void testForInUntilLongMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt"); } @TestMetadata("forIntInIntUntilSmartcastInt.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index 03546c84d99..e2ff74f0e00 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -1657,6 +1657,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt"); } + @TestMetadata("forInRangeToCharConstIR.kt") + public void testForInRangeToCharConstIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt"); + } + @TestMetadata("forInRangeToCharMaxValue.kt") public void testForInRangeToCharMaxValue() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt"); @@ -1667,6 +1672,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt"); } + @TestMetadata("forInRangeToConstIR.kt") + public void testForInRangeToConstIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt"); + } + @TestMetadata("forInRangeToIntMaxValue.kt") public void testForInRangeToIntMaxValue() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt"); @@ -1677,6 +1687,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt"); } + @TestMetadata("forInRangeToLongConstIR.kt") + public void testForInRangeToLongConstIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt"); + } + @TestMetadata("forInRangeToLongMaxValue.kt") public void testForInRangeToLongMaxValue() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt"); @@ -1687,6 +1702,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt"); } + @TestMetadata("forInRangeToQualifiedConstIR.kt") + public void testForInRangeToQualifiedConstIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt"); + } + @TestMetadata("forInRangeWithImplicitReceiver.kt") public void testForInRangeWithImplicitReceiver() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt"); @@ -1697,26 +1717,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt"); } - @TestMetadata("forInUntil.kt") - public void testForInUntil() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt"); - } - - @TestMetadata("forInUntilCharMaxValue.kt") - public void testForInUntilCharMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilCharMaxValue.kt"); - } - - @TestMetadata("forInUntilIntMaxValue.kt") - public void testForInUntilIntMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilIntMaxValue.kt"); - } - - @TestMetadata("forInUntilLongMaxValue.kt") - public void testForInUntilLongMaxValue() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntilLongMaxValue.kt"); - } - @TestMetadata("forIntInDownTo.kt") public void testForIntInDownTo() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt"); @@ -1737,6 +1737,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt"); } + @TestMetadata("primitiveLiteralRange1IR.kt") + public void testPrimitiveLiteralRange1IR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt"); + } + @TestMetadata("primitiveLiteralRange2.kt") public void testPrimitiveLiteralRange2() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt"); @@ -1870,10 +1875,20 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt"); } + @TestMetadata("forInObjectArrayIndicesIR.kt") + public void testForInObjectArrayIndicesIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt"); + } + @TestMetadata("forInPrimitiveArrayIndices.kt") public void testForInPrimitiveArrayIndices() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt"); } + + @TestMetadata("forInPrimitiveArrayIndicesIR.kt") + public void testForInPrimitiveArrayIndicesIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt"); + } } @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex") @@ -1931,6 +1946,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt"); } + @TestMetadata("forInReversedArrayIndicesIR.kt") + public void testForInReversedArrayIndicesIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt"); + } + @TestMetadata("forInReversedCharSequenceIndices.kt") public void testForInReversedCharSequenceIndices() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt"); @@ -1946,6 +1966,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt"); } + @TestMetadata("forInReversedDownToIR.kt") + public void testForInReversedDownToIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt"); + } + @TestMetadata("forInReversedEmptyRangeLiteral.kt") public void testForInReversedEmptyRangeLiteral() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt"); @@ -1961,6 +1986,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt"); } + @TestMetadata("forInReversedRangeLiteralIR.kt") + public void testForInReversedRangeLiteralIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt"); + } + @TestMetadata("forInReversedReversedArrayIndices.kt") public void testForInReversedReversedArrayIndices() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt"); @@ -1971,6 +2001,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt"); } + @TestMetadata("forInReversedReversedDownToIR.kt") + public void testForInReversedReversedDownToIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt"); + } + @TestMetadata("ForInReversedReversedRange.kt") public void testForInReversedReversedRange() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt"); @@ -1986,10 +2021,20 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt"); } + @TestMetadata("forInReversedReversedUntilIR.kt") + public void testForInReversedReversedUntilIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt"); + } + @TestMetadata("forInReversedUntil.kt") public void testForInReversedUntil() throws Exception { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt"); } + + @TestMetadata("forInReversedUntilIR.kt") + public void testForInReversedUntilIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt"); + } } @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex") @@ -2034,6 +2079,109 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt"); } } + + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInUntil") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInUntil extends AbstractIrBytecodeTextTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInForInUntil() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInUntil"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("forInUntilChar.kt") + public void testForInUntilChar() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt"); + } + + @TestMetadata("forInUntilCharIR.kt") + public void testForInUntilCharIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt"); + } + + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMaxValueIR.kt") + public void testForInUntilCharMaxValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt"); + } + + @TestMetadata("forInUntilCharMinValueIR.kt") + public void testForInUntilCharMinValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt"); + } + + @TestMetadata("forInUntilInt.kt") + public void testForInUntilInt() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt"); + } + + @TestMetadata("forInUntilIntIR.kt") + public void testForInUntilIntIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt"); + } + + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMaxValueIR.kt") + public void testForInUntilIntMaxValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt"); + } + + @TestMetadata("forInUntilIntMinValueIR.kt") + public void testForInUntilIntMinValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt"); + } + + @TestMetadata("forInUntilLong.kt") + public void testForInUntilLong() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt"); + } + + @TestMetadata("forInUntilLongIR.kt") + public void testForInUntilLongIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt"); + } + + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt"); + } + + @TestMetadata("forInUntilLongMaxValueIR.kt") + public void testForInUntilLongMaxValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt"); + } + + @TestMetadata("forInUntilLongMinValueIR.kt") + public void testForInUntilLongMinValueIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt"); + } + + @TestMetadata("forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt") + public void testForInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt"); + } + + @TestMetadata("forInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR.kt") + public void testForInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForIntRangeIR.kt"); + } + + @TestMetadata("forInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR.kt") + public void testForInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForLongRangeIR.kt"); + } + } } @TestMetadata("compiler/testData/codegen/bytecodeText/hashCode") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 5cae9cdc136..7cc13423963 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -14802,34 +14802,49 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); } - @TestMetadata("forInDownToEvaluationOrder.kt") - public void testForInDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + @TestMetadata("forInDownTo.kt") + public void testForInDownTo() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt"); } - @TestMetadata("forInRangeLiteralEvaluationOrder.kt") - public void testForInRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInDownToReversed.kt") + public void testForInDownToReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt"); } - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + @TestMetadata("forInDownToReversedReversed.kt") + public void testForInDownToReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt"); } - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteral.kt") + public void testForInRangeLiteral() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt"); } - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversed.kt") + public void testForInRangeLiteralReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt"); } - @TestMetadata("forInUntilEvaluationOrder.kt") - public void testForInUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversedReversed.kt") + public void testForInRangeLiteralReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt"); + } + + @TestMetadata("forInUntil.kt") + public void testForInUntil() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt"); + } + + @TestMetadata("forInUntilReversed.kt") + public void testForInUntilReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt"); + } + + @TestMetadata("forInUntilReversedReversed.kt") + public void testForInUntilReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt"); } } @@ -15247,9 +15262,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar.kt"); } - @TestMetadata("forInUntilChar0.kt") - public void testForInUntilChar0() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt"); + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMinValue.kt") + public void testForInUntilCharMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt"); + } + + @TestMetadata("forInUntilCharMinValueNonConst.kt") + public void testForInUntilCharMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt"); } @TestMetadata("forInUntilInt.kt") @@ -15257,6 +15282,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilInt.kt"); } + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMinValue.kt") + public void testForInUntilIntMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt"); + } + + @TestMetadata("forInUntilIntMinValueNonConst.kt") + public void testForInUntilIntMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt"); + } + @TestMetadata("forInUntilLesserInt.kt") public void testForInUntilLesserInt() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLesserInt.kt"); @@ -15267,19 +15307,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLong.kt"); } - @TestMetadata("forInUntilMaxint.kt") - public void testForInUntilMaxint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt"); + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt"); } - @TestMetadata("forInUntilMinint.kt") - public void testForInUntilMinint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt"); + @TestMetadata("forInUntilLongMinValue.kt") + public void testForInUntilLongMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt"); } - @TestMetadata("forInUntilMinlong.kt") - public void testForInUntilMinlong() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt"); + @TestMetadata("forInUntilLongMinValueNonConst.kt") + public void testForInUntilLongMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt"); } @TestMetadata("forIntInIntUntilSmartcastInt.kt") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index aa6d59beae0..822d0923bea 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -15957,34 +15957,49 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } - @TestMetadata("forInDownToEvaluationOrder.kt") - public void testForInDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + @TestMetadata("forInDownTo.kt") + public void testForInDownTo() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownTo.kt"); } - @TestMetadata("forInRangeLiteralEvaluationOrder.kt") - public void testForInRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInDownToReversed.kt") + public void testForInDownToReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversed.kt"); } - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + @TestMetadata("forInDownToReversedReversed.kt") + public void testForInDownToReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToReversedReversed.kt"); } - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteral.kt") + public void testForInRangeLiteral() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteral.kt"); } - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversed.kt") + public void testForInRangeLiteralReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversed.kt"); } - @TestMetadata("forInUntilEvaluationOrder.kt") - public void testForInUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + @TestMetadata("forInRangeLiteralReversedReversed.kt") + public void testForInRangeLiteralReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralReversedReversed.kt"); + } + + @TestMetadata("forInUntil.kt") + public void testForInUntil() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntil.kt"); + } + + @TestMetadata("forInUntilReversed.kt") + public void testForInUntilReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversed.kt"); + } + + @TestMetadata("forInUntilReversedReversed.kt") + public void testForInUntilReversedReversed() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilReversedReversed.kt"); } } @@ -16402,9 +16417,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar.kt"); } - @TestMetadata("forInUntilChar0.kt") - public void testForInUntilChar0() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilChar0.kt"); + @TestMetadata("forInUntilCharMaxValue.kt") + public void testForInUntilCharMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMaxValue.kt"); + } + + @TestMetadata("forInUntilCharMinValue.kt") + public void testForInUntilCharMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValue.kt"); + } + + @TestMetadata("forInUntilCharMinValueNonConst.kt") + public void testForInUntilCharMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilCharMinValueNonConst.kt"); } @TestMetadata("forInUntilInt.kt") @@ -16412,6 +16437,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilInt.kt"); } + @TestMetadata("forInUntilIntMaxValue.kt") + public void testForInUntilIntMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMaxValue.kt"); + } + + @TestMetadata("forInUntilIntMinValue.kt") + public void testForInUntilIntMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValue.kt"); + } + + @TestMetadata("forInUntilIntMinValueNonConst.kt") + public void testForInUntilIntMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilIntMinValueNonConst.kt"); + } + @TestMetadata("forInUntilLesserInt.kt") public void testForInUntilLesserInt() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLesserInt.kt"); @@ -16422,19 +16462,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLong.kt"); } - @TestMetadata("forInUntilMaxint.kt") - public void testForInUntilMaxint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMaxint.kt"); + @TestMetadata("forInUntilLongMaxValue.kt") + public void testForInUntilLongMaxValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMaxValue.kt"); } - @TestMetadata("forInUntilMinint.kt") - public void testForInUntilMinint() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinint.kt"); + @TestMetadata("forInUntilLongMinValue.kt") + public void testForInUntilLongMinValue() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValue.kt"); } - @TestMetadata("forInUntilMinlong.kt") - public void testForInUntilMinlong() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilMinlong.kt"); + @TestMetadata("forInUntilLongMinValueNonConst.kt") + public void testForInUntilLongMinValueNonConst() throws Exception { + runTest("compiler/testData/codegen/box/ranges/forInUntil/forInUntilLongMinValueNonConst.kt"); } @TestMetadata("forIntInIntUntilSmartcastInt.kt")