diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt index 44361a94ad6..8b5ef4edab8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt @@ -289,6 +289,8 @@ abstract class Symbols(val context: T, irBuiltIns: abstract val returnIfSuspended: IrSimpleFunctionSymbol + open val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol? = null + companion object { fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean = symbol is IrSimpleFunctionSymbol && symbol.owner.let { function -> 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 d12756e2545..b66eabd2990 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 @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.functions +import org.jetbrains.kotlin.ir.util.isUnsigned import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -32,11 +33,15 @@ internal enum class ProgressionType( INT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt")), LONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong"), isLong = true), CHAR_PROGRESSION(Name.identifier("toChar"), Name.identifier("toInt")), - UINT_PROGRESSION(Name.identifier("toUInt"), Name.identifier("toInt"), isUnsigned = true), - ULONG_PROGRESSION(Name.identifier("toULong"), Name.identifier("toLong"), isLong = true, isUnsigned = true); + UINT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt"), isUnsigned = true), + ULONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong"), isLong = true, isUnsigned = true); /** Returns the [IrType] of the `first`/`last` properties and elements in the progression. */ - fun elementType(symbols: Symbols): IrType = elementClassifier(symbols).defaultType + fun elementType(symbols: Symbols): IrType = when (this) { + INT_PROGRESSION, UINT_PROGRESSION -> symbols.int + LONG_PROGRESSION, ULONG_PROGRESSION -> symbols.long + CHAR_PROGRESSION -> symbols.char + }.defaultType /** Returns the [IrClassSymbol] of the `first`/`last` properties and elements in the progression. */ fun elementClassifier(symbols: Symbols): IrClassSymbol = when (this) { @@ -59,6 +64,15 @@ internal enum class ProgressionType( LONG_PROGRESSION, ULONG_PROGRESSION -> builtIns.longClass } + /** Returns the [IrType] used in loop conditions (`buildLoopCondition()`) and when calling `getProgressionLastElement()`. */ + fun compareType(symbols: Symbols): IrType = when (this) { + INT_PROGRESSION -> symbols.int + LONG_PROGRESSION -> symbols.long + CHAR_PROGRESSION -> symbols.char + UINT_PROGRESSION -> symbols.uInt!! + ULONG_PROGRESSION -> symbols.uLong!! + }.defaultType + fun castElementIfNecessary(element: IrExpression, context: CommonBackendContext) = element.castIfNecessary(elementType(context.ir.symbols), elementCastFunctionName) @@ -78,6 +92,69 @@ internal enum class ProgressionType( .apply { dispatchReceiver = this@castIfNecessary } } + fun coerceToUnsigned(value: IrExpression, symbols: Symbols): IrExpression { + if (!isUnsigned || value.type.isUnsigned()) return value + + val unsafeCoerceIntrinsic = symbols.unsafeCoerceIntrinsic + return if (unsafeCoerceIntrinsic != null) { + val from = when (this) { + UINT_PROGRESSION -> symbols.int.defaultType + ULONG_PROGRESSION -> symbols.long.defaultType + else -> error("Unexpected progression type") + } + val to = when (this) { + UINT_PROGRESSION -> symbols.uInt!!.defaultType + ULONG_PROGRESSION -> symbols.uLong!!.defaultType + else -> error("Unexpected progression type") + } + IrCallImpl(value.startOffset, value.endOffset, to, unsafeCoerceIntrinsic).apply { + putTypeArgument(0, from) + putTypeArgument(1, to) + putValueArgument(0, value) + } + } else { + val conversionFunctionMap = when (this) { + UINT_PROGRESSION -> symbols.toUIntByExtensionReceiver + ULONG_PROGRESSION -> symbols.toULongByExtensionReceiver + else -> error("Unexpected progression type") + } + val from = when (this) { + UINT_PROGRESSION -> symbols.int.defaultType + ULONG_PROGRESSION -> symbols.long.defaultType + else -> error("Unexpected progression type") + }.toKotlinType() + val castFun = conversionFunctionMap.getValue(from) + IrCallImpl(value.startOffset, value.endOffset, castFun.owner.returnType, castFun).apply { + extensionReceiver = value + } + } + } + + fun coerceToSigned(value: IrExpression, symbols: Symbols): IrExpression { + if (!isUnsigned || !value.type.isUnsigned()) return value + + val unsafeCoerceIntrinsic = symbols.unsafeCoerceIntrinsic + return if (unsafeCoerceIntrinsic != null) { + val from = when (this) { + UINT_PROGRESSION -> symbols.uInt!!.defaultType + ULONG_PROGRESSION -> symbols.uLong!!.defaultType + else -> error("Unexpected progression type") + } + val to = when (this) { + UINT_PROGRESSION -> symbols.int.defaultType + ULONG_PROGRESSION -> symbols.long.defaultType + else -> error("Unexpected progression type") + } + IrCallImpl(value.startOffset, value.endOffset, to, unsafeCoerceIntrinsic).apply { + putTypeArgument(0, from) + putTypeArgument(1, to) + putValueArgument(0, value) + } + } else { + castElementIfNecessary(value, symbols.context) + } + } + companion object { fun fromIrType(irType: IrType, symbols: Symbols): ProgressionType? = when { irType.isSubtypeOfClass(symbols.charProgression) -> CHAR_PROGRESSION 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 20f23d893ff..50f843863ac 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 @@ -68,7 +68,6 @@ internal abstract class NumericForLoopHeader( val inductionVariable: IrVariable protected val stepVariable: IrVariable? - protected val stepVariableForIncrement: IrVariable? val stepExpression: IrExpression // Always copy `stepExpression` is it may be used multiple times. get() = field.deepCopyWithSymbols() @@ -78,7 +77,7 @@ internal abstract class NumericForLoopHeader( // Always copy `lastExpression` is it may be used in multiple conditions. get() = field.deepCopyWithSymbols() - private val symbols = context.ir.symbols + protected val symbols = context.ir.symbols private val elementType: IrType init { @@ -124,24 +123,6 @@ internal abstract class NumericForLoopHeader( ) stepVariable = tmpStepVar stepExpression = tmpStepExpression - - stepVariableForIncrement = when (headerInfo.progressionType) { - ProgressionType.UINT_PROGRESSION -> { - val castFun = context.ir.symbols.toUIntByExtensionReceiver.getValue(stepType.toKotlinType()) - scope.createTmpVariable( - irCall(castFun).apply { extensionReceiver = stepExpression }, - nameHint = "stepForIncrement" - ) - } - ProgressionType.ULONG_PROGRESSION -> { - val castFun = context.ir.symbols.toULongByExtensionReceiver.getValue(stepType.toKotlinType()) - scope.createTmpVariable( - irCall(castFun).apply { extensionReceiver = stepExpression }, - nameHint = "stepForIncrement" - ) - } - else -> null - } } } @@ -155,10 +136,9 @@ internal abstract class NumericForLoopHeader( /** Statement used to increment the induction variable. */ protected fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) { // inductionVariable = inductionVariable + step - val stepExpressionToUse = stepVariableForIncrement?.let { irGet(stepVariableForIncrement) } ?: stepExpression - // NOTE: We cannot use `stepExpression.type` below because it may be of type `Nothing`. This happens in the case of an illegal step - // where the "step" is actually a `throw IllegalArgumentException(...)`. - val stepType = stepVariableForIncrement?.type ?: headerInfo.progressionType.stepType(context.irBuiltIns) + // NOTE: We cannot use `stepExpression.type` to match the value parameter type because it may be of type `Nothing`. + // This happens in the case of an illegal step where the "step" is actually a `throw IllegalArgumentException(...)`. + val stepType = headerInfo.progressionType.stepType(context.irBuiltIns) val plusFun = elementType.getClass()!!.functions.single { it.name == OperatorNameConventions.PLUS && it.valueParameters.size == 1 && @@ -168,7 +148,7 @@ internal abstract class NumericForLoopHeader( inductionVariable.symbol, irCallOp( plusFun.symbol, plusFun.returnType, irGet(inductionVariable), - stepExpressionToUse + stepExpression ) ) } @@ -177,7 +157,7 @@ internal abstract class NumericForLoopHeader( with(builder) { val builtIns = context.irBuiltIns val progressionType = headerInfo.progressionType - val progressionElementType = progressionType.elementType(symbols) + val progressionCompareType = progressionType.compareType(symbols) // `compareTo` must be used for UInt/ULong; they don't have intrinsic comparison operators. val intCompFun = if (isLastInclusive) { @@ -185,17 +165,17 @@ internal abstract class NumericForLoopHeader( } else { builtIns.lessFunByOperandType.getValue(builtIns.intClass) } - val elementCompareToFun = progressionElementType.getClass()!!.functions.single { + val elementCompareToFun = progressionCompareType.getClass()!!.functions.single { it.name == OperatorNameConventions.COMPARE_TO && it.dispatchReceiverParameter != null && it.extensionReceiverParameter == null && - it.valueParameters.size == 1 && it.valueParameters[0].type == progressionElementType + it.valueParameters.size == 1 && it.valueParameters[0].type == progressionCompareType } val elementCompFun = if (isLastInclusive) { - builtIns.lessOrEqualFunByOperandType[progressionElementType.classifierOrFail] + builtIns.lessOrEqualFunByOperandType[progressionCompareType.classifierOrFail] } else { - builtIns.lessFunByOperandType[progressionElementType.classifierOrFail] + builtIns.lessFunByOperandType[progressionCompareType.classifierOrFail] } fun conditionForDecreasing(): IrExpression = @@ -203,8 +183,8 @@ internal abstract class NumericForLoopHeader( if (progressionType.isUnsigned) { irCall(intCompFun).apply { putValueArgument(0, irCall(elementCompareToFun).apply { - dispatchReceiver = lastExpression - putValueArgument(0, irGet(inductionVariable)) + dispatchReceiver = progressionType.coerceToUnsigned(lastExpression, symbols) + putValueArgument(0, progressionType.coerceToUnsigned(irGet(inductionVariable), symbols)) }) putValueArgument(1, irInt(0)) } @@ -220,8 +200,8 @@ internal abstract class NumericForLoopHeader( if (progressionType.isUnsigned) { irCall(intCompFun).apply { putValueArgument(0, irCall(elementCompareToFun).apply { - dispatchReceiver = irGet(inductionVariable) - putValueArgument(0, lastExpression) + dispatchReceiver = progressionType.coerceToUnsigned(irGet(inductionVariable), symbols) + putValueArgument(0, progressionType.coerceToUnsigned(lastExpression, symbols)) }) putValueArgument(1, irInt(0)) } @@ -284,7 +264,7 @@ internal class ProgressionLoopHeader( else listOfNotNull(inductionVariable, lastVariableIfCanCacheLast) ) + - listOfNotNull(stepVariable, stepVariableForIncrement) + listOfNotNull(stepVariable) private var loopVariable: IrVariable? = null @@ -303,7 +283,7 @@ internal class ProgressionLoopHeader( isMutable = true ) } else { - loopVariable?.initializer = irGet(inductionVariable) + loopVariable?.initializer = headerInfo.progressionType.coerceToUnsigned(irGet(inductionVariable), symbols) loopVariable } @@ -328,7 +308,7 @@ internal class ProgressionLoopHeader( // } IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { label = oldLoop.label - condition = irNotEquals(irGet(loopVariable!!), lastExpression) + condition = irNotEquals(headerInfo.progressionType.coerceToSigned(irGet(loopVariable!!), symbols), lastExpression) body = newBody } } else { @@ -382,7 +362,7 @@ internal class IndexedGetLoopHeader( ) : NumericForLoopHeader(headerInfo, builder, context, isLastInclusive = false) { override val loopInitStatements = - listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable, stepVariableForIncrement) + listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable) override fun initializeIteration( loopVariable: IrVariable?, 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 240b9c043c1..984e014c968 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 @@ -17,12 +17,10 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction 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.impl.IrConstImpl import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.types.asSimpleType import org.jetbrains.kotlin.util.OperatorNameConventions import kotlin.math.absoluteValue @@ -148,29 +146,14 @@ internal class UntilHandler(private val context: CommonBackendContext, private v val untilArgExpression = if (untilArgVar == null) untilArgCasted else irGet(untilArgVar) val last = untilArgExpression.decrement() + // Type of MIN_VALUE constant is signed even for unsigned progressions since the bounds are signed. 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)) - ProgressionType.UINT_PROGRESSION -> Pair( - UInt.MIN_VALUE.toLong(), - IrConstImpl.int( - startOffset, - endOffset, - symbols.uInt!!.defaultType, - UInt.MIN_VALUE.toInt() - ) - ) - ProgressionType.ULONG_PROGRESSION -> Pair( - ULong.MIN_VALUE.toLong(), - IrConstImpl.long( - startOffset, - endOffset, - symbols.uLong!!.defaultType, - ULong.MIN_VALUE.toLong() - ) - ) + ProgressionType.UINT_PROGRESSION -> Pair(UInt.MIN_VALUE.toLong(), irInt(UInt.MIN_VALUE.toInt())) + ProgressionType.ULONG_PROGRESSION -> Pair(ULong.MIN_VALUE.toLong(), irLong(ULong.MIN_VALUE.toLong())) } val additionalNotEmptyCondition = untilArg.constLongValue.let { when { @@ -496,22 +479,43 @@ internal class StepHandler( // - getProgressionLastElement(ULong, ULong, Long): ULong // Used by ULongProgression (uses Long step) // // We make sure to retrieve the correct symbol and use the correct argument types. - val returnTypeClassifier = if (progressionType.isUnsigned) { - progressionType.elementClassifier(symbols) - } else { - progressionType.stepClassifier(context.irBuiltIns) - } - val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[returnTypeClassifier] - ?: throw IllegalArgumentException("No `getProgressionLastElement` for return type ${returnTypeClassifier.defaultType}") - return irCall(getProgressionLastElementFun).apply { - if (progressionType.isUnsigned) { - putValueArgument(0, progressionType.castElementIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context)) - putValueArgument(1, progressionType.castElementIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context)) + return with(progressionType) { + val returnTypeClassifier = if (progressionType.isUnsigned) { + progressionType.elementClassifier(symbols) } else { - putValueArgument(0, progressionType.castStepIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context)) - putValueArgument(1, progressionType.castStepIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context)) + progressionType.stepClassifier(context.irBuiltIns) + } + val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[returnTypeClassifier] + ?: throw IllegalArgumentException("No `getProgressionLastElement` for return type ${returnTypeClassifier.defaultType}") + val call = irCall(getProgressionLastElementFun).apply { + if (isUnsigned) { + putValueArgument( + 0, + coerceToUnsigned( + castElementIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context), + symbols + ) + ) + putValueArgument( + 1, + coerceToUnsigned( + castElementIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context), + symbols + ) + ) + } else { + putValueArgument(0, castStepIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context)) + putValueArgument(1, castStepIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context)) + } + putValueArgument(2, castStepIfNecessary(step.deepCopyWithSymbols(), this@StepHandler.context)) + } + + if (isUnsigned) { + // Bounds are signed for unsigned progressions. + coerceToSigned(call, symbols) + } else { + call } - putValueArgument(2, progressionType.castStepIfNecessary(step.deepCopyWithSymbols(), this@StepHandler.context)) } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index c3e304c2c5b..3c80c5cebbe 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -507,7 +507,7 @@ class JvmSymbols( javaLangClass.functionByName("desiredAssertionStatus") } - val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol = + override val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol = buildFun { name = Name.special("") origin = IrDeclarationOrigin.IR_BUILTINS_STUB diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/emptyUntilProgressionToMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/emptyUntilProgressionToMinValue.kt index 0190e80f543..38d2d3e6a9c 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/emptyUntilProgressionToMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/emptyUntilProgressionToMinValue.kt @@ -35,4 +35,6 @@ fun box(): String { // 1 INVOKESTATIC kotlin/internal/UProgressionUtilKt.getProgressionLastElement // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW -// 0 IF \ No newline at end of file +// 0 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt index cfd85a8a199..d1b585d22b2 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt @@ -16,4 +16,6 @@ fun f(a: UInt): Int { // 0 getLast // 0 getStep // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt index d56a460ec8d..1e43d708dd9 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt @@ -16,4 +16,6 @@ fun f(a: ULong): Int { // 0 getLast // 0 getStep // 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/ULong.constructor-impl +// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt index c0ad14bcec1..d9443ec785b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt @@ -56,3 +56,5 @@ fun testULongDownTo(a: ULong, b: ULong): Int { // 0 getFirst // 0 getLast // 0 getStep +// 0 INVOKESTATIC kotlin/U(Int|Long).constructor-impl +// 0 INVOKE\w+ kotlin/U(Int|Long).(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt index 177dfbb1e89..69843ba0f7f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt @@ -1,3 +1,4 @@ +// WITH_RUNTIME const val M = UInt.MAX_VALUE fun f(a: UInt): Int { @@ -15,4 +16,6 @@ fun f(a: UInt): Int { // 0 getLast // 0 getStep // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt index 5be062007c1..3c82e5295a6 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt @@ -16,4 +16,6 @@ fun f(a: ULong): Int { // 0 getLast // 0 getStep // 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/ULong.constructor-impl +// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt index 8335e41d01a..09c348623de 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt @@ -18,6 +18,8 @@ fun f(a: UInt): Int { // 0 getFirst // 0 getLast // 0 getStep +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl // JVM_TEMPLATES // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt index 1f9e1896f99..c5e5c9fe327 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt @@ -18,6 +18,8 @@ fun f(a: UInt): Int { // 0 getFirst // 0 getLast // 0 getStep +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl // JVM_TEMPLATES // 1 IF diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt index 3a03500ffc8..84821b5beea 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt @@ -18,6 +18,8 @@ fun f(a: ULong): Int { // 0 getFirst // 0 getLast // 0 getStep +// 0 INVOKESTATIC kotlin/ULong.constructor-impl +// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl // JVM_TEMPLATES // 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt index 07f5bf762ed..e0a09f1bbc9 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt @@ -18,6 +18,8 @@ fun f(a: ULong): Int { // 0 getFirst // 0 getLast // 0 getStep +// 0 INVOKESTATIC kotlin/ULong.constructor-impl +// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl // JVM_TEMPLATES // 1 IF diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForUIntRangeIR.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForUIntRangeIR.kt index 2fa3b5d4013..e71e6089ec7 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForUIntRangeIR.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilWithMixedTypeBoundsNoBoundCheckNeededForUIntRangeIR.kt @@ -1,17 +1,17 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME -fun testUByteUntilUByte(a: UByte, b: UByte): UInt { - var sum = 0u +fun testUByteUntilUByte(a: UByte, b: UByte): Int { + var sum = 0 for (i in a until b) { - sum = sum * 10u + i + sum += i.toInt() } return sum } -fun testUShortUntilUShort(a: UShort, b: UShort): UInt { - var sum = 0u +fun testUShortUntilUShort(a: UShort, b: UShort): Int { + var sum = 0 for (i in a until b) { - sum = sum * 10u + i + sum += i.toInt() } return sum } @@ -31,4 +31,6 @@ fun testUShortUntilUShort(a: UShort, b: UShort): UInt { // 0 getStep // 2 IFGT // 2 IFLE -// 4 IF \ No newline at end of file +// 4 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt index 6f495e45130..9f2849e7f60 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt @@ -38,4 +38,6 @@ fun box(): String { // 1 NEW java/lang/IllegalArgumentException // 1 ATHROW // 0 IF -// 0 ARETURN \ No newline at end of file +// 0 ARETURN +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt index 5624d450da9..0bd2d2d06bb 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt @@ -40,4 +40,6 @@ fun box(): String { // 0 ATHROW // 1 IFGT // 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt index 81d05fe9315..add0c6fe432 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt @@ -50,4 +50,6 @@ fun box(): String { // 3 IFLE // 1 IFGE // 6 IF -// 0 INEG \ No newline at end of file +// 0 INEG +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt index b41db5c1409..7fc353014fb 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt @@ -54,4 +54,6 @@ fun box(): String { // 4 IFLE // 1 IFGE // 7 IF -// 1 INEG \ No newline at end of file +// 1 INEG +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt index 7579485bfa4..53d88968c59 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt @@ -42,4 +42,6 @@ fun box(): String { // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare // 1 IFGT // 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 2 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/untilProgressionToNonConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/untilProgressionToNonConst.kt index 08b9f106bea..0d0986e8b3d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/untilProgressionToNonConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/untilProgressionToNonConst.kt @@ -42,4 +42,6 @@ fun box(): String { // 1 IFEQ // 1 IFGT // 1 IF_ICMPNE -// 3 IF \ No newline at end of file +// 3 IF +// 0 INVOKESTATIC kotlin/UInt.constructor-impl +// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl