ForLoopsLowering: Eliminate construction/boxing/unboxing of UInt/ULong.

This needs further cleanup to encapsulate more logic into ProgressionType.
This commit is contained in:
Mark Punzalan
2020-05-02 00:17:26 -07:00
committed by Alexander Udalov
parent e1120f49d8
commit 177967258b
22 changed files with 192 additions and 94 deletions
@@ -289,6 +289,8 @@ abstract class Symbols<out T : CommonBackendContext>(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 ->
@@ -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<CommonBackendContext>): IrType = elementClassifier(symbols).defaultType
fun elementType(symbols: Symbols<CommonBackendContext>): 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<CommonBackendContext>): 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<CommonBackendContext>): 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<CommonBackendContext>): 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<CommonBackendContext>): 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<CommonBackendContext>): ProgressionType? = when {
irType.isSubtypeOfClass(symbols.charProgression) -> CHAR_PROGRESSION
@@ -68,7 +68,6 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
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<T : NumericHeaderInfo>(
// 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<T : NumericHeaderInfo>(
)
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<T : NumericHeaderInfo>(
/** 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<T : NumericHeaderInfo>(
inductionVariable.symbol, irCallOp(
plusFun.symbol, plusFun.returnType,
irGet(inductionVariable),
stepExpressionToUse
stepExpression
)
)
}
@@ -177,7 +157,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
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<T : NumericHeaderInfo>(
} 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<T : NumericHeaderInfo>(
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<T : NumericHeaderInfo>(
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<IndexedGetHeaderInfo>(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?,
@@ -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))
}
}
}
@@ -507,7 +507,7 @@ class JvmSymbols(
javaLangClass.functionByName("desiredAssertionStatus")
}
val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
override val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
buildFun {
name = Name.special("<unsafe-coerce>")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
@@ -35,4 +35,6 @@ fun box(): String {
// 1 INVOKESTATIC kotlin/internal/UProgressionUtilKt.getProgressionLastElement
// 0 NEW java/lang/IllegalArgumentException
// 0 ATHROW
// 0 IF
// 0 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -16,4 +16,6 @@ fun f(a: UInt): Int {
// 0 getLast
// 0 getStep
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
// 2 IF
// 2 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -16,4 +16,6 @@ fun f(a: ULong): Int {
// 0 getLast
// 0 getStep
// 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare
// 2 IF
// 2 IF
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
@@ -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
@@ -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
// 2 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -16,4 +16,6 @@ fun f(a: ULong): Int {
// 0 getLast
// 0 getStep
// 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare
// 2 IF
// 2 IF
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
// 4 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -38,4 +38,6 @@ fun box(): String {
// 1 NEW java/lang/IllegalArgumentException
// 1 ATHROW
// 0 IF
// 0 ARETURN
// 0 ARETURN
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -40,4 +40,6 @@ fun box(): String {
// 0 ATHROW
// 1 IFGT
// 1 IF_ICMPNE
// 2 IF
// 2 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -50,4 +50,6 @@ fun box(): String {
// 3 IFLE
// 1 IFGE
// 6 IF
// 0 INEG
// 0 INEG
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -54,4 +54,6 @@ fun box(): String {
// 4 IFLE
// 1 IFGE
// 7 IF
// 1 INEG
// 1 INEG
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -42,4 +42,6 @@ fun box(): String {
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
// 1 IFGT
// 1 IF_ICMPNE
// 2 IF
// 2 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
@@ -42,4 +42,6 @@ fun box(): String {
// 1 IFEQ
// 1 IFGT
// 1 IF_ICMPNE
// 3 IF
// 3 IF
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl