From d822d3e7c6592c2a230167979aacd3aec41e21ac Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Fri, 2 Sep 2022 11:24:16 +0200 Subject: [PATCH] [K/N] Reenable constant inlining except for Double nan constants ^KT-52970 --- .../testData/codegen/box/properties/const/kt52970.kt | 10 ++++++++-- .../jetbrains/kotlin/backend/konan/ToplevelPhases.kt | 8 ++++++-- .../kotlin/backend/konan/lower/ConstLowering.kt | 9 ++++++++- .../backend.native/tests/interop/basics/cmacros.def | 5 +++++ .../backend.native/tests/interop/basics/macros.kt | 5 +++++ 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/compiler/testData/codegen/box/properties/const/kt52970.kt b/compiler/testData/codegen/box/properties/const/kt52970.kt index 254bc617028..2634dc12d7e 100644 --- a/compiler/testData/codegen/box/properties/const/kt52970.kt +++ b/compiler/testData/codegen/box/properties/const/kt52970.kt @@ -1,7 +1,13 @@ open class A(val a: String = DEFAULT_A){ companion object: A(){ - const val DEFAULT_A = "OK" + const val DEFAULT_A = "O" } } -fun box() = A().a \ No newline at end of file +open class B(val b: String = DEFAULT_B){ + companion object: B(){ + const val DEFAULT_B = "K" + } +} + +fun box() = A.a + B().b \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index f5922799d6e..36c63252973 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.checkDeclarationParents @@ -276,8 +281,7 @@ internal val allLoweringsPhase = NamedCompilerPhase( coroutinesPhase, typeOperatorPhase, expressionBodyTransformPhase, -// Disabled for now because it leads to problems with Double.NaN and Float.NaN on macOS AArch 64. -// constantInliningPhase, + constantInliningPhase, fileInitializersPhase, bridgesPhase, exportInternalAbiPhase, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ConstLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ConstLowering.kt index 3f068b2a18c..d813847c582 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ConstLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ConstLowering.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrConst +import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -23,7 +24,13 @@ internal class ConstLowering(val context: Context) : FileLoweringPass { private class NativeInlineConstTransformer : InlineConstTransformer() { override val IrField.constantInitializer get() = - (initializer?.expression as? IrConst<*>)?.takeIf { correspondingPropertySymbol?.owner?.isConst == true } + (initializer?.expression as? IrConst<*>) + ?.takeIf { correspondingPropertySymbol?.owner?.isConst == true } + // NaN constants has inconsistencies between IR and metadata representation, + // so inlining them can lead to incorrect behaviour. Check KT-53258 for details. + ?.takeUnless { it.kind == IrConstKind.Double && IrConstKind.Double.valueOf(it).isNaN() } + ?.takeUnless { it.kind == IrConstKind.Float && IrConstKind.Float.valueOf(it).isNaN() } + override fun reportInlineConst(field: IrField, value: IrConst<*>) {} // on jvm IrGetObjectValue is also dropped. This would be breaking change for native. // Some design work is required to decide what is correct, let just keep current behaviour for now diff --git a/kotlin-native/backend.native/tests/interop/basics/cmacros.def b/kotlin-native/backend.native/tests/interop/basics/cmacros.def index 803a22a7bff..2af4171f1ea 100644 --- a/kotlin-native/backend.native/tests/interop/basics/cmacros.def +++ b/kotlin-native/backend.native/tests/interop/basics/cmacros.def @@ -76,3 +76,8 @@ enum { void increment(int* counter); #define increment(counter) { (*(counter))++; } + +#define DEFAULT_DOUBLE_NAN __builtin_nan("") +#define DEFAULT_FLOAT_NAN __builtin_nanf("") +#define OTHER_DOUBLE_NAN __builtin_nan("0x7ffc0123456789ab") +#define OTHER_FLOAT_NAN __builtin_nanf("0x7fc12345") diff --git a/kotlin-native/backend.native/tests/interop/basics/macros.kt b/kotlin-native/backend.native/tests/interop/basics/macros.kt index 826f3e70887..4973cfa36a0 100644 --- a/kotlin-native/backend.native/tests/interop/basics/macros.kt +++ b/kotlin-native/backend.native/tests/interop/basics/macros.kt @@ -45,4 +45,9 @@ fun main(args: Array) { increment(counter.ptr) assertEquals(43, counter.value) } + + assertEquals(Double.NaN.toRawBits(), DEFAULT_DOUBLE_NAN.toRawBits()) + assertEquals(Float.NaN.toRawBits(), DEFAULT_FLOAT_NAN.toRawBits()) + assertEquals(0x7fc12345, OTHER_FLOAT_NAN.toRawBits()) + assertEquals(0x7ffc0123456789abL, OTHER_DOUBLE_NAN.toRawBits()) }