[K/N] Allow volatile intrinsics on inline function constant arguments
diff --git a/compiler/testData/codegen/box/volatile/initrinsicWithInlineFunction.kt b/compiler/testData/codegen/box/volatile/initrinsicWithInlineFunction.kt
new file mode 100644
index 0000000..4407515
--- /dev/null
+++ b/compiler/testData/codegen/box/volatile/initrinsicWithInlineFunction.kt
@@ -0,0 +1,27 @@
+// TARGET_BACKEND: NATIVE
+
+@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
+@file:OptIn(kotlin.ExperimentalStdlibApi::class)
+
+import kotlin.native.concurrent.*
+import kotlin.concurrent.*
+import kotlin.reflect.*
+
+
+class Box(@Volatile var value1: Int, @Volatile var value2: Int)
+
+inline fun KMutableProperty0<Int>.wrapCas(expected: Int, new: Int) = this.compareAndSwapField(expected, new)
+inline fun wrapCasTwice(expected: Int, new: Int, property: KMutableProperty0<Int>) = property.wrapCas(expected, new)
+
+fun box() : String {
+ val a = Box(1, 2)
+ (a::value1).wrapCas(1, 3)
+ (a::value2).wrapCas(2, 4)
+ if (a.value1 != 3) return "FAIL 1"
+ if (a.value2 != 4) return "FAIL 2"
+ wrapCasTwice(3, 5, a::value1)
+ wrapCasTwice( 4, 6, a::value2)
+ if (a.value1 != 5) return "FAIL 3"
+ if (a.value2 != 6) return "FAIL 4"
+ return "OK"
+}
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/VolatileFieldsLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/VolatileFieldsLowering.kt
index 34e5cc8..a2dddde 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/VolatileFieldsLowering.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/VolatileFieldsLowering.kt
@@ -203,11 +203,27 @@
IntrinsicType.GET_AND_ADD_FIELD to ::getAndAddFunction,
)
+ private fun resolveConstantProperty(expression: IrExpression?) : IrPropertyReference? = when (expression) {
+ null -> null
+ is IrPropertyReference -> expression
+ // This is required for handling calling intrinsic inside inline function,
+ // where constant property is passed in inline function argument.
+ // This is required for atomicfu atomic extensions machinery
+ is IrGetValue -> {
+ val variable = expression.symbol.owner as? IrVariable
+ resolveConstantProperty(variable?.takeIf { !it.isVar }?.initializer)
+ }
+ is IrBlock -> {
+ resolveConstantProperty(expression.statements.singleOrNull() as? IrExpression)
+ }
+ else -> null
+ }
+
override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid(this)
val intrinsicType = tryGetIntrinsicType(expression).takeIf { it in intrinsicMap } ?: return expression
builder.at(expression)
- val reference = expression.extensionReceiver as? IrPropertyReference
+ val reference = resolveConstantProperty(expression.extensionReceiver)
?: return unsupported("Only compile-time known IrProperties supported for $intrinsicType")
val property = reference.symbol.owner
val backingField = property.backingField
diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java
index cf0bf52..8b50ed0 100644
--- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java
+++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java
@@ -40273,6 +40273,12 @@
}
@Test
+ @TestMetadata("initrinsicWithInlineFunction.kt")
+ public void testInitrinsicWithInlineFunction() throws Exception {
+ runTest("compiler/testData/codegen/box/volatile/initrinsicWithInlineFunction.kt");
+ }
+
+ @Test
@TestMetadata("intrinsics.kt")
public void testIntrinsics() throws Exception {
runTest("compiler/testData/codegen/box/volatile/intrinsics.kt");
diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java
index d07a1c0..7340fd3 100644
--- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java
+++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java
@@ -39771,6 +39771,12 @@
}
@Test
+ @TestMetadata("initrinsicWithInlineFunction.kt")
+ public void testInitrinsicWithInlineFunction() throws Exception {
+ runTest("compiler/testData/codegen/box/volatile/initrinsicWithInlineFunction.kt");
+ }
+
+ @Test
@TestMetadata("intrinsics.kt")
public void testIntrinsics() throws Exception {
runTest("compiler/testData/codegen/box/volatile/intrinsics.kt");