[vm/arm64] Avoid conditional branch to ret in identical() stub

This is attempt to workaround a possible CPU bug on Exynos 2100 SoC.

The fix is tentative as we were unable to locate an erratum which
matches the symptoms and the specific code pattern.

https://github.com/flutter/flutter/issues/88261

TEST=user manually verified the fix on a Exynos 2100 SoC device

Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm64-try,vm-ffi-android-release-arm64-try
Change-Id: I3be20d47d710a6bc520f2f7d6da81483baf74787
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211240
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 2c1288d..8694eb4 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -3173,15 +3173,14 @@
 }
 
 // Does identical check (object references are equal or not equal) with special
-// checks for boxed numbers.
-// Left and right are pushed on stack.
-// Return Zero condition flag set if equal.
-// Note: A Mint cannot contain a value that would fit in Smi.
+// checks for boxed numbers and returns with ZF set iff left and right are
+// identical.
 static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
                                                  const Register left,
                                                  const Register right) {
-  Label reference_compare, done, check_mint;
+  Label reference_compare, check_mint;
   // If any of the arguments is Smi do reference compare.
+  // Note: A Mint cannot contain a value that would fit in Smi.
   __ BranchIfSmi(left, &reference_compare);
   __ BranchIfSmi(right, &reference_compare);
 
@@ -3189,27 +3188,31 @@
   __ CompareClassId(left, kDoubleCid);
   __ b(&check_mint, NE);
   __ CompareClassId(right, kDoubleCid);
-  __ b(&done, NE);
+  __ b(&reference_compare, NE);  // Do not branch directly to ret! See below.
 
   // Double values bitwise compare.
   __ LoadFieldFromOffset(left, left, target::Double::value_offset());
   __ LoadFieldFromOffset(right, right, target::Double::value_offset());
   __ CompareRegisters(left, right);
-  __ b(&done);
+  __ ret();
 
   __ Bind(&check_mint);
   __ CompareClassId(left, kMintCid);
   __ b(&reference_compare, NE);
   __ CompareClassId(right, kMintCid);
-  __ b(&done, NE);
+  __ b(&reference_compare, NE);  // Do not branch directly to ret! See below.
   __ LoadFieldFromOffset(left, left, target::Mint::value_offset());
   __ LoadFieldFromOffset(right, right, target::Mint::value_offset());
   __ CompareRegisters(left, right);
-  __ b(&done);
+  __ ret();
 
   __ Bind(&reference_compare);
   __ CompareObjectRegisters(left, right);
-  __ Bind(&done);
+  // None of the branches above go directly here to avoid generating a conditional 
+  // branch to a ret instruction.
+  // This is an attempt to work-around a possible CPU on Exynos 2100 SoC.
+  // See https://github.com/flutter/flutter/issues/88261
+  __ ret();
 }
 
 // Called only from unoptimized code. All relevant registers have been saved.
@@ -3235,7 +3238,6 @@
   __ LoadFromOffset(left, SP, 1 * target::kWordSize);
   __ LoadFromOffset(right, SP, 0 * target::kWordSize);
   GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
 
 #if !defined(PRODUCT)
   __ Bind(&stepping);
@@ -3259,7 +3261,6 @@
   __ LoadFromOffset(left, SP, 1 * target::kWordSize);
   __ LoadFromOffset(right, SP, 0 * target::kWordSize);
   GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
 }
 
 // Called from megamorphic call sites.