Fix specialization of equality comparison calls for inline classes

Receiver of equals() call should be checked instead of argument

^KT-57261: Fixed
diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
index a030bf1..49055d8 100644
--- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
+++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java
@@ -22614,6 +22614,12 @@
         }
 
         @Test
+        @TestMetadata("kt57261.kt")
+        public void testKt57261() throws Exception {
+            runTest("compiler/testData/codegen/box/inlineClasses/kt57261.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
+        }
+
+        @Test
         @TestMetadata("lateinitInlineClasses.kt")
         public void testLateinitInlineClasses() throws Exception {
             runTest("compiler/testData/codegen/box/inlineClasses/lateinitInlineClasses.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
index 8118349..6139f40 100644
--- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
+++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java
@@ -22614,6 +22614,12 @@
         }
 
         @Test
+        @TestMetadata("kt57261.kt")
+        public void testKt57261() throws Exception {
+            runTest("compiler/testData/codegen/box/inlineClasses/kt57261.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
+        }
+
+        @Test
         @TestMetadata("lateinitInlineClasses.kt")
         public void testLateinitInlineClasses() throws Exception {
             runTest("compiler/testData/codegen/box/inlineClasses/lateinitInlineClasses.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt
index 2d5a80f..21f1bb8 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt
@@ -22,7 +22,6 @@
 import org.jetbrains.kotlin.ir.declarations.*
 import org.jetbrains.kotlin.ir.expressions.*
 import org.jetbrains.kotlin.ir.expressions.impl.*
-import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
 import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
 import org.jetbrains.kotlin.ir.transformStatement
 import org.jetbrains.kotlin.ir.types.*
@@ -335,11 +334,11 @@
                 coerceInlineClasses(arg, expression.symbol.owner.dispatchReceiverParameter!!.type, expression.type)
             }
             // Specialize calls to equals when the left argument is a value of inline class type.
-            expression.isSpecializedInlineClassEqEq || expression.isSpecializedInlineClassEquals -> {
+            expression.isEqEqCallOnInlineClass || expression.isEqualsMethodCallOnInlineClass -> {
                 expression.transformChildrenVoid()
                 val leftOp: IrExpression
                 val rightOp: IrExpression
-                if (expression.isSpecializedInlineClassEqEq) {
+                if (expression.isEqEqCallOnInlineClass) {
                     leftOp = expression.getValueArgument(0)!!
                     rightOp = expression.getValueArgument(1)!!
                 } else {
@@ -354,29 +353,29 @@
                 super.visitCall(expression)
         }
 
-    private val IrCall.isSpecializedInlineClassEquals: Boolean
+    private val IrCall.isEqualsMethodCallOnInlineClass: Boolean
         get() {
-            return isSpecializedInlineClassEqualityCheck { symbol.owner.isEquals() }
+            if (!symbol.owner.isEquals()) return false
+            val receiverClass = dispatchReceiver?.type?.classOrNull?.owner
+            return receiverClass?.canUseSpecializedEqMethod ?: false
         }
 
-    private val IrCall.isSpecializedInlineClassEqEq: Boolean
+    private val IrCall.isEqEqCallOnInlineClass: Boolean
         get() {
             // Note that reference equality (x === y) is not allowed on values of inline class type,
             // so it is enough to check for eqeq.
-            return isSpecializedInlineClassEqualityCheck { symbol == context.irBuiltIns.eqeqSymbol }
+            if (symbol != context.irBuiltIns.eqeqSymbol) return false
+            val leftOperandClass = getValueArgument(0)?.type?.classOrNull?.owner
+            return leftOperandClass?.canUseSpecializedEqMethod ?: false
         }
 
-    private inline fun IrCall.isSpecializedInlineClassEqualityCheck(calleePredicate: (IrSimpleFunctionSymbol) -> Boolean): Boolean {
-
-        if (!calleePredicate(symbol)) return false
-
-        val leftClass = getValueArgument(0)?.type?.classOrNull?.owner?.takeIf { it.isSingleFieldValueClass }
-            ?: return false
-
-        // Before version 1.4, we cannot rely on the Result.equals-impl0 method
-        return (leftClass.fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME) ||
-                context.state.languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
-    }
+    private val IrClass.canUseSpecializedEqMethod: Boolean
+        get() {
+            if (!isSingleFieldValueClass) return false
+            // Before version 1.4, we cannot rely on the Result.equals-impl0 method
+            return fqNameWhenAvailable != StandardNames.RESULT_FQ_NAME ||
+                    context.state.languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
+        }
 
     override fun visitGetField(expression: IrGetField): IrExpression {
         val field = expression.symbol.owner
diff --git a/compiler/testData/codegen/box/inlineClasses/kt57261.kt b/compiler/testData/codegen/box/inlineClasses/kt57261.kt
new file mode 100644
index 0000000..83a2d21
--- /dev/null
+++ b/compiler/testData/codegen/box/inlineClasses/kt57261.kt
@@ -0,0 +1,19 @@
+// TARGET_BACKEND: JVM_IR
+// WITH_STDLIB
+// WORKS_WHEN_VALUE_CLASS
+// LANGUAGE: +ValueClasses
+
+OPTIONAL_JVM_INLINE_ANNOTATION
+value class Ic(val x: Int)
+
+fun box(): String {
+
+    val strAsAny : Any = "a"
+
+    if ("a".equals(Ic(1))) return "Fail 1"
+    if (strAsAny.equals(Ic(1))) return "Fail 2"
+    if (Ic(1).equals("a")) return "Fail 3"
+    if (Ic(1).equals(strAsAny)) return "Fail 4"
+
+    return "OK"
+}
\ No newline at end of file
diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
index 6da1be1..47a4bbe 100644
--- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java
@@ -22614,6 +22614,12 @@
         }
 
         @Test
+        @TestMetadata("kt57261.kt")
+        public void testKt57261() throws Exception {
+            runTest("compiler/testData/codegen/box/inlineClasses/kt57261.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
+        }
+
+        @Test
         @TestMetadata("lateinitInlineClasses.kt")
         public void testLateinitInlineClasses() throws Exception {
             runTest("compiler/testData/codegen/box/inlineClasses/lateinitInlineClasses.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());