[VM] Only use strict comparisons if the receiver has a numeric type

Change-Id: Ic8b13ac45fd9ac71fea96503226f74d52364b90c
Reviewed-on: https://dart-review.googlesource.com/c/84529
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 342b101..d905077 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -432,8 +432,9 @@
     CompileType* right_type = right_value->Type();
 
     const bool is_equality_op = Token::IsEqualityOperator(op_kind);
+    const bool receiver_is_nullable_numeric = left_type->IsNullableNumeric();
     const bool can_use_strict_compare =
-        is_equality_op &&
+        is_equality_op && receiver_is_nullable_numeric &&
         (left_type->IsNullableSmi() || right_type->IsNullableSmi());
     const bool has_nullable_int_args =
         left_type->IsNullableInt() && right_type->IsNullableInt();
@@ -458,8 +459,7 @@
             right_type->IsInt();
 
         // We prefer equality compare, since it doesn't require boxing.
-        if (is_equality_op && !can_use_equality_compare &&
-            (left_type->IsNullableSmi() || right_type->IsNullableSmi())) {
+        if (!can_use_equality_compare && can_use_strict_compare) {
           replacement = new (Z) StrictCompareInstr(
               instr->token_pos(),
               (op_kind == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index dff225c..32415aa 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -226,6 +226,18 @@
     return false;
   }
 
+  // Returns true if value of this type is either Smi, Mint, Double or null.
+  bool IsNullableNumeric() {
+    if (cid_ == kSmiCid || cid_ == kMintCid || cid_ == kDoubleCid) {
+      return true;
+    }
+    if (cid_ == kIllegalCid || cid_ == kDynamicCid) {
+      return type_ != NULL && (type_->IsIntType() || type_->IsDoubleType() ||
+                               type_->IsNumberType());
+    }
+    return false;
+  }
+
   void PrintTo(BufferFormatter* f) const;
   const char* ToCString() const;