[vm/compiler] Fixed bug with clamping on 32-bit arch

Rationale:
Feel the power of value-guided fuzzing that, in combination
with new types, founds this issue in the graph intrinsifier.
The deopt on the speculative code for Smi was missing.

https://github.com/dart-lang/sdk/issues/37868

Change-Id: I9f310f62eb6cf1cdb3e39685caed5b7792024565
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/113203
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Aart Bik <ajcbik@google.com>
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index db4e7dc..d251b3e 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -285,6 +285,8 @@
     case kTypedDataUint16ArrayCid:
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
+      builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone,
+                                               builder.TokenPos()));
       value = builder.AddUnboxInstr(kUnboxedIntPtr, new Value(value),
                                     /* is_checked = */ false);
       value->AsUnboxInteger()->mark_truncating();
diff --git a/tests/language_2/vm/clamp_37868_test.dart b/tests/language_2/vm/clamp_37868_test.dart
new file mode 100755
index 0000000..181f895
--- /dev/null
+++ b/tests/language_2/vm/clamp_37868_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, 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.
+
+// VMOptions=--deterministic
+
+import "package:expect/expect.dart";
+
+import 'dart:typed_data';
+
+// Found by "value-guided" DartFuzzing: incorrect clamping.
+// https://github.com/dart-lang/sdk/issues/37868
+@pragma("vm:never-inline")
+foo(List<int> x) => Uint8ClampedList.fromList(x);
+
+main() {
+  var x = [
+    9223372036854775807,
+    -9223372036854775808,
+    9223372032559808513,
+    -9223372032559808513,
+    5000000000,
+    -5000000000,
+    2147483647,
+    -2147483648,
+    255,
+    -255,
+  ];
+  var y = foo(x);
+  for (int i = 0; i < y.length; i += 2) {
+    Expect.equals(255, y[i]);
+    Expect.equals(0, y[i + 1]);
+  }
+}