[vm/compiler] Forward the ByteData constructor length argument.

In addition, if a _ByteDataView came from a use of the ByteData
constructor, its offset is always 0.

Also add appropriate canonicalization for the following instructions for
typed data views coming from a known factory call:

* LoadField getting type arguments
* GuardFieldLength

This closes https://github.com/dart-lang/sdk/issues/36570.

Change-Id: I1c045edb2d928c3bb3340d9d12009c2afa66febb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102362
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Teagan Strickland <sstrickl@google.com>
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 7edc129..c554d5a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2778,6 +2778,11 @@
       if (call->is_known_list_constructor() &&
           IsFixedLengthArrayCid(call->Type()->ToCid())) {
         return call->ArgumentAt(1);
+      } else if (call->function().recognized_kind() ==
+                 MethodRecognizer::kByteDataFactory) {
+        // Similarly, we check for the ByteData constructor and forward its
+        // explicit length argument appropriately.
+        return call->ArgumentAt(1);
       } else if (IsTypedDataViewFactory(call->function())) {
         // Typed data view factories all take three arguments (after
         // the implicit type arguments parameter):
@@ -2820,6 +2825,11 @@
     if (StaticCallInstr* call = array->AsStaticCall()) {
       if (IsTypedDataViewFactory(call->function())) {
         return call->ArgumentAt(2);
+      } else if (call->function().recognized_kind() ==
+                 MethodRecognizer::kByteDataFactory) {
+        // A _ByteDataView returned from the ByteData constructor always
+        // has an offset of 0.
+        return flow_graph->GetConstant(Smi::Handle(Smi::New(0)));
       }
     }
   } else if (slot().IsTypeArguments()) {
@@ -2827,10 +2837,16 @@
     if (StaticCallInstr* call = array->AsStaticCall()) {
       if (call->is_known_list_constructor()) {
         return call->ArgumentAt(0);
-      } else if (call->function().recognized_kind() ==
-                 MethodRecognizer::kLinkedHashMap_getData) {
+      } else if (IsTypedDataViewFactory(call->function())) {
         return flow_graph->constant_null();
       }
+      switch (call->function().recognized_kind()) {
+        case MethodRecognizer::kByteDataFactory:
+        case MethodRecognizer::kLinkedHashMap_getData:
+          return flow_graph->constant_null();
+        default:
+          break;
+      }
     } else if (CreateArrayInstr* create_array = array->AsCreateArray()) {
       return create_array->element_type()->definition();
     } else if (LoadFieldInstr* load_array = array->AsLoadField()) {
@@ -3573,6 +3589,11 @@
   if (call->is_known_list_constructor() &&
       LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) {
     length = call->ArgumentAt(1)->AsConstant();
+  } else if (call->function().recognized_kind() ==
+             MethodRecognizer::kByteDataFactory) {
+    length = call->ArgumentAt(1)->AsConstant();
+  } else if (LoadFieldInstr::IsTypedDataViewFactory(call->function())) {
+    length = call->ArgumentAt(3)->AsConstant();
   }
   if ((length != NULL) && length->value().IsSmi() &&
       Smi::Cast(length->value()).Value() == expected_length) {
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 6fc48f4..ffd7255 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -42,6 +42,7 @@
   V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
   V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
   V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
+  V(ByteData, ., ByteDataFactory, 0x0)                                         \
   V(_ByteDataView, get:offsetInBytes, ByteDataViewOffsetInBytes, 0x0)          \
   V(_ByteDataView, get:_typedData, ByteDataViewTypedData, 0x0)                 \
   V(_TypedListView, get:offsetInBytes, TypedDataViewOffsetInBytes, 0x0)        \