[FIR] Use ieee754equals for floating-point equality operations

This commit is contained in:
Mark Punzalan
2020-04-16 23:01:32 -07:00
committed by Mikhail Glukhikh
parent d66281d11f
commit b74652aa5b
36 changed files with 85 additions and 491 deletions
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.getSimpleFunction
import java.util.*
internal class OperatorExpressionGenerator(
private val components: Fir2IrComponents,
@@ -28,12 +27,6 @@ internal class OperatorExpressionGenerator(
private val callGenerator: CallAndReferenceGenerator
) : Fir2IrComponents by components {
companion object {
private val NEGATED_OPERATIONS: Set<FirOperation> = EnumSet.of(FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY)
private val UNARY_OPERATIONS: Set<FirOperation> = EnumSet.of(FirOperation.EXCL)
}
fun convertComparisonExpression(comparisonExpression: FirComparisonExpression): IrExpression {
return comparisonExpression.convertWithOffsets { startOffset, endOffset ->
generateComparisonCall(startOffset, endOffset, comparisonExpression)
@@ -92,39 +85,60 @@ internal class OperatorExpressionGenerator(
private fun generateOperatorCall(
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
): IrExpression {
val (type, symbol, origin) = when (operation) {
FirOperation.EQ -> Triple(irBuiltIns.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ)
FirOperation.NOT_EQ -> Triple(irBuiltIns.booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ)
FirOperation.IDENTITY -> Triple(irBuiltIns.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ)
FirOperation.NOT_IDENTITY -> Triple(irBuiltIns.booleanType, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EXCLEQEQ)
FirOperation.EXCL -> Triple(irBuiltIns.booleanType, irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL)
FirOperation.LT, FirOperation.GT,
FirOperation.LT_EQ, FirOperation.GT_EQ,
FirOperation.OTHER, FirOperation.ASSIGN, FirOperation.PLUS_ASSIGN,
FirOperation.MINUS_ASSIGN, FirOperation.TIMES_ASSIGN,
FirOperation.DIV_ASSIGN, FirOperation.REM_ASSIGN,
FirOperation.IS, FirOperation.NOT_IS,
FirOperation.AS, FirOperation.SAFE_AS
-> {
TODO("Should not be here: incompatible operation in FirOperatorCall: $operation")
}
}
val result = if (operation in UNARY_OPERATIONS) {
primitiveOp1(startOffset, endOffset, symbol, type, origin, visitor.convertToIrExpression(arguments[0]))
} else {
val comparisonInfo = inferPrimitiveNumericComparisonInfo(arguments[0], arguments[1])
val comparisonType = comparisonInfo?.comparisonType
primitiveOp2(
startOffset, endOffset, symbol, type, origin,
visitor.convertToIrExpression(arguments[0]).asComparisonOperand(comparisonInfo?.leftType, comparisonType),
visitor.convertToIrExpression(arguments[1]).asComparisonOperand(comparisonInfo?.rightType, comparisonType)
)
}
if (operation !in NEGATED_OPERATIONS) return result
return primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, irBuiltIns.booleanType, origin, result)
): IrExpression = when (operation) {
FirOperation.EQ, FirOperation.NOT_EQ -> generateEqualityOperatorCall(startOffset, endOffset, operation, arguments)
FirOperation.IDENTITY, FirOperation.NOT_IDENTITY -> generateIdentityOperatorCall(startOffset, endOffset, operation, arguments)
FirOperation.EXCL -> visitor.convertToIrExpression(arguments[0]).negate(IrStatementOrigin.EXCL)
else -> error("Unexpected operation: $operation")
}
private fun generateEqualityOperatorCall(
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
): IrExpression {
val origin = when (operation) {
FirOperation.EQ -> IrStatementOrigin.EQEQ
FirOperation.NOT_EQ -> IrStatementOrigin.EXCLEQ
else -> error("Not an equality operation: $operation")
}
val comparisonInfo = inferPrimitiveNumericComparisonInfo(arguments[0], arguments[1])
val comparisonType = comparisonInfo?.comparisonType
val eqeqSymbol = comparisonType?.let { typeConverter.classIdToSymbolMap[it.lookupTag.classId] }
?.let { irBuiltIns.ieee754equalsFunByOperandType[it] } ?: irBuiltIns.eqeqSymbol
val equalsCall = primitiveOp2(
startOffset, endOffset, eqeqSymbol, irBuiltIns.booleanType, origin,
visitor.convertToIrExpression(arguments[0]).asComparisonOperand(comparisonInfo?.leftType, comparisonType),
visitor.convertToIrExpression(arguments[1]).asComparisonOperand(comparisonInfo?.rightType, comparisonType)
)
return if (operation == FirOperation.EQ) {
equalsCall
} else {
equalsCall.negate(origin)
}
}
private fun generateIdentityOperatorCall(
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
): IrExpression {
val origin = when (operation) {
FirOperation.IDENTITY -> IrStatementOrigin.EQEQEQ
FirOperation.NOT_IDENTITY -> IrStatementOrigin.EXCLEQEQ
else -> error("Not an identity operation: $operation")
}
val identityCall = primitiveOp2(
startOffset, endOffset, irBuiltIns.eqeqeqSymbol, irBuiltIns.booleanType, origin,
visitor.convertToIrExpression(arguments[0]),
visitor.convertToIrExpression(arguments[1])
)
return if (operation == FirOperation.IDENTITY) {
identityCall
} else {
identityCall.negate(origin)
}
}
private fun IrExpression.negate(origin: IrStatementOrigin) =
primitiveOp1(startOffset, endOffset, irBuiltIns.booleanNotSymbol, irBuiltIns.booleanType, origin, this)
private fun IrExpression.asComparisonOperand(
operandType: ConeClassLikeType?,
targetType: ConeClassLikeType?
@@ -29,10 +29,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
@@ -216,10 +213,21 @@ fun IrDeclaration.isInCurrentModule(): Boolean =
// This is needed to pinpoint exceptional treatment of IEEE754 floating point comparisons, where proper IEEE
// comparisons are used "if values are statically known to be of primitive numeric types", taken to mean as
// "not learned through smartcasting".
fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext) =
this is IrTypeOperatorCall &&
operator == IrTypeOperator.IMPLICIT_CAST &&
!this.argument.type.isSubtypeOf(type.makeNullable(), context.irBuiltIns)
fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext): Boolean {
return when (this) {
is IrTypeOperatorCall -> operator == IrTypeOperator.IMPLICIT_CAST && !argument.type.isSubtypeOf(
type.makeNullable(),
context.irBuiltIns
)
is IrGetValue -> {
// Check if the variable initializer is smartcast. In FIR, if the subject of a `when` is smartcast,
// the IMPLICIT_CAST is in the initializer of the variable for the subject.
val variable = (symbol as? IrVariableSymbol)?.owner ?: return false
!variable.isVar && variable.initializer?.isSmartcastFromHigherThanNullable(context) == true
}
else -> false
}
}
fun IrBody.replaceThisByStaticReference(
declarationFactory: JvmDeclarationFactory,
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun eq_double_doubleN(a: Double, b: Double?) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun <A: Double, B: Double?> eq_double_doubleN(a: A, b: B) = a == b
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val plusZero: Any = 0.0
val minusZero: Any = -0.0
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: JS_IR
fun equals1(a: Double, b: Double) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun equals1(a: Double, b: Double) = a == b
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: JS_IR
fun equals1(a: Float, b: Float) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun equals1(a: Float, b: Float) = a == b
-1
View File
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: JS_IR
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: JS_IR
fun equals1(a: Double, b: Double?) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun equals1(a: Double, b: Double?) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: -ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
// DONT_TARGET_EXACT_BACKEND: JS_IR
fun equals1(a: Float, b: Float?) = a == b
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun equals1(a: Float, b: Float?) = a == b
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: b.kt
class Foo<T>(val minus0: T, val plus0: T) {
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
inline fun less(a: Comparable<Double>, b: Double): Boolean {
return a < b
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val plusZero: Any? = 0.0
val minusZero: Any? = -0.0
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun eqDI(x: Any?, y: Any?) = x is Double? && y is Int? && x == y
fun eqDL(x: Any?, y: Any?) = x is Double? && y is Long? && x == y
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun ne(x: Any, y: Any) = x is Double && y is Float && x != y
fun lt(x: Any, y: Any) = x is Double && y is Float && x < y
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
val minus: Any = -0.0
-1
View File
@@ -14,7 +14,6 @@ fun box(): String {
-0.0 -> {
return "fail 2"
}
else -> {}
}
if (minusZero is Double) {
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val plusZero: Any = 0.0
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun box(): String {
val plusZero: Any = 0.0
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun eqeq(x: Any, y: Any) =
x is Double && y is Double && x == y
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperIeee754Comparisons
// IGNORE_BACKEND_FIR: JVM_IR
fun eqeq(x: Any, y: Any) =
x is Float && y is Float && x == y
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// This test checks that our bytecode is consistent with javac bytecode
@@ -1,5 +1,4 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// IGNORE_BACKEND_FIR: JVM_IR
val dz = -0.0
val fz = -0.0f
@@ -1,195 +0,0 @@
FILE fqName:<root> fileName:/floatingPointEqeq.kt
FUN name:test1d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Double) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Double
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1d (x: kotlin.Double, y: kotlin.Double): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test1d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Double declared in <root>.test1d' type=kotlin.Double origin=null
FUN name:test2d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Double?) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Double?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2d (x: kotlin.Double, y: kotlin.Double?): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test2d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Double? declared in <root>.test2d' type=kotlin.Double? origin=null
FUN name:test3d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3d (x: kotlin.Double, y: kotlin.Any): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test3d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Any declared in <root>.test3d' type=kotlin.Any origin=null
FUN name:test4d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Number) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Number
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4d (x: kotlin.Double, y: kotlin.Number): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test4d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Number declared in <root>.test4d' type=kotlin.Number origin=null
FUN name:test5d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test5d (x: kotlin.Double, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test5d' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test5d' type=kotlin.Double origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test5d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test6d visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test6d (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test1f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Float) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Float
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1f (x: kotlin.Float, y: kotlin.Float): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test1f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Float declared in <root>.test1f' type=kotlin.Float origin=null
FUN name:test2f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Float?) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Float?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2f (x: kotlin.Float, y: kotlin.Float?): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test2f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Float? declared in <root>.test2f' type=kotlin.Float? origin=null
FUN name:test3f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3f (x: kotlin.Float, y: kotlin.Any): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test3f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Any declared in <root>.test3f' type=kotlin.Any origin=null
FUN name:test4f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Number) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Number
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4f (x: kotlin.Float, y: kotlin.Number): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test4f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Number declared in <root>.test4f' type=kotlin.Number origin=null
FUN name:test5f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test5f (x: kotlin.Float, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test5f' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test5f' type=kotlin.Float origin=null
arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test5f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test6f visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test6f (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:testFD visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testFD (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:testDF visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testDF (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
arg1: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun test1d(x: Double, y: Double) = x == y
fun test2d(x: Double, y: Double?) = x == y
fun test3d(x: Double, y: Any) = x == y
@@ -1,209 +0,0 @@
FILE fqName:<root> fileName:/floatingPointExcleq.kt
FUN name:test1d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Double) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Double
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1d (x: kotlin.Double, y: kotlin.Double): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test1d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Double declared in <root>.test1d' type=kotlin.Double origin=null
FUN name:test2d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Double?) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Double?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2d (x: kotlin.Double, y: kotlin.Double?): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test2d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Double? declared in <root>.test2d' type=kotlin.Double? origin=null
FUN name:test3d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3d (x: kotlin.Double, y: kotlin.Any): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test3d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Any declared in <root>.test3d' type=kotlin.Any origin=null
FUN name:test4d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Number) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Number
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4d (x: kotlin.Double, y: kotlin.Number): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test4d' type=kotlin.Double origin=null
arg1: GET_VAR 'y: kotlin.Number declared in <root>.test4d' type=kotlin.Number origin=null
FUN name:test5d visibility:public modality:FINAL <> (x:kotlin.Double, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Double
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test5d (x: kotlin.Double, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test5d' type=kotlin.Any origin=null
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Double declared in <root>.test5d' type=kotlin.Double origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test5d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test6d visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test6d (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.test6d' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test1f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Float) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Float
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1f (x: kotlin.Float, y: kotlin.Float): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test1f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Float declared in <root>.test1f' type=kotlin.Float origin=null
FUN name:test2f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Float?) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Float?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2f (x: kotlin.Float, y: kotlin.Float?): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test2f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Float? declared in <root>.test2f' type=kotlin.Float? origin=null
FUN name:test3f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3f (x: kotlin.Float, y: kotlin.Any): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test3f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Any declared in <root>.test3f' type=kotlin.Any origin=null
FUN name:test4f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Number) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Number
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4f (x: kotlin.Float, y: kotlin.Number): kotlin.Boolean declared in <root>'
CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test4f' type=kotlin.Float origin=null
arg1: GET_VAR 'y: kotlin.Number declared in <root>.test4f' type=kotlin.Number origin=null
FUN name:test5f visibility:public modality:FINAL <> (x:kotlin.Float, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Float
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test5f (x: kotlin.Float, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test5f' type=kotlin.Any origin=null
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: GET_VAR 'x: kotlin.Float declared in <root>.test5f' type=kotlin.Float origin=null
arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test5f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:test6f visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test6f (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.test6f' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:testFD visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testFD (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.testFD' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
FUN name:testDF visibility:public modality:FINAL <> (x:kotlin.Any, y:kotlin.Any) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.Any
VALUE_PARAMETER name:y index:1 type:kotlin.Any
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testDF (x: kotlin.Any, y: kotlin.Any): kotlin.Boolean declared in <root>'
WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: WHEN type=kotlin.Boolean origin=ANDAND
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'x: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
arg1: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'y: kotlin.Any declared in <root>.testDF' type=kotlin.Any origin=null
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun test1d(x: Double, y: Double) = x != y
fun test2d(x: Double, y: Double?) = x != y
fun test3d(x: Double, y: Any) = x != y
@@ -4,7 +4,7 @@ FILE fqName:<root> fileName:/nullableFloatingPointEqeq.kt
VALUE_PARAMETER name:y index:1 type:kotlin.Double?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun testDD (x: kotlin.Double?, y: kotlin.Double?): kotlin.Boolean declared in <root>'
CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double? declared in <root>.testDD' type=kotlin.Double? origin=null
arg1: GET_VAR 'y: kotlin.Double? declared in <root>.testDD' type=kotlin.Double? origin=null
FUN name:testDF visibility:public modality:FINAL <> (x:kotlin.Double?, y:kotlin.Any?) returnType:kotlin.Boolean
@@ -16,7 +16,7 @@ FILE fqName:<root> fileName:/nullableFloatingPointEqeq.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float?
GET_VAR 'y: kotlin.Any? declared in <root>.testDF' type=kotlin.Any? origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double? declared in <root>.testDF' type=kotlin.Double? origin=null
arg1: BLOCK type=kotlin.Double? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Float? [val]
@@ -44,7 +44,7 @@ FILE fqName:<root> fileName:/nullableFloatingPointEqeq.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int?
GET_VAR 'y: kotlin.Any? declared in <root>.testDI' type=kotlin.Any? origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Double? declared in <root>.testDI' type=kotlin.Double? origin=null
arg1: BLOCK type=kotlin.Double? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int? [val]
@@ -79,7 +79,7 @@ FILE fqName:<root> fileName:/nullableFloatingPointEqeq.kt
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Boolean type=kotlin.Boolean value=false
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: BLOCK type=kotlin.Double? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int? [val]
TYPE_OP type=kotlin.Int? origin=IMPLICIT_CAST typeOperand=kotlin.Int?
@@ -26,7 +26,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test1' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Float?, arg1: kotlin.Float?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test1' type=kotlin.Any origin=null
arg1: GET_VAR 'y: T of <root>.test1 declared in <root>.test1' type=T of <root>.test1 origin=null
@@ -43,7 +43,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test2' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
GET_VAR 'x: kotlin.Any declared in <root>.test2' type=kotlin.Any origin=null
@@ -61,7 +61,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test3' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Float?, arg1: kotlin.Float?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toFloat (): kotlin.Float declared in kotlin.Int' type=kotlin.Float origin=null
$this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test3' type=kotlin.Any origin=null
@@ -79,7 +79,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test4' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Float?, arg1: kotlin.Float?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toFloat (): kotlin.Float declared in kotlin.Int' type=kotlin.Float origin=null
$this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test4' type=kotlin.Any origin=null
@@ -98,7 +98,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Float?, arg1: kotlin.Float?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toFloat (): kotlin.Float declared in kotlin.Int' type=kotlin.Float origin=null
$this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
GET_VAR 'x: kotlin.Any declared in <root>.test5' type=kotlin.Any origin=null
@@ -140,7 +140,7 @@ FILE fqName:<root> fileName:/typeParameterWithPrimitiveNumericSupertype.kt
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.F.testCapturedType' type=kotlin.Any origin=null
then: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
then: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: GET_VAR 'x: T of <root>.F declared in <root>.F.testCapturedType' type=T of <root>.F origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
@@ -8,7 +8,7 @@ FILE fqName:<root> fileName:/whenByFloatingPoint.kt
GET_VAR 'x: kotlin.Double declared in <root>.testSimple' type=kotlin.Double origin=null
WHEN type=kotlin.Int origin=WHEN
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
if: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_0: kotlin.Double [val] declared in <root>.testSimple' type=kotlin.Double origin=null
arg1: CONST Double type=kotlin.Double value=0.0
then: CONST Int type=kotlin.Int value=0
@@ -32,7 +32,7 @@ FILE fqName:<root> fileName:/whenByFloatingPoint.kt
GET_VAR 'x: kotlin.Any declared in <root>.testSmartCastInWhenSubject' type=kotlin.Any origin=null
WHEN type=kotlin.Int origin=WHEN
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
if: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_1: kotlin.Double [val] declared in <root>.testSmartCastInWhenSubject' type=kotlin.Double origin=null
arg1: CONST Double type=kotlin.Double value=0.0
then: CONST Int type=kotlin.Int value=0
@@ -56,7 +56,7 @@ FILE fqName:<root> fileName:/whenByFloatingPoint.kt
GET_VAR 'x: kotlin.Double declared in <root>.testSmartCastInWhenCondition' type=kotlin.Double origin=null
WHEN type=kotlin.Int origin=WHEN
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
if: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_2: kotlin.Double [val] declared in <root>.testSmartCastInWhenCondition' type=kotlin.Double origin=null
arg1: TYPE_OP type=kotlin.Double origin=IMPLICIT_CAST typeOperand=kotlin.Double
GET_VAR 'y: kotlin.Any declared in <root>.testSmartCastInWhenCondition' type=kotlin.Any origin=null
@@ -110,7 +110,7 @@ FILE fqName:<root> fileName:/whenByFloatingPoint.kt
GET_VAR 'x: kotlin.Any declared in <root>.testSmartCastToDifferentTypes' type=kotlin.Any origin=null
WHEN type=kotlin.Int origin=WHEN
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
if: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp_4: kotlin.Double [val] declared in <root>.testSmartCastToDifferentTypes' type=kotlin.Double origin=null
arg1: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Float' type=kotlin.Double origin=null
$this: TYPE_OP type=kotlin.Float origin=IMPLICIT_CAST typeOperand=kotlin.Float
@@ -16,7 +16,7 @@ FILE fqName:<root> fileName:/coercionInLoop.kt
WHEN type=kotlin.Unit origin=IF
BRANCH
if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
$this: CALL 'public final fun ieee754equals (arg0: kotlin.Double?, arg1: kotlin.Double?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'public final fun get (index: kotlin.Int): kotlin.Double [operator] declared in kotlin.DoubleArray' type=kotlin.Double origin=null
$this: GET_VAR 'val a: kotlin.DoubleArray [val] declared in <root>.box' type=kotlin.DoubleArray origin=null
index: GET_VAR 'var i: kotlin.Int [var] declared in <root>.box' type=kotlin.Int origin=null