diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index 020aa39c253..08753c89b15 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -28,11 +28,13 @@ import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.util.OperatorNameConventions @@ -70,13 +72,7 @@ internal fun T.resolveFakeOverride(): T { private val intrinsicAnnotation = FqName("konan.internal.Intrinsic") internal val CallableDescriptor.isIntrinsic: Boolean - get() = when { - this.annotations.hasAnnotation(intrinsicAnnotation) -> { - // check(isExternal, { "Intrinsic function $name should be external" }) - true - } - else -> false - } + get() = this.annotations.hasAnnotation(intrinsicAnnotation) private val intrinsicTypes = setOf( "kotlin.Boolean", "kotlin.Char", @@ -345,3 +341,6 @@ val ClassDescriptor.enumEntries: List internal val DeclarationDescriptor.isExpectMember: Boolean get() = this is MemberDescriptor && this.isExpect + +fun FunctionDescriptor.isComparisonDescriptor(map: Map): Boolean = + map.values.any { it.descriptor == this } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index eaa5a67b4da..b62753a6ed2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -2341,41 +2341,35 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map funGen.icmpEq(args[0], args[1]) - descriptor == ib.booleanNot -> funGen.icmpNe(args[0], kTrue) + with(functionGenerationContext) { + val arg0 = args[0] + val arg1 = args[1] + return when { + descriptor == ib.eqeqeq -> icmpEq(arg0, arg1) + descriptor == ib.booleanNot -> icmpNe(arg0, kTrue) - descriptor.isComparisonDescriptor(ib.greaterFunByOperandType) -> { - if (args[0].type.isFloatingPoint()) funGen.fcmpGt(args[0], args[1]) - else funGen.icmpGt(args[0], args[1]) + descriptor.isComparisonDescriptor(ib.greaterFunByOperandType) -> { + if (arg0.type.isFloatingPoint()) fcmpGt(arg0, arg1) + else icmpGt(arg0, arg1) + } + descriptor.isComparisonDescriptor(ib.greaterOrEqualFunByOperandType) -> { + if (arg0.type.isFloatingPoint()) fcmpGe(arg0, arg1) + else icmpGe(arg0, arg1) + } + descriptor.isComparisonDescriptor(ib.lessFunByOperandType) -> { + if (arg0.type.isFloatingPoint()) fcmpLt(arg0, arg1) + else icmpLt(arg0, arg1) + } + descriptor.isComparisonDescriptor(ib.lessOrEqualFunByOperandType) -> { + if (arg0.type.isFloatingPoint()) fcmpLe(arg0, arg1) + else icmpLe(arg0, arg1) + } + else -> TODO(descriptor.name.toString()) } - descriptor.isComparisonDescriptor(ib.greaterOrEqualFunByOperandType) -> { - if (args[0].type.isFloatingPoint()) funGen.fcmpGe(args[0], args[1]) - else funGen.icmpGe(args[0], args[1]) - } - descriptor.isComparisonDescriptor(ib.lessFunByOperandType) -> { - if (args[0].type.isFloatingPoint()) funGen.fcmpLt(args[0], args[1]) - else funGen.icmpLt(args[0], args[1]) - } - descriptor.isComparisonDescriptor(ib.lessOrEqualFunByOperandType) -> { - if (args[0].type.isFloatingPoint()) funGen.fcmpLe(args[0], args[1]) - else funGen.icmpLe(args[0], args[1]) - } - else -> TODO(descriptor.name.toString()) } } - private fun LLVMTypeRef.isFloatingPoint(): Boolean { - val typeKind = LLVMGetTypeKind(this) - return typeKind == LLVMTypeKind.LLVMFloatTypeKind || typeKind == LLVMTypeKind.LLVMDoubleTypeKind - } - - private fun FunctionDescriptor.isComparisonDescriptor(map: Map): Boolean { - return map.values.any { it.descriptor == this } - } - //-------------------------------------------------------------------------// private fun generateWhenCase(resultPhi: LLVMValueRef?, branch: IrBranch, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 05ba3b08667..09124bec676 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -307,3 +307,8 @@ internal fun String.mdString() = LLVMMDString(this, this.length)!! internal fun node(vararg it:LLVMValueRef) = LLVMMDNode(it.toList().toCValues(), it.size) internal fun LLVMValueRef.setUnaligned() = apply { LLVMSetAlignment(this, 1) } + +fun LLVMTypeRef.isFloatingPoint(): Boolean = when (llvm.LLVMGetTypeKind(this)) { + LLVMTypeKind.LLVMFloatTypeKind, LLVMTypeKind.LLVMDoubleTypeKind -> true + else -> false +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/box/ieee754/inline.kt b/backend.native/tests/external/codegen/box/ieee754/inline.kt index f4381928459..58a844412bc 100644 --- a/backend.native/tests/external/codegen/box/ieee754/inline.kt +++ b/backend.native/tests/external/codegen/box/ieee754/inline.kt @@ -1,4 +1,4 @@ -// IGNORE_BACKEND: JS! +// IGNORE_BACKEND: JS inline fun less(a: Comparable, b: Double): Boolean { return a < b diff --git a/runtime/src/main/kotlin/kotlin/Primitives.kt b/runtime/src/main/kotlin/kotlin/Primitives.kt index eb5ba7dc94c..361779688af 100644 --- a/runtime/src/main/kotlin/kotlin/Primitives.kt +++ b/runtime/src/main/kotlin/kotlin/Primitives.kt @@ -1016,11 +1016,7 @@ public final class Float : Number(), Comparable { val otherBits = other.toBits() // Canonical NaN bits representation higher than any other bit representvalue - return when { - (thisBits > otherBits) -> 1 - (thisBits < otherBits) -> -1 - else -> 0 - } + return thisBits.compareTo(otherBits) } /** @@ -1028,7 +1024,7 @@ public final class Float : Number(), Comparable { * Returns zero if this value is equal to the specified other value, a negative number if its less than other, * or a positive number if its greater than other. */ - public operator fun compareTo(other: Double): Int = - other.toDouble().compareTo(this) + public operator fun compareTo(other: Double): Int = - other.compareTo(this) /** Adds the other value to this value. */ @SymbolName("Kotlin_Float_plus_Byte") @@ -1250,11 +1246,7 @@ public final class Double : Number(), Comparable { val otherBits = other.toBits() // Canonical NaN bits representation higher than any other bit representvalue - return when { - (thisBits > otherBits) -> 1 - (thisBits < otherBits) -> -1 - else -> 0 - } + return thisBits.compareTo(otherBits) } /** Adds the other value to this value. */ @@ -1371,8 +1363,8 @@ public final class Double : Number(), Comparable { public override fun toShort(): Short = this.toInt().toShort() - public override fun toInt(): Int = this.toLong().toInt() - + @SymbolName("Kotlin_Double_toInt") + external public override fun toInt(): Int @SymbolName("Kotlin_Double_toLong") external public override fun toLong(): Long @SymbolName("Kotlin_Double_toFloat")