Accept comparison of instance-of with the constant 2

We were assuming that the comparison of the result of an instance-of bytecode with an int constant would be only with 0 or 1. It potentially can be with any other int constant too.

Bug: 252804549
Fixes: 252804549
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Test: dex2oatd compiling the apps in the bug
Change-Id: Ia7d9352fb2074edfb2f74920f74a076f977e5dd4
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index cfbf2aa..2b0a118 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -430,10 +430,13 @@
         if (rhs->AsIntConstant()->IsTrue()) {
           // Case (1a)
           *trueBranch = ifInstruction->IfTrueSuccessor();
-        } else {
+        } else if (rhs->AsIntConstant()->IsFalse()) {
           // Case (2a)
-          DCHECK(rhs->AsIntConstant()->IsFalse()) << rhs->AsIntConstant()->GetValue();
           *trueBranch = ifInstruction->IfFalseSuccessor();
+        } else {
+          // Sometimes we see a comparison of instance-of with a constant which is neither 0 nor 1.
+          // In those cases, we cannot do the match if+instance-of.
+          return false;
         }
         *instanceOf = lhs->AsInstanceOf();
         return true;
@@ -447,10 +450,13 @@
         if (rhs->AsIntConstant()->IsFalse()) {
           // Case (1b)
           *trueBranch = ifInstruction->IfTrueSuccessor();
-        } else {
+        } else if (rhs->AsIntConstant()->IsTrue()) {
           // Case (2b)
-          DCHECK(rhs->AsIntConstant()->IsTrue()) << rhs->AsIntConstant()->GetValue();
           *trueBranch = ifInstruction->IfFalseSuccessor();
+        } else {
+          // Sometimes we see a comparison of instance-of with a constant which is neither 0 nor 1.
+          // In those cases, we cannot do the match if+instance-of.
+          return false;
         }
         *instanceOf = lhs->AsInstanceOf();
         return true;
diff --git a/test/2245-checker-smali-instance-of-comparison/expected-stderr.txt b/test/2245-checker-smali-instance-of-comparison/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/2245-checker-smali-instance-of-comparison/expected-stderr.txt
diff --git a/test/2245-checker-smali-instance-of-comparison/expected-stdout.txt b/test/2245-checker-smali-instance-of-comparison/expected-stdout.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/2245-checker-smali-instance-of-comparison/expected-stdout.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/2245-checker-smali-instance-of-comparison/info.txt b/test/2245-checker-smali-instance-of-comparison/info.txt
new file mode 100644
index 0000000..5c6df8e
--- /dev/null
+++ b/test/2245-checker-smali-instance-of-comparison/info.txt
@@ -0,0 +1 @@
+Smali test comparing instance-of (which returns 0 or 1) with a constant 2.
diff --git a/test/2245-checker-smali-instance-of-comparison/smali/b_252804549.smali b/test/2245-checker-smali-instance-of-comparison/smali/b_252804549.smali
new file mode 100644
index 0000000..38d4d0c
--- /dev/null
+++ b/test/2245-checker-smali-instance-of-comparison/smali/b_252804549.smali
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+.class public LB252804549;
+
+.super Ljava/lang/Object;
+
+## CHECK-START: int B252804549.compareInstanceOfWithTwo(java.lang.Object) builder (after)
+## CHECK-DAG: <<Const2:i\d+>>     IntConstant 2
+## CHECK-DAG: <<InstanceOf:z\d+>> InstanceOf
+## CHECK-DAG: <<Eq:z\d+>>         Equal [<<InstanceOf>>,<<Const2>>]
+## CHECK-DAG:                     If [<<Eq>>]
+.method public static compareInstanceOfWithTwo(Ljava/lang/Object;)I
+   .registers 2
+   instance-of v0, p0, Ljava/lang/String;
+   const/4 v1, 0x2
+   # Compare instance-of with 2 (i.e. neither 0 nor 1)
+   if-eq v0, v1, :Lequal
+   const/4 v1, 0x3
+   return v1
+:Lequal
+   return v1
+.end method
diff --git a/test/2245-checker-smali-instance-of-comparison/src/Main.java b/test/2245-checker-smali-instance-of-comparison/src/Main.java
new file mode 100644
index 0000000..cd9003a
--- /dev/null
+++ b/test/2245-checker-smali-instance-of-comparison/src/Main.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Method;
+
+/**
+ * Smali exercise, copied from 800-smali and modified for this test case.
+ */
+public class Main {
+    public static void main(String[] args) throws Exception {
+        System.loadLibrary(args[0]);
+        Object retValue = Class.forName("B252804549")
+                                  .getDeclaredMethod("compareInstanceOfWithTwo", Object.class)
+                                  .invoke(null, new Object[] {new Object()});
+        if (retValue == null || !retValue.equals(3)) {
+            throw new Exception("Expected 3, but got " + retValue);
+        }
+    }
+}
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index 90476b3..06d24d8 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -21,7 +21,7 @@
 import java.util.List;
 
 /**
- * Smali excercise.
+ * Smali exercise.
  */
 public class Main {
 
diff --git a/test/knownfailures.json b/test/knownfailures.json
index bbd20e9..d94e3df 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1079,7 +1079,8 @@
           "1946-list-descriptors",
           "1947-breakpoint-redefine-deopt",
           "2041-bad-cleaner",
-          "2230-profile-save-hotness"
+          "2230-profile-save-hotness",
+          "2245-checker-smali-instance-of-comparison"
         ],
         "variant": "jvm",
         "bug": "b/73888836",