[vm] Fix Type.hashCode asm intrinsic with compressed pointers

When loading cached hash code, asm intrinsic used LoadCompressed
which results in garbage in the high 32-bits of the register.
So the full register was not zero and intrinsic could return zero value
in the low 32-bits.

TEST=runtime/tests/vm/dart/regress_49672_test.dart
Fixes https://github.com/dart-lang/sdk/issues/49672

Change-Id: Ie800dcea02db5b54bd8bf7e9df0f437f09e92932
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305360
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/tests/vm/dart/regress_49672_test.dart b/runtime/tests/vm/dart/regress_49672_test.dart
new file mode 100644
index 0000000..5976918
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_49672_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that hash code of equal types is the same and not zero.
+// Regression test for https://github.com/dart-lang/sdk/issues/49672.
+
+import 'package:expect/expect.dart';
+
+class Foo<T> {
+  final brokenType = List<T>;
+}
+
+class Bar {}
+
+void test1<T>() {
+  Expect.equals(Foo<Bar>, Foo<Bar>);
+  Expect.equals((Foo<Bar>).hashCode, (Foo<Bar>).hashCode);
+  Expect.equals(Foo<T>, Foo<Bar>);
+  Expect.equals((Foo<T>).hashCode, (Foo<Bar>).hashCode);
+}
+
+void test2<T>() {
+  Expect.equals(Foo<Bar>, Foo<Bar>);
+  Expect.equals((Foo<Bar>).hashCode, (Foo<Bar>).hashCode);
+  Expect.equals(T, Foo<Bar>);
+  Expect.equals((T).hashCode, (Foo<Bar>).hashCode);
+}
+
+void main() {
+  test1<Bar>();
+  test2<Foo<Bar>>();
+
+  final a = Foo<Object>();
+  Expect.isTrue(a.brokenType.hashCode != 0);
+}
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index cf18f8d..aef8a16 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1362,8 +1362,8 @@
 void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
                                        Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ LoadCompressed(R0, FieldAddress(R0, target::Type::hash_offset()));
-  __ cbz(normal_ir_body, R0);
+  __ LoadCompressedSmi(R0, FieldAddress(R0, target::Type::hash_offset()));
+  __ cbz(normal_ir_body, R0, kObjectBytes);
   __ ret();
   // Hash not yet computed.
   __ Bind(normal_ir_body);
@@ -1432,8 +1432,9 @@
 void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ ldr(R0, Address(SP, 0 * target::kWordSize));
-  __ LoadCompressed(R0, FieldAddress(R0, target::FunctionType::hash_offset()));
-  __ cbz(normal_ir_body, R0);
+  __ LoadCompressedSmi(R0,
+                       FieldAddress(R0, target::FunctionType::hash_offset()));
+  __ cbz(normal_ir_body, R0, kObjectBytes);
   __ ret();
   // Hash not yet computed.
   __ Bind(normal_ir_body);
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index d323c74..51c2a6c 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1251,10 +1251,10 @@
 void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
                                        Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Type object.
-  __ LoadCompressed(RAX, FieldAddress(RAX, target::Type::hash_offset()));
+  __ LoadCompressedSmi(RAX, FieldAddress(RAX, target::Type::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
-  __ testq(RAX, RAX);
+  __ OBJ(test)(RAX, RAX);
   __ j(ZERO, normal_ir_body, Assembler::kNearJump);
   __ ret();
   __ Bind(normal_ir_body);
@@ -1325,11 +1325,11 @@
 void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
                                                Label* normal_ir_body) {
   __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // FunctionType object.
-  __ LoadCompressed(RAX,
-                    FieldAddress(RAX, target::FunctionType::hash_offset()));
+  __ LoadCompressedSmi(RAX,
+                       FieldAddress(RAX, target::FunctionType::hash_offset()));
   ASSERT(kSmiTag == 0);
   ASSERT(kSmiTagShift == 1);
-  __ testq(RAX, RAX);
+  __ OBJ(test)(RAX, RAX);
   __ j(ZERO, normal_ir_body, Assembler::kNearJump);
   __ ret();
   __ Bind(normal_ir_body);