Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/cctest/compiler/c-signature.h b/test/cctest/compiler/c-signature.h
index 13ef38a..1c2f963 100644
--- a/test/cctest/compiler/c-signature.h
+++ b/test/cctest/compiler/c-signature.h
@@ -53,16 +53,16 @@
  public:
   template <typename P1 = void, typename P2 = void, typename P3 = void,
             typename P4 = void, typename P5 = void>
-  void VerifyParams() {
+  static void VerifyParams(MachineSignature* sig) {
     // Verifies the C signature against the machine types. Maximum {5} params.
-    CHECK_LT(parameter_count(), 6u);
+    CHECK_LT(sig->parameter_count(), 6u);
     const int kMax = 5;
     MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
                             MachineTypeForC<P3>(), MachineTypeForC<P4>(),
                             MachineTypeForC<P5>()};
     for (int p = kMax - 1; p >= 0; p--) {
-      if (p < static_cast<int>(parameter_count())) {
-        CHECK_EQ(GetParam(p), params[p]);
+      if (p < static_cast<int>(sig->parameter_count())) {
+        CHECK_EQ(sig->GetParam(p), params[p]);
       } else {
         CHECK_EQ(MachineType::None(), params[p]);
       }
diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h
index e60f717..8ee6b99 100644
--- a/test/cctest/compiler/call-tester.h
+++ b/test/cctest/compiler/call-tester.h
@@ -119,7 +119,7 @@
 template <typename R>
 class CallHelper {
  public:
-  explicit CallHelper(Isolate* isolate, CSignature* csig)
+  explicit CallHelper(Isolate* isolate, MachineSignature* csig)
       : csig_(csig), isolate_(isolate) {
     USE(isolate_);
   }
@@ -127,47 +127,47 @@
 
   R Call() {
     typedef R V8_CDECL FType();
-    csig_->VerifyParams();
+    CSignature::VerifyParams(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()));
   }
 
   template <typename P1>
   R Call(P1 p1) {
     typedef R V8_CDECL FType(P1);
-    csig_->VerifyParams<P1>();
+    CSignature::VerifyParams<P1>(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()), p1);
   }
 
   template <typename P1, typename P2>
   R Call(P1 p1, P2 p2) {
     typedef R V8_CDECL FType(P1, P2);
-    csig_->VerifyParams<P1, P2>();
+    CSignature::VerifyParams<P1, P2>(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2);
   }
 
   template <typename P1, typename P2, typename P3>
   R Call(P1 p1, P2 p2, P3 p3) {
     typedef R V8_CDECL FType(P1, P2, P3);
-    csig_->VerifyParams<P1, P2, P3>();
+    CSignature::VerifyParams<P1, P2, P3>(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
   }
 
   template <typename P1, typename P2, typename P3, typename P4>
   R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
     typedef R V8_CDECL FType(P1, P2, P3, P4);
-    csig_->VerifyParams<P1, P2, P3, P4>();
+    CSignature::VerifyParams<P1, P2, P3, P4>(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
   }
 
   template <typename P1, typename P2, typename P3, typename P4, typename P5>
   R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
     typedef R V8_CDECL FType(P1, P2, P3, P4, P5);
-    csig_->VerifyParams<P1, P2, P3, P4, P5>();
+    CSignature::VerifyParams<P1, P2, P3, P4, P5>(csig_);
     return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4, p5);
   }
 
  protected:
-  CSignature* csig_;
+  MachineSignature* csig_;
 
   virtual byte* Generate() = 0;
 
@@ -342,7 +342,7 @@
 template <typename T>
 class CodeRunner : public CallHelper<T> {
  public:
-  CodeRunner(Isolate* isolate, Handle<Code> code, CSignature* csig)
+  CodeRunner(Isolate* isolate, Handle<Code> code, MachineSignature* csig)
       : CallHelper<T>(isolate, csig), code_(code) {}
   virtual ~CodeRunner() {}
 
diff --git a/test/cctest/compiler/codegen-tester.h b/test/cctest/compiler/codegen-tester.h
index 56e90c6..5d670bf 100644
--- a/test/cctest/compiler/codegen-tester.h
+++ b/test/cctest/compiler/codegen-tester.h
@@ -35,10 +35,13 @@
             Linkage::GetSimplifiedCDescriptor(
                 main_zone(),
                 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
-                                p1, p2, p3, p4)),
+                                p1, p2, p3, p4),
+                true),
             MachineType::PointerRepresentation(),
             InstructionSelector::SupportedMachineOperatorFlags()) {}
 
+  virtual ~RawMachineAssemblerTester() {}
+
   void CheckNumber(double expected, Object* number) {
     CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
   }
@@ -85,6 +88,7 @@
       : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
                                           p0, p1, p2, p3) {}
 
+  virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
 
   // The BufferedRawMachineAssemblerTester does not pass parameters directly
   // to the constructed IR graph. Instead it passes a pointer to the parameter
@@ -92,11 +96,10 @@
   // parameters from memory. Thereby it is possible to pass 64 bit parameters
   // to the IR graph.
   Node* Parameter(size_t index) {
-    CHECK(index >= 0 && index < 4);
+    CHECK(index < 4);
     return parameter_nodes_[index];
   }
 
-
   // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
   // to store the graph's return value in memory. The memory address for the
   // Store node is provided as a parameter. By storing the return value in
@@ -110,7 +113,7 @@
 
   ReturnType Call() {
     ReturnType return_value;
-    test_graph_signature_->VerifyParams();
+    CSignature::VerifyParams(test_graph_signature_);
     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
     return return_value;
   }
@@ -118,7 +121,7 @@
   template <typename P0>
   ReturnType Call(P0 p0) {
     ReturnType return_value;
-    test_graph_signature_->VerifyParams<P0>();
+    CSignature::VerifyParams<P0>(test_graph_signature_);
     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
                               reinterpret_cast<void*>(&return_value));
     return return_value;
@@ -127,7 +130,7 @@
   template <typename P0, typename P1>
   ReturnType Call(P0 p0, P1 p1) {
     ReturnType return_value;
-    test_graph_signature_->VerifyParams<P0, P1>();
+    CSignature::VerifyParams<P0, P1>(test_graph_signature_);
     CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
                               reinterpret_cast<void*>(&p1),
                               reinterpret_cast<void*>(&return_value));
@@ -137,7 +140,7 @@
   template <typename P0, typename P1, typename P2>
   ReturnType Call(P0 p0, P1 p1, P2 p2) {
     ReturnType return_value;
-    test_graph_signature_->VerifyParams<P0, P1, P2>();
+    CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
     CallHelper<int32_t>::Call(
         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
@@ -147,7 +150,7 @@
   template <typename P0, typename P1, typename P2, typename P3>
   ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
     ReturnType return_value;
-    test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+    CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
     CallHelper<int32_t>::Call(
         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
@@ -245,6 +248,7 @@
                               : Load(p3, RawMachineAssembler::Parameter(3));
   }
 
+  virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
 
   // The BufferedRawMachineAssemblerTester does not pass parameters directly
   // to the constructed IR graph. Instead it passes a pointer to the parameter
@@ -258,26 +262,26 @@
 
 
   void Call() {
-    test_graph_signature_->VerifyParams();
+    CSignature::VerifyParams(test_graph_signature_);
     CallHelper<void>::Call();
   }
 
   template <typename P0>
   void Call(P0 p0) {
-    test_graph_signature_->VerifyParams<P0>();
+    CSignature::VerifyParams<P0>(test_graph_signature_);
     CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
   }
 
   template <typename P0, typename P1>
   void Call(P0 p0, P1 p1) {
-    test_graph_signature_->VerifyParams<P0, P1>();
+    CSignature::VerifyParams<P0, P1>(test_graph_signature_);
     CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
                            reinterpret_cast<void*>(&p1));
   }
 
   template <typename P0, typename P1, typename P2>
   void Call(P0 p0, P1 p1, P2 p2) {
-    test_graph_signature_->VerifyParams<P0, P1, P2>();
+    CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
     CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
                            reinterpret_cast<void*>(&p1),
                            reinterpret_cast<void*>(&p2));
@@ -285,7 +289,7 @@
 
   template <typename P0, typename P1, typename P2, typename P3>
   void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
-    test_graph_signature_->VerifyParams<P0, P1, P2, P3>();
+    CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
     CallHelper<void>::Call(
         reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
         reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
@@ -397,7 +401,6 @@
 
 // A helper class for testing code sequences that take two float parameters and
 // return a float value.
-// TODO(titzer): figure out how to return floats correctly on ia32.
 class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
  public:
   explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
@@ -407,7 +410,6 @@
 
 // A helper class for testing code sequences that take two double parameters and
 // return a double value.
-// TODO(titzer): figure out how to return doubles correctly on ia32.
 class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
  public:
   explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
@@ -524,7 +526,8 @@
 // and run the generated code to ensure it produces the correct results.
 class Int32BinopInputShapeTester {
  public:
-  explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) : gen(g) {}
+  explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g)
+      : gen(g), input_a(0), input_b(0) {}
 
   void TestAllInputShapes();
 
@@ -537,24 +540,6 @@
   void RunLeft(RawMachineAssemblerTester<int32_t>* m);
   void RunRight(RawMachineAssemblerTester<int32_t>* m);
 };
-
-// TODO(bmeurer): Drop this crap once we switch to GTest/Gmock.
-static inline void CheckFloatEq(volatile float x, volatile float y) {
-  if (std::isnan(x)) {
-    CHECK(std::isnan(y));
-  } else {
-    CHECK_EQ(x, y);
-  }
-}
-
-static inline void CheckDoubleEq(volatile double x, volatile double y) {
-  if (std::isnan(x)) {
-    CHECK(std::isnan(y));
-  } else {
-    CHECK_EQ(x, y);
-  }
-}
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/function-tester.h b/test/cctest/compiler/function-tester.h
index 2fcd353..c6093ce 100644
--- a/test/cctest/compiler/function-tester.h
+++ b/test/cctest/compiler/function-tester.h
@@ -162,15 +162,26 @@
 
   Handle<Object> false_value() { return isolate->factory()->false_value(); }
 
+  static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) {
+    JSFunction* p = NULL;
+    {  // because of the implicit handle scope of FunctionTester.
+      FunctionTester f(graph, param_count);
+      p = *f.function;
+    }
+    return Handle<JSFunction>(p);  // allocated in outer handle scope.
+  }
+
+ private:
+  uint32_t flags_;
+
   Handle<JSFunction> Compile(Handle<JSFunction> function) {
-// TODO(titzer): make this method private.
     Zone zone;
     ParseInfo parse_info(&zone, function);
     CompilationInfo info(&parse_info);
     info.MarkAsDeoptimizationEnabled();
 
     CHECK(Parser::ParseStatic(info.parse_info()));
-    info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+    info.SetOptimizing();
     if (flags_ & CompilationInfo::kFunctionContextSpecializing) {
       info.MarkAsFunctionContextSpecializing();
     }
@@ -192,26 +203,13 @@
     return function;
   }
 
-  static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) {
-    JSFunction* p = NULL;
-    {  // because of the implicit handle scope of FunctionTester.
-      FunctionTester f(graph, param_count);
-      p = *f.function;
-    }
-    return Handle<JSFunction>(p);  // allocated in outer handle scope.
-  }
-
- private:
-  uint32_t flags_;
-
   std::string BuildFunction(int param_count) {
     std::string function_string = "(function(";
     if (param_count > 0) {
-      char next = 'a';
-      function_string += next;
-      while (param_count-- > 0) {
+      function_string += 'a';
+      for (int i = 1; i < param_count; i++) {
         function_string += ',';
-        function_string += ++next;
+        function_string += static_cast<char>('a' + i);
       }
     }
     function_string += "){})";
@@ -231,8 +229,7 @@
     CompilationInfo info(&parse_info);
 
     CHECK(Parser::ParseStatic(info.parse_info()));
-    info.SetOptimizing(BailoutId::None(),
-                       Handle<Code>(function->shared()->code()));
+    info.SetOptimizing();
     CHECK(Compiler::Analyze(info.parse_info()));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
diff --git a/test/cctest/compiler/test-code-stub-assembler.cc b/test/cctest/compiler/test-code-stub-assembler.cc
index d7a7a81..0306561 100644
--- a/test/cctest/compiler/test-code-stub-assembler.cc
+++ b/test/cctest/compiler/test-code-stub-assembler.cc
@@ -16,7 +16,7 @@
   CodeStubAssemblerTester(Isolate* isolate,
                           const CallInterfaceDescriptor& descriptor)
       : CodeStubAssembler(isolate, isolate->runtime_zone(), descriptor,
-                          Code::STUB, "test"),
+                          Code::ComputeFlags(Code::STUB), "test"),
         scope_(isolate) {}
 
  private:
@@ -120,6 +120,133 @@
   CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value());
 }
 
+TEST(VariableMerge1) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+  Node* temp = m.Int32Constant(0);
+  var1.Bind(temp);
+  m.Branch(m.Int32Constant(1), &l1, &l2);
+  m.Bind(&l1);
+  CHECK_EQ(var1.value(), temp);
+  m.Goto(&merge);
+  m.Bind(&l2);
+  CHECK_EQ(var1.value(), temp);
+  m.Goto(&merge);
+  m.Bind(&merge);
+  CHECK_EQ(var1.value(), temp);
+}
+
+TEST(VariableMerge2) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+  Node* temp = m.Int32Constant(0);
+  var1.Bind(temp);
+  m.Branch(m.Int32Constant(1), &l1, &l2);
+  m.Bind(&l1);
+  CHECK_EQ(var1.value(), temp);
+  m.Goto(&merge);
+  m.Bind(&l2);
+  Node* temp2 = m.Int32Constant(2);
+  var1.Bind(temp2);
+  CHECK_EQ(var1.value(), temp2);
+  m.Goto(&merge);
+  m.Bind(&merge);
+  CHECK_NE(var1.value(), temp);
+}
+
+TEST(VariableMerge3) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Variable var2(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+  Node* temp = m.Int32Constant(0);
+  var1.Bind(temp);
+  var2.Bind(temp);
+  m.Branch(m.Int32Constant(1), &l1, &l2);
+  m.Bind(&l1);
+  CHECK_EQ(var1.value(), temp);
+  m.Goto(&merge);
+  m.Bind(&l2);
+  Node* temp2 = m.Int32Constant(2);
+  var1.Bind(temp2);
+  CHECK_EQ(var1.value(), temp2);
+  m.Goto(&merge);
+  m.Bind(&merge);
+  CHECK_NE(var1.value(), temp);
+  CHECK_NE(var1.value(), temp2);
+  CHECK_EQ(var2.value(), temp);
+}
+
+TEST(VariableMergeBindFirst) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Label l1(&m), l2(&m), merge(&m, &var1), end(&m);
+  Node* temp = m.Int32Constant(0);
+  var1.Bind(temp);
+  m.Branch(m.Int32Constant(1), &l1, &l2);
+  m.Bind(&l1);
+  CHECK_EQ(var1.value(), temp);
+  m.Goto(&merge);
+  m.Bind(&merge);
+  CHECK(var1.value() != temp);
+  CHECK(var1.value() != nullptr);
+  m.Goto(&end);
+  m.Bind(&l2);
+  Node* temp2 = m.Int32Constant(2);
+  var1.Bind(temp2);
+  CHECK_EQ(var1.value(), temp2);
+  m.Goto(&merge);
+  m.Bind(&end);
+  CHECK(var1.value() != temp);
+  CHECK(var1.value() != nullptr);
+}
+
+TEST(VariableMergeSwitch) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
+  CodeStubAssembler::Label l1(&m), l2(&m), default_label(&m);
+  CodeStubAssembler::Label* labels[] = {&l1, &l2};
+  int32_t values[] = {1, 2};
+  Node* temp = m.Int32Constant(0);
+  var1.Bind(temp);
+  m.Switch(m.Int32Constant(2), &default_label, values, labels, 2);
+  m.Bind(&l1);
+  DCHECK_EQ(temp, var1.value());
+  m.Return(temp);
+  m.Bind(&l2);
+  DCHECK_EQ(temp, var1.value());
+  m.Return(temp);
+  m.Bind(&default_label);
+  DCHECK_EQ(temp, var1.value());
+  m.Return(temp);
+}
+
+TEST(FixedArrayAccessSmiIndex) {
+  Isolate* isolate(CcTest::InitIsolateOnce());
+  VoidDescriptor descriptor(isolate);
+  CodeStubAssemblerTester m(isolate, descriptor);
+  Handle<FixedArray> array = isolate->factory()->NewFixedArray(5);
+  array->set(4, Smi::FromInt(733));
+  m.Return(m.LoadFixedArrayElementSmiIndex(m.HeapConstant(array),
+                                           m.SmiTag(m.Int32Constant(4))));
+  Handle<Code> code = m.GenerateCode();
+  FunctionTester ft(descriptor, code);
+  MaybeHandle<Object> result = ft.Call();
+  CHECK_EQ(733, Handle<Smi>::cast(result.ToHandleChecked())->value());
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/test-js-context-specialization.cc b/test/cctest/compiler/test-js-context-specialization.cc
index 43b7665..c7cd47a 100644
--- a/test/cctest/compiler/test-js-context-specialization.cc
+++ b/test/cctest/compiler/test-js-context-specialization.cc
@@ -225,8 +225,8 @@
         t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load);
 
     Node* add = t.graph()->NewNode(
-        t.javascript()->Add(LanguageMode::SLOPPY, BinaryOperationHints::Any()),
-        value_use, other_use, param_context, t.jsgraph()->EmptyFrameState(),
+        t.javascript()->Add(BinaryOperationHints::Any()), value_use, other_use,
+        param_context, t.jsgraph()->EmptyFrameState(),
         t.jsgraph()->EmptyFrameState(), other_load, start);
 
     Node* ret =
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc
index c8b7734..24db6a5 100644
--- a/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/test/cctest/compiler/test-js-typed-lowering.cc
@@ -17,19 +17,6 @@
 namespace internal {
 namespace compiler {
 
-#ifndef TEST_WITH_STRONG
-#define TEST_WITH_STRONG(Name)                                                 \
-  static void Test##Name();                                                    \
-  static void TestWithStrong##Name(LanguageMode language_mode);                \
-  CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true);  \
-  static void Test##Name() {                                                   \
-    TestWithStrong##Name(LanguageMode::SLOPPY);                                \
-    TestWithStrong##Name(LanguageMode::STRONG);                                \
-  }                                                                            \
-  static void TestWithStrong##Name(LanguageMode language_mode)
-#endif
-
-
 class JSTypedLoweringTester : public HandleAndZoneScope {
  public:
   explicit JSTypedLoweringTester(int num_parameters = 0)
@@ -163,17 +150,8 @@
   }
 
   Node* UseForEffect(Node* node) {
-    // TODO(titzer): use EffectPhi after fixing EffectCount
-    if (OperatorProperties::GetFrameStateInputCount(javascript.ToNumber()) >
-        0) {
-      CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(
-                      javascript.ToNumber()));
-      return graph.NewNode(javascript.ToNumber(), node, context(),
-                           EmptyFrameState(context()), node, control());
-    } else {
-      return graph.NewNode(javascript.ToNumber(), node, context(), node,
-                           control());
-    }
+    Node* merge = graph.NewNode(common.Merge(1), start());
+    return graph.NewNode(common.EffectPhi(1), node, merge);
   }
 
   void CheckEffectInput(Node* effect, Node* use) {
@@ -240,7 +218,7 @@
 
 // TODO(turbofan): Lowering of StringAdd is disabled for now.
 #if 0
-TEST_WITH_STRONG(StringBinops) {
+TEST(StringBinops) {
   JSTypedLoweringTester R;
 
   for (size_t i = 0; i < arraysize(kStringTypes); ++i) {
@@ -249,7 +227,7 @@
     for (size_t j = 0; j < arraysize(kStringTypes); ++j) {
       Node* p1 = R.Parameter(kStringTypes[j], 1);
 
-      Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1);
+      Node* add = R.Binop(R.javascript.Add(), p0, p1);
       Node* r = R.reduce(add);
 
       R.CheckBinop(IrOpcode::kStringAdd, r);
@@ -260,14 +238,12 @@
 }
 #endif
 
-
-TEST_WITH_STRONG(AddNumber1) {
+TEST(AddNumber1) {
   JSTypedLoweringTester R;
   for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
     Node* p0 = R.Parameter(kNumberTypes[i], 0);
     Node* p1 = R.Parameter(kNumberTypes[i], 1);
-    Node* add = R.Binop(
-        R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1);
+    Node* add = R.Binop(R.javascript.Add(BinaryOperationHints::Any()), p0, p1);
     Node* r = R.reduce(add);
 
     R.CheckBinop(IrOpcode::kNumberAdd, r);
@@ -276,20 +252,14 @@
   }
 }
 
-
-TEST_WITH_STRONG(NumberBinops) {
+TEST(NumberBinops) {
   JSTypedLoweringTester R;
   const Operator* ops[] = {
-      R.javascript.Add(language_mode, R.hints),
-      R.simplified.NumberAdd(),
-      R.javascript.Subtract(language_mode, R.hints),
-      R.simplified.NumberSubtract(),
-      R.javascript.Multiply(language_mode, R.hints),
-      R.simplified.NumberMultiply(),
-      R.javascript.Divide(language_mode, R.hints),
-      R.simplified.NumberDivide(),
-      R.javascript.Modulus(language_mode, R.hints),
-      R.simplified.NumberModulus(),
+      R.javascript.Add(R.hints),      R.simplified.NumberAdd(),
+      R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+      R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+      R.javascript.Divide(R.hints),   R.simplified.NumberDivide(),
+      R.javascript.Modulus(R.hints),  R.simplified.NumberModulus(),
   };
 
   for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
@@ -329,14 +299,13 @@
 // A helper class for testing lowering of bitwise shift operators.
 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
  public:
-  explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode)
-      : JSTypedLoweringTester(), language_mode_(language_mode) {
+  JSBitwiseShiftTypedLoweringTester() : JSTypedLoweringTester() {
     int i = 0;
-    set(i++, javascript.ShiftLeft(language_mode_, hints), true);
+    set(i++, javascript.ShiftLeft(hints), true);
     set(i++, simplified.NumberShiftLeft(), false);
-    set(i++, javascript.ShiftRight(language_mode_, hints), true);
+    set(i++, javascript.ShiftRight(hints), true);
     set(i++, simplified.NumberShiftRight(), false);
-    set(i++, javascript.ShiftRightLogical(language_mode_, hints), false);
+    set(i++, javascript.ShiftRightLogical(hints), false);
     set(i++, simplified.NumberShiftRightLogical(), false);
   }
   static const int kNumberOps = 6;
@@ -344,7 +313,6 @@
   bool signedness[kNumberOps];
 
  private:
-  LanguageMode language_mode_;
   void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
@@ -353,7 +321,7 @@
 
 
 TEST(Int32BitwiseShifts) {
-  JSBitwiseShiftTypedLoweringTester R(LanguageMode::SLOPPY);
+  JSBitwiseShiftTypedLoweringTester R;
 
   Type* types[] = {
       Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(),
@@ -387,14 +355,13 @@
 // A helper class for testing lowering of bitwise operators.
 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
  public:
-  explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode)
-      : JSTypedLoweringTester(), language_mode_(language_mode) {
+  JSBitwiseTypedLoweringTester() : JSTypedLoweringTester() {
     int i = 0;
-    set(i++, javascript.BitwiseOr(language_mode_, hints), true);
+    set(i++, javascript.BitwiseOr(hints), true);
     set(i++, simplified.NumberBitwiseOr(), true);
-    set(i++, javascript.BitwiseXor(language_mode_, hints), true);
+    set(i++, javascript.BitwiseXor(hints), true);
     set(i++, simplified.NumberBitwiseXor(), true);
-    set(i++, javascript.BitwiseAnd(language_mode_, hints), true);
+    set(i++, javascript.BitwiseAnd(hints), true);
     set(i++, simplified.NumberBitwiseAnd(), true);
   }
   static const int kNumberOps = 6;
@@ -402,7 +369,6 @@
   bool signedness[kNumberOps];
 
  private:
-  LanguageMode language_mode_;
   void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
@@ -411,7 +377,7 @@
 
 
 TEST(Int32BitwiseBinops) {
-  JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
+  JSBitwiseTypedLoweringTester R;
 
   Type* types[] = {
       Type::SignedSmall(),   Type::UnsignedSmall(), Type::Unsigned32(),
@@ -558,7 +524,6 @@
 
   {  // ToString(number)
     Node* r = R.ReduceUnop(op, Type::Number());
-    // TODO(titzer): could remove effects
     CHECK_EQ(IrOpcode::kJSToString, r->opcode());
   }
 
@@ -602,17 +567,14 @@
   }
 }
 
-
-TEST_WITH_STRONG(StringComparison) {
+TEST(StringComparison) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.LessThan(language_mode), R.simplified.StringLessThan(),
-      R.javascript.LessThanOrEqual(language_mode),
-      R.simplified.StringLessThanOrEqual(),
-      R.javascript.GreaterThan(language_mode), R.simplified.StringLessThan(),
-      R.javascript.GreaterThanOrEqual(language_mode),
-      R.simplified.StringLessThanOrEqual()};
+      R.javascript.LessThan(),           R.simplified.StringLessThan(),
+      R.javascript.LessThanOrEqual(),    R.simplified.StringLessThanOrEqual(),
+      R.javascript.GreaterThan(),        R.simplified.StringLessThan(),
+      R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
 
   for (size_t i = 0; i < arraysize(kStringTypes); i++) {
     Node* p0 = R.Parameter(kStringTypes[i], 0);
@@ -652,17 +614,14 @@
   }
 }
 
-
-TEST_WITH_STRONG(NumberComparison) {
+TEST(NumberComparison) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(),
-      R.javascript.LessThanOrEqual(language_mode),
-      R.simplified.NumberLessThanOrEqual(),
-      R.javascript.GreaterThan(language_mode), R.simplified.NumberLessThan(),
-      R.javascript.GreaterThanOrEqual(language_mode),
-      R.simplified.NumberLessThanOrEqual()};
+      R.javascript.LessThan(),           R.simplified.NumberLessThan(),
+      R.javascript.LessThanOrEqual(),    R.simplified.NumberLessThanOrEqual(),
+      R.javascript.GreaterThan(),        R.simplified.NumberLessThan(),
+      R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
 
   Node* const p0 = R.Parameter(Type::Number(), 0);
   Node* const p1 = R.Parameter(Type::Number(), 1);
@@ -684,8 +643,7 @@
   }
 }
 
-
-TEST_WITH_STRONG(MixedComparison1) {
+TEST(MixedComparison1) {
   JSTypedLoweringTester R;
 
   Type* types[] = {Type::Number(), Type::String(),
@@ -697,16 +655,15 @@
     for (size_t j = 0; j < arraysize(types); j++) {
       Node* p1 = R.Parameter(types[j], 1);
       {
-        const Operator* less_than = R.javascript.LessThan(language_mode);
+        const Operator* less_than = R.javascript.LessThan();
         Node* cmp = R.Binop(less_than, p0, p1);
         Node* r = R.reduce(cmp);
         if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
           R.CheckBinop(R.simplified.StringLessThan(), r);
         } else if ((types[i]->Is(Type::Number()) &&
                     types[j]->Is(Type::Number())) ||
-                   (!is_strong(language_mode) &&
-                    (!types[i]->Maybe(Type::String()) ||
-                     !types[j]->Maybe(Type::String())))) {
+                   (!types[i]->Maybe(Type::String()) ||
+                    !types[j]->Maybe(Type::String()))) {
           R.CheckBinop(R.simplified.NumberLessThan(), r);
         } else {
           // No reduction of mixed types.
@@ -717,8 +674,7 @@
   }
 }
 
-
-TEST_WITH_STRONG(RemoveToNumberEffects) {
+TEST(RemoveToNumberEffects) {
   JSTypedLoweringTester R;
 
   Node* effect_use = NULL;
@@ -744,14 +700,14 @@
       case 2:
         effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
       case 3:
-        effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
-                                     ton, ton, R.context(), frame_state,
-                                     frame_state, ton, R.start());
+        effect_use =
+            R.graph.NewNode(R.javascript.Add(R.hints), ton, ton, R.context(),
+                            frame_state, frame_state, ton, R.start());
         break;
       case 4:
-        effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints),
-                                     p0, p0, R.context(), frame_state,
-                                     frame_state, ton, R.start());
+        effect_use =
+            R.graph.NewNode(R.javascript.Add(R.hints), p0, p0, R.context(),
+                            frame_state, frame_state, ton, R.start());
         break;
       case 5:
         effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
@@ -896,9 +852,16 @@
     Node* p1 = R.Parameter(types[i]);
     CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
   }
-  // TODO(titzer): Equal(RefEqualTypes)
 }
 
+TEST(StrictEqualityForUnique) {
+  JSTypedLoweringTester R;
+
+  Node* p0 = R.Parameter(Type::Unique());
+  Node* p1 = R.Parameter(Type::Unique());
+  CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
+  CheckEqualityReduction(&R, true, p1, p0, IrOpcode::kReferenceEqual);
+}
 
 TEST(StringEquality) {
   JSTypedLoweringTester R;
@@ -909,27 +872,18 @@
   CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual);
 }
 
-
-TEST_WITH_STRONG(RemovePureNumberBinopEffects) {
+TEST(RemovePureNumberBinopEffects) {
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Equal(),
-      R.simplified.NumberEqual(),
-      R.javascript.Add(language_mode, R.hints),
-      R.simplified.NumberAdd(),
-      R.javascript.Subtract(language_mode, R.hints),
-      R.simplified.NumberSubtract(),
-      R.javascript.Multiply(language_mode, R.hints),
-      R.simplified.NumberMultiply(),
-      R.javascript.Divide(language_mode, R.hints),
-      R.simplified.NumberDivide(),
-      R.javascript.Modulus(language_mode, R.hints),
-      R.simplified.NumberModulus(),
-      R.javascript.LessThan(language_mode),
-      R.simplified.NumberLessThan(),
-      R.javascript.LessThanOrEqual(language_mode),
-      R.simplified.NumberLessThanOrEqual(),
+      R.javascript.Equal(),           R.simplified.NumberEqual(),
+      R.javascript.Add(R.hints),      R.simplified.NumberAdd(),
+      R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+      R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+      R.javascript.Divide(R.hints),   R.simplified.NumberDivide(),
+      R.javascript.Modulus(R.hints),  R.simplified.NumberModulus(),
+      R.javascript.LessThan(),        R.simplified.NumberLessThan(),
+      R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -950,12 +904,9 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberSubtract(),
-      R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberMultiply(),
-      R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberDivide(),
+      R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+      R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+      R.javascript.Divide(R.hints),   R.simplified.NumberDivide(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -978,14 +929,10 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.Add(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberAdd(),
-      R.javascript.Subtract(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberSubtract(),
-      R.javascript.Multiply(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberMultiply(),
-      R.javascript.Divide(LanguageMode::SLOPPY, R.hints),
-      R.simplified.NumberDivide(),
+      R.javascript.Add(R.hints),      R.simplified.NumberAdd(),
+      R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(),
+      R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(),
+      R.javascript.Divide(R.hints),   R.simplified.NumberDivide(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1020,10 +967,8 @@
   JSTypedLoweringTester R;
 
   const Operator* ops[] = {
-      R.javascript.GreaterThan(LanguageMode::SLOPPY),
-      R.simplified.NumberLessThan(),
-      R.javascript.GreaterThanOrEqual(LanguageMode::SLOPPY),
-      R.simplified.NumberLessThanOrEqual(),
+      R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
+      R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1070,7 +1015,7 @@
 
 
 TEST(Int32BinopEffects) {
-  JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY);
+  JSBitwiseTypedLoweringTester R;
   for (int j = 0; j < R.kNumberOps; j += 2) {
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
     BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right));
@@ -1150,10 +1095,9 @@
   }
 }
 
-
-TEST_WITH_STRONG(Int32AddNarrowing) {
+TEST(Int32AddNarrowing) {
   {
-    JSBitwiseTypedLoweringTester R(language_mode);
+    JSBitwiseTypedLoweringTester R;
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1176,7 +1120,7 @@
     }
   }
   {
-    JSBitwiseShiftTypedLoweringTester R(language_mode);
+    JSBitwiseShiftTypedLoweringTester R;
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       for (size_t i = 0; i < arraysize(kInt32Types); i++) {
@@ -1199,7 +1143,7 @@
     }
   }
   {
-    JSBitwiseTypedLoweringTester R(language_mode);
+    JSBitwiseTypedLoweringTester R;
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
       Node* n0 = R.Parameter(I32Type(R.signedness[o]));
@@ -1222,8 +1166,7 @@
   }
 }
 
-
-TEST_WITH_STRONG(Int32Comparisons) {
+TEST(Int32Comparisons) {
   JSTypedLoweringTester R;
 
   struct Entry {
@@ -1235,17 +1178,16 @@
   };
 
   Entry ops[] = {
-      {R.javascript.LessThan(language_mode), R.machine.Uint32LessThan(),
+      {R.javascript.LessThan(), R.machine.Uint32LessThan(),
        R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false},
-      {R.javascript.LessThanOrEqual(language_mode),
-       R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
-       R.simplified.NumberLessThanOrEqual(), false},
-      {R.javascript.GreaterThan(language_mode), R.machine.Uint32LessThan(),
+      {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+       R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+       false},
+      {R.javascript.GreaterThan(), R.machine.Uint32LessThan(),
        R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true},
-      {R.javascript.GreaterThanOrEqual(language_mode),
-       R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(),
-       R.simplified.NumberLessThanOrEqual(), true}
-  };
+      {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(),
+       R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
+       true}};
 
   for (size_t o = 0; o < arraysize(ops); o++) {
     for (size_t i = 0; i < arraysize(kNumberTypes); i++) {
diff --git a/test/cctest/compiler/test-jump-threading.cc b/test/cctest/compiler/test-jump-threading.cc
index 8c02012..71f774f 100644
--- a/test/cctest/compiler/test-jump-threading.cc
+++ b/test/cctest/compiler/test-jump-threading.cc
@@ -108,7 +108,7 @@
 void VerifyForwarding(TestCode& code, int count, int* expected) {
   Zone local_zone;
   ZoneVector<RpoNumber> result(&local_zone);
-  JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_);
+  JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_, true);
 
   CHECK(count == static_cast<int>(result.size()));
   for (int i = 0; i < count; i++) {
diff --git a/test/cctest/compiler/test-linkage.cc b/test/cctest/compiler/test-linkage.cc
index 939b144..6722f59 100644
--- a/test/cctest/compiler/test-linkage.cc
+++ b/test/cctest/compiler/test-linkage.cc
@@ -71,20 +71,6 @@
 }
 
 
-TEST(TestLinkageCodeStubIncoming) {
-  Isolate* isolate = CcTest::InitIsolateOnce();
-  Zone zone;
-  ToNumberStub stub(isolate);
-  CompilationInfo info(&stub, isolate, &zone);
-  CallDescriptor* descriptor = Linkage::ComputeIncoming(&zone, &info);
-  CHECK(descriptor);
-  CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
-  CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
-  CHECK_EQ(Operator::kNoProperties, descriptor->properties());
-  CHECK_EQ(false, descriptor->IsJSFunctionCall());
-}
-
-
 TEST(TestLinkageJSCall) {
   HandleAndZoneScope handles;
   Handle<JSFunction> function = Compile("a + c");
@@ -109,6 +95,20 @@
 
 
 TEST(TestLinkageStubCall) {
+  Isolate* isolate = CcTest::InitIsolateOnce();
+  Zone zone;
+  ToNumberStub stub(isolate);
+  CompilationInfo info("test", isolate, &zone, Code::ComputeFlags(Code::STUB));
+  CallInterfaceDescriptor interface_descriptor =
+      stub.GetCallInterfaceDescriptor();
+  CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+      isolate, &zone, interface_descriptor, stub.GetStackParameterCount(),
+      CallDescriptor::kNoFlags, Operator::kNoProperties);
+  CHECK(descriptor);
+  CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount()));
+  CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
+  CHECK_EQ(Operator::kNoProperties, descriptor->properties());
+  CHECK_EQ(false, descriptor->IsJSFunctionCall());
   // TODO(titzer): test linkage creation for outgoing stub calls.
 }
 
diff --git a/test/cctest/compiler/test-pipeline.cc b/test/cctest/compiler/test-pipeline.cc
index f4ffd02..35e3427 100644
--- a/test/cctest/compiler/test-pipeline.cc
+++ b/test/cctest/compiler/test-pipeline.cc
@@ -18,7 +18,7 @@
   ParseInfo parse_info(zone, function);
   CHECK(Compiler::ParseAndAnalyze(&parse_info));
   CompilationInfo info(&parse_info);
-  info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+  info.SetOptimizing();
 
   Pipeline pipeline(&info);
   Handle<Code> code = pipeline.GenerateCode();
diff --git a/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
index 88555b7..9a03822 100644
--- a/test/cctest/compiler/test-run-bytecode-graph-builder.cc
+++ b/test/cctest/compiler/test-run-bytecode-graph-builder.cc
@@ -16,6 +16,14 @@
 namespace internal {
 namespace compiler {
 
+#define SHARD_TEST_BY_2(x)    \
+  TEST(x##_0) { Test##x(0); } \
+  TEST(x##_1) { Test##x(1); }
+#define SHARD_TEST_BY_4(x)    \
+  TEST(x##_0) { Test##x(0); } \
+  TEST(x##_1) { Test##x(1); } \
+  TEST(x##_2) { Test##x(2); } \
+  TEST(x##_3) { Test##x(3); }
 
 static const char kFunctionName[] = "f";
 
@@ -70,7 +78,7 @@
     i::FLAG_ignition = true;
     i::FLAG_always_opt = false;
     i::FLAG_allow_natives_syntax = true;
-    i::FLAG_ignition_fallback_on_eval_and_catch = false;
+    i::FLAG_loop_assignment_analysis = false;
     // Set ignition filter flag via SetFlagsFromString to avoid double-free
     // (or potential leak with StrDup() based on ownership confusion).
     ScopedVector<char> ignition_filter(64);
@@ -119,13 +127,13 @@
         Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
     CHECK(function->shared()->HasBytecodeArray());
 
+    // TODO(mstarzinger): We should be able to prime CompilationInfo without
+    // having to instantiate a ParseInfo first. Fix this!
     ParseInfo parse_info(zone_, function);
 
     CompilationInfo compilation_info(&parse_info);
-    compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>());
+    compilation_info.SetOptimizing();
     compilation_info.MarkAsDeoptimizationEnabled();
-    // TODO(mythria): Remove this step once parse_info is not needed.
-    CHECK(Compiler::ParseAndAnalyze(&parse_info));
     compiler::Pipeline pipeline(&compilation_info);
     Handle<Code> code = pipeline.GenerateCode();
     function->ReplaceCode(*code);
@@ -205,8 +213,7 @@
       {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}},
       {"return NaN;", {factory->nan_value()}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -233,8 +240,7 @@
       {"return 25 % 7;", {factory->NewNumberFromInt(4)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -292,8 +298,7 @@
         factory->NewStringFromStaticChars("abc"),
         factory->NewStringFromStaticChars("def")}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1, p2) { %s }\n%s(0, 0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -337,8 +342,7 @@
         BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -394,8 +398,7 @@
         factory->NewNumberFromInt(100)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -409,8 +412,7 @@
   }
 }
 
-
-TEST(BytecodeGraphBuilderNamedStore) {
+void TestBytecodeGraphBuilderNamedStore(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -445,8 +447,8 @@
         BytecodeGraphTester::NewObject("({ name : 'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     ScopedVector<char> script(3072);
     SNPrintF(script, "function %s(p1) { %s };\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -459,8 +461,9 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderNamedStore)
 
-TEST(BytecodeGraphBuilderKeyedStore) {
+void TestBytecodeGraphBuilderKeyedStore(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -503,8 +506,8 @@
         factory->NewNumberFromInt(100)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1, p2) { %s };\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -517,6 +520,7 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderKeyedStore)
 
 TEST(BytecodeGraphBuilderPropertyCall) {
   HandleAndZoneScope scope;
@@ -538,8 +542,7 @@
             "  return a + b + c + d + e + f + g + h;}})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s({func() {}});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -582,8 +585,7 @@
        {factory->NewNumberFromInt(25)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -621,8 +623,7 @@
        {factory->NewNumberFromInt(25)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -649,8 +650,7 @@
         BytecodeGraphTester::NewObject("[1, 2, 3]")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<Handle<Object>>();
     Handle<Object> return_value =
@@ -659,8 +659,7 @@
   }
 }
 
-
-TEST(BytecodeGraphBuilderGlobals) {
+void TestBytecodeGraphBuilderGlobals(size_t shard) {
   HandleAndZoneScope scope;
   Isolate* isolate = scope.main_isolate();
   Zone* zone = scope.main_zone();
@@ -700,8 +699,8 @@
        {factory->NewStringFromStaticChars("number")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    if ((i % 2) != shard) continue;
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -709,6 +708,7 @@
   }
 }
 
+SHARD_TEST_BY_2(BytecodeGraphBuilderGlobals)
 
 TEST(BytecodeGraphBuilderToObject) {
   // TODO(mythria): tests for ToObject. Needs ForIn.
@@ -746,8 +746,7 @@
        {factory->NewNumberFromInt(10)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -778,8 +777,7 @@
        {factory->false_value(), factory->NewStringFromStaticChars("abc")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -816,8 +814,7 @@
         factory->NewStringFromStaticChars("abc")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -871,8 +868,7 @@
        {factory->nan_value(), factory->NewStringFromStaticChars("String")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -911,8 +907,7 @@
         BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -966,8 +961,7 @@
        {factory->true_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName);
 
@@ -1003,8 +997,7 @@
       {"return delete z;", {factory->false_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1045,8 +1038,7 @@
       {"'use strict'; obj.val = 23.456; return obj.val;",
        {factory->NewNumber(23.456)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1089,8 +1081,7 @@
       {"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;",
        {factory->NewNumber(23.456)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(3072);
     SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
              function_epilogue);
@@ -1120,8 +1111,7 @@
        {handle(Smi::FromInt(30), isolate)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1173,8 +1163,7 @@
        {factory->NewStringFromStaticChars("object")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1202,8 +1191,7 @@
        {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1234,8 +1222,7 @@
        {factory->NewStringFromStaticChars("undefined")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
     auto callable = tester.GetCallable<>();
     Handle<Object> return_value = callable().ToHandleChecked();
@@ -1366,8 +1353,7 @@
         factory->NewNumberFromInt(1)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1399,8 +1385,7 @@
        {factory->true_value(), factory->undefined_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1413,6 +1398,98 @@
   }
 }
 
+TEST(BytecodeGraphBuilderTryCatch) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = 1; try { a = 2 } catch(e) { a = 3 }; return a;",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a; try { undef.x } catch(e) { a = 2 }; return a;",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a; try { throw 1 } catch(e) { a = e + 2 }; return a;",
+       {handle(Smi::FromInt(3), isolate)}},
+      {"var a; try { throw 1 } catch(e) { a = e + 2 };"
+       "       try { throw a } catch(e) { a = e + 3 }; return a;",
+       {handle(Smi::FromInt(6), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderTryFinally1) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = 1; try { a = a + 1; } finally { a = a + 2; }; return a;",
+       {handle(Smi::FromInt(4), isolate)}},
+      {"var a = 1; try { a = 2; return 23; } finally { a = 3 }; return a;",
+       {handle(Smi::FromInt(23), isolate)}},
+      {"var a = 1; try { a = 2; throw 23; } finally { return a; };",
+       {handle(Smi::FromInt(2), isolate)}},
+      {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+       "  try { a = 2; break; } finally { a = 3; }"
+       "} return a + i;",
+       {handle(Smi::FromInt(13), isolate)}},
+      {"var a = 1; for (var i = 10; i < 20; i += 5) {"
+       "  try { a = 2; continue; } finally { a = 3; }"
+       "} return a + i;",
+       {handle(Smi::FromInt(23), isolate)}},
+      {"var a = 1; try { a = 2;"
+       "  try { a = 3; throw 23; } finally { a = 4; }"
+       "} catch(e) { a = a + e; } return a;",
+       {handle(Smi::FromInt(27), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderTryFinally2) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0, const char*> snippets[] = {
+      {"var a = 1; try { a = 2; throw 23; } finally { a = 3 }; return a;",
+       {"Uncaught 23"}},
+      {"var a = 1; try { a = 2; throw 23; } finally { throw 42; };",
+       {"Uncaught 42"}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+}
 
 TEST(BytecodeGraphBuilderThrow) {
   HandleAndZoneScope scope;
@@ -1426,15 +1503,14 @@
       {"throw 1;", {"Uncaught 1"}},
       {"throw 'Error';", {"Uncaught Error"}},
       {"throw 'Error1'; throw 'Error2'", {"Uncaught Error1"}},
-      // TODO(mythria): Enable these tests when JumpIfTrue is supported.
-      // {"var a = true; if (a) { throw 'Error'; }", {"Error"}},
+      {"var a = true; if (a) { throw 'Error'; }", {"Uncaught Error"}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
+
     BytecodeGraphTester tester(isolate, zone, script.start());
     v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
     v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value());
@@ -1492,8 +1568,7 @@
        {factory->NewStringFromStaticChars("innermost inner_changed outer")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s", snippets[i].code_snippet);
 
@@ -1558,8 +1633,7 @@
        "f(0);",
        {factory->NewNumberFromInt(24), factory->NewNumberFromInt(4)}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s", snippets[i].code_snippet);
 
@@ -1585,10 +1659,13 @@
        {factory->undefined_value()}},
       {"function f(a) {'use strict'; return arguments[0];}",
        {factory->undefined_value()}},
+      {"function f(...restArgs) {return restArgs[0];}",
+       {factory->undefined_value()}},
+      {"function f(a, ...restArgs) {return restArgs[0];}",
+       {factory->undefined_value()}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
 
@@ -1631,8 +1708,7 @@
         factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(1024);
     SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
 
@@ -1647,6 +1723,48 @@
   }
 }
 
+TEST(BytecodeGraphBuilderCreateRestArguments) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<3> snippets[] = {
+      {"function f(...restArgs) {return restArgs[0];}",
+       {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, ...restArgs) {return restArgs[0];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, b, ...restArgs) {return arguments[2];}",
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, ...restArgs) { return restArgs[2];}",
+       {factory->undefined_value(), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function f(a, ...restArgs) { return arguments[0] + restArgs[1];}",
+       {factory->NewNumberFromInt(4), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {"function inline_func(a, ...restArgs) { return restArgs[0] }"
+       "function f(a, b, c) {return inline_func(b, c) + arguments[0];}",
+       {factory->NewNumberFromInt(31), factory->NewNumberFromInt(1),
+        factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable =
+        tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0), snippets[i].parameter(1),
+                 snippets[i].parameter(2))
+            .ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
 
 TEST(BytecodeGraphBuilderRegExpLiterals) {
   HandleAndZoneScope scope;
@@ -1671,8 +1789,7 @@
        {factory->NewStringFromStaticChars("AbC")}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1712,8 +1829,7 @@
       {"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];",
        {factory->NewStringFromStaticChars("1t")}}};
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1778,8 +1894,7 @@
        {factory->NewNumberFromInt(987)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(4096);
     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1856,10 +1971,38 @@
        "   if (p1 < -10) { return -2; } else { return -1; }\n"
        "}",
        {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}},
+      {"var b = 20, c;"
+       "if (p1 >= 0) {\n"
+       "   if (b > 0) { c = 2; } else { c = 3; }\n"
+       "} else {\n"
+       "   if (b < -10) { c = -2; } else { c = -1; }\n"
+       "}"
+       "return c;",
+       {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-1)}},
+      {"var b = 20, c = 10;"
+       "if (p1 >= 0) {\n"
+       "   if (b < 0) { c = 2; }\n"
+       "} else {\n"
+       "   if (b < -10) { c = -2; } else { c = -1; }\n"
+       "}"
+       "return c;",
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(1)}},
+      {"var x = 2, a = 10, b = 20, c, d;"
+       "x = 0;"
+       "if (a) {\n"
+       "   b = x;"
+       "   if (b > 0) { c = 2; } else { c = 3; }\n"
+       "   x = 4; d = 2;"
+       "} else {\n"
+       "   d = 3;\n"
+       "}"
+       "x = d;"
+       "function f1() {x}"
+       "return x + c;",
+       {factory->NewNumberFromInt(5), factory->NewNumberFromInt(-1)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1890,8 +2033,7 @@
        {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}},
   };
 
-  size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
-  for (size_t i = 0; i < num_snippets; i++) {
+  for (size_t i = 0; i < arraysize(snippets); i++) {
     ScopedVector<char> script(2048);
     SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
              snippets[i].code_snippet, kFunctionName);
@@ -1952,6 +2094,54 @@
   }
 }
 
+TEST(BytecodeGraphBuilderSwitchMerge) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  const char* switch_code =
+      "var x = 10;"
+      "switch (p1) {\n"
+      "  case 1: x = 0;\n"
+      "  case 2: x = 1;\n"
+      "  case 3:\n"
+      "  case 4: x = 2; break;\n"
+      "  case 5: x = 3;\n"
+      "  case 9: break;\n"
+      "  default: x = 4;\n"
+      "}\n"
+      "return x;";
+
+  ExpectedSnippet<1> snippets[] = {
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(2)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}},
+      {switch_code,
+       {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}},
+      {switch_code,
+       {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}},
+      {switch_code,
+       {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}},
+      {switch_code,
+       {factory->NewNumberFromInt(4), factory->NewNumberFromInt(6)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(2048);
+    SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<Handle<Object>>();
+    Handle<Object> return_value =
+        callable(snippets[i].parameter(0)).ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
 
 TEST(BytecodeGraphBuilderNestedSwitch) {
   HandleAndZoneScope scope;
@@ -2294,12 +2484,102 @@
 }
 
 
-TEST(JumpWithConstantsAndWideConstants) {
+TEST(BytecodeGraphBuilderForOf) {
   HandleAndZoneScope scope;
-  auto isolate = scope.main_isolate();
-  const int kStep = 19;
-  int start = 7;
-  for (int constants = start; constants < 256 + 3 * kStep; constants += kStep) {
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  ExpectedSnippet<0> snippets[] = {
+      {"  var r = 0;\n"
+       "  for (var a of [0,6,7,9]) { r += a; }\n"
+       "  return r;\n",
+       {handle(Smi::FromInt(22), isolate)}},
+      {"  var r = '';\n"
+       "  for (var a of 'foobar') { r = a + r; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("raboof")}},
+      {"  var a = [1, 2, 3];\n"
+       "  a.name = 4;\n"
+       "  var r = 0;\n"
+       "  for (var x of a) { r += x; }\n"
+       "  return r;\n",
+       {handle(Smi::FromInt(6), isolate)}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data[0]; r += a; } return r;",
+       {factory->NewStringFromStaticChars("123")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data[2]; r += a; } return r;",
+       {factory->NewStringFromStaticChars("12undefined")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3]; \n"
+       "  for (a of data) { delete data; r += a; } return r;",
+       {factory->NewStringFromStaticChars("123")}},
+      {"  var r = '';\n"
+       "  var input = 'foobar';\n"
+       "  for (var a of input) {\n"
+       "    if (a == 'b') break;\n"
+       "    r += a;\n"
+       "  }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("foo")}},
+      {"  var r = '';\n"
+       "  var input = 'foobar';\n"
+       "  for (var a of input) {\n"
+       "    if (a == 'b') continue;\n"
+       "    r += a;\n"
+       "  }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("fooar")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[2] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("125674")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[4] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("1234567")}},
+      {"  var r = '';\n"
+       "  var data = [1, 2, 3, 4]; \n"
+       "  for (a of data) { data[5] = 567; r += a; }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("1234undefined567")}},
+      {"  var r = '';\n"
+       "  var obj = new Object();\n"
+       "  obj[Symbol.iterator] = function() { return {\n"
+       "    index: 3,\n"
+       "    data: ['a', 'b', 'c', 'd'],"
+       "    next: function() {"
+       "      return {"
+       "        done: this.index == -1,\n"
+       "        value: this.index < 0 ? undefined : this.data[this.index--]\n"
+       "      }\n"
+       "    }\n"
+       "    }}\n"
+       "  for (a of obj) { r += a }\n"
+       "  return r;\n",
+       {factory->NewStringFromStaticChars("dcba")}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+void TestJumpWithConstantsAndWideConstants(size_t shard) {
+  const int kStep = 46;
+  int start = static_cast<int>(7 + 17 * shard);
+  for (int constants = start; constants < 300; constants += kStep) {
     std::stringstream filler_os;
     // Generate a string that consumes constant pool entries and
     // spread out branch distances in script below.
@@ -2321,11 +2601,14 @@
     script_os << "}\n";
     script_os << kFunctionName << "(0);\n";
     std::string script(script_os.str());
+
+    HandleAndZoneScope scope;
+    auto isolate = scope.main_isolate();
     auto factory = isolate->factory();
     auto zone = scope.main_zone();
+    BytecodeGraphTester tester(isolate, zone, script.c_str());
+    auto callable = tester.GetCallable<Handle<Object>>();
     for (int a = 0; a < 3; a++) {
-      BytecodeGraphTester tester(isolate, zone, script.c_str());
-      auto callable = tester.GetCallable<Handle<Object>>();
       Handle<Object> return_val =
           callable(factory->NewNumberFromInt(a)).ToHandleChecked();
       static const int results[] = {11, 12, 2};
@@ -2334,6 +2617,368 @@
   }
 }
 
+SHARD_TEST_BY_4(JumpWithConstantsAndWideConstants)
+
+TEST(BytecodeGraphBuilderDoExpressions) {
+  bool old_flag = FLAG_harmony_do_expressions;
+  FLAG_harmony_do_expressions = true;
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+  ExpectedSnippet<0> snippets[] = {
+      {"var a = do {}; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; }; return a;", {factory->undefined_value()}},
+      {"var a = do { var x = 100; x++; }; return a;",
+       {handle(Smi::FromInt(100), isolate)}},
+      {"var i = 0; for (; i < 5;) { i = do { if (i == 3) { break; }; i + 1; }};"
+       "return i;",
+       {handle(Smi::FromInt(3), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  FLAG_harmony_do_expressions = old_flag;
+}
+
+TEST(BytecodeGraphBuilderWithStatement) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"with({x:42}) return x;", {handle(Smi::FromInt(42), isolate)}},
+      {"with({}) { var y = 10; return y;}",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var y = {x:42};"
+       " function inner() {"
+       "   var x = 20;"
+       "   with(y) return x;"
+       "}"
+       "return inner();",
+       {handle(Smi::FromInt(42), isolate)}},
+      {"var y = {x:42};"
+       " function inner(o) {"
+       "   var x = 20;"
+       "   with(o) return x;"
+       "}"
+       "return inner(y);",
+       {handle(Smi::FromInt(42), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstDeclaration) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = 3; return x;", {handle(Smi::FromInt(3), isolate)}},
+      {"let x = 10; x = x + 20; return x;",
+       {handle(Smi::FromInt(30), isolate)}},
+      {"let x = 10; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+      {"let x; x = 20; return x;", {handle(Smi::FromInt(20), isolate)}},
+      {"let x; return x;", {factory->undefined_value()}},
+      {"var x = 10; { let x = 30; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"let x = 10; { let x = 20; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; eval('let x = 20;'); return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; eval('const x = 20;'); return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; { const x = 20; } return x;",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"var x = 10; { const x = 20; return x;} return -1;",
+       {handle(Smi::FromInt(20), isolate)}},
+      {"var a = 10;\n"
+       "for (var i = 0; i < 10; ++i) {\n"
+       " const x = i;\n"  // const declarations are block scoped.
+       " a = a + x;\n"
+       "}\n"
+       "return a;\n",
+       {handle(Smi::FromInt(55), isolate)}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstDeclarationLookupSlots) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+  Factory* factory = isolate->factory();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = 3; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(3), isolate)}},
+      {"let x = 10; x = x + 20; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(30), isolate)}},
+      {"let x; x = 20; function f1() {return x;}; return x;",
+       {handle(Smi::FromInt(20), isolate)}},
+      {"let x; function f1() {return x;}; return x;",
+       {factory->undefined_value()}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+}
+
+TEST(BytecodeGraphBuilderConstInLookupContextChain) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  const char* prologue =
+      "function OuterMost() {\n"
+      "  const outerConst = 10;\n"
+      "  let outerLet = 20;\n"
+      "  function Outer() {\n"
+      "    function Inner() {\n"
+      "      this.innerFunc = function() { ";
+  const char* epilogue =
+      "      }\n"
+      "    }\n"
+      "    this.getInnerFunc ="
+      "         function() {return new Inner().innerFunc;}\n"
+      "  }\n"
+      "  this.getOuterFunc ="
+      "     function() {return new Outer().getInnerFunc();}"
+      "}\n"
+      "var f = new OuterMost().getOuterFunc();\n"
+      "f();\n";
+
+  // Tests for let / constant.
+  ExpectedSnippet<0> const_decl[] = {
+      {"return outerConst;", {handle(Smi::FromInt(10), isolate)}},
+      {"return outerLet;", {handle(Smi::FromInt(20), isolate)}},
+      {"outerLet = 30; return outerLet;", {handle(Smi::FromInt(30), isolate)}},
+      {"var outerLet = 40; return outerLet;",
+       {handle(Smi::FromInt(40), isolate)}},
+      {"var outerConst = 50; return outerConst;",
+       {handle(Smi::FromInt(50), isolate)}},
+      {"try { outerConst = 30 } catch(e) { return -1; }",
+       {handle(Smi::FromInt(-1), isolate)}}};
+
+  for (size_t i = 0; i < arraysize(const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", prologue, const_decl[i].code_snippet,
+             epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*const_decl[i].return_value()));
+  }
+
+  // Tests for Legacy constant.
+  bool old_flag_legacy_const = FLAG_legacy_const;
+  FLAG_legacy_const = true;
+
+  ExpectedSnippet<0> legacy_const_decl[] = {
+      {"return outerConst = 23;", {handle(Smi::FromInt(23), isolate)}},
+      {"outerConst = 30; return outerConst;",
+       {handle(Smi::FromInt(10), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(legacy_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "%s %s %s", prologue, legacy_const_decl[i].code_snippet,
+             epilogue);
+
+    BytecodeGraphTester tester(isolate, zone, script.start(), "*");
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*legacy_const_decl[i].return_value()));
+  }
+
+  FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderIllegalConstDeclaration) {
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0, const char*> illegal_const_decl[] = {
+      {"const x = x = 10 + 3; return x;",
+       {"Uncaught ReferenceError: x is not defined"}},
+      {"const x = 10; x = 20; return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"const x = 10; { x = 20; } return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"const x = 10; eval('x = 20;'); return x;",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+      {"let x = x + 10; return x;",
+       {"Uncaught ReferenceError: x is not defined"}},
+      {"'use strict'; (function f1() { f1 = 123; })() ",
+       {"Uncaught TypeError: Assignment to constant variable."}},
+  };
+
+  // Tests for sloppy mode.
+  for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             illegal_const_decl[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string =
+        v8_str(illegal_const_decl[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+
+  // Tests for strict mode.
+  for (size_t i = 0; i < arraysize(illegal_const_decl); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() {'use strict'; %s }\n%s();", kFunctionName,
+             illegal_const_decl[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get();
+    v8::Local<v8::String> expected_string =
+        v8_str(illegal_const_decl[i].return_value());
+    CHECK(
+        message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string)
+            .FromJust());
+  }
+}
+
+TEST(BytecodeGraphBuilderLegacyConstDeclaration) {
+  bool old_flag_legacy_const = FLAG_legacy_const;
+  FLAG_legacy_const = true;
+
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippets[] = {
+      {"const x = (x = 10) + 3; return x;",
+       {handle(Smi::FromInt(13), isolate)}},
+      {"const x = 10; x = 20; return x;", {handle(Smi::FromInt(10), isolate)}},
+      {"var a = 10;\n"
+       "for (var i = 0; i < 10; ++i) {\n"
+       " const x = i;\n"  // Legacy constants are not block scoped.
+       " a = a + x;\n"
+       "}\n"
+       "return a;\n",
+       {handle(Smi::FromInt(10), isolate)}},
+      {"const x = 20; eval('x = 10;'); return x;",
+       {handle(Smi::FromInt(20), isolate)}},
+  };
+
+  for (size_t i = 0; i < arraysize(snippets); i++) {
+    ScopedVector<char> script(1024);
+    SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+             snippets[i].code_snippet, kFunctionName);
+
+    BytecodeGraphTester tester(isolate, zone, script.start());
+    auto callable = tester.GetCallable<>();
+    Handle<Object> return_value = callable().ToHandleChecked();
+    CHECK(return_value->SameValue(*snippets[i].return_value()));
+  }
+
+  FLAG_legacy_const = old_flag_legacy_const;
+}
+
+TEST(BytecodeGraphBuilderDebuggerStatement) {
+  FLAG_expose_debug_as = "debug";
+  HandleAndZoneScope scope;
+  Isolate* isolate = scope.main_isolate();
+  Zone* zone = scope.main_zone();
+
+  ExpectedSnippet<0> snippet = {
+      "var Debug = debug.Debug;"
+      "var count = 0;"
+      "function f() {"
+      "  debugger;"
+      "}"
+      "function listener(event) {"
+      "  if (event == Debug.DebugEvent.Break) count++;"
+      "}"
+      "Debug.setListener(listener);"
+      "f();"
+      "Debug.setListener(null);"
+      "return count;",
+      {handle(Smi::FromInt(1), isolate)}};
+
+  ScopedVector<char> script(1024);
+  SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
+           snippet.code_snippet, kFunctionName);
+
+  BytecodeGraphTester tester(isolate, zone, script.start());
+  auto callable = tester.GetCallable<>();
+  Handle<Object> return_value = callable().ToHandleChecked();
+  CHECK(return_value->SameValue(*snippet.return_value()));
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/test-run-deopt.cc b/test/cctest/compiler/test-run-deopt.cc
index 8b4c9dc..76dc9ac 100644
--- a/test/cctest/compiler/test-run-deopt.cc
+++ b/test/cctest/compiler/test-run-deopt.cc
@@ -84,7 +84,6 @@
 
 TEST(DeoptExceptionHandlerFinally) {
   FLAG_allow_natives_syntax = true;
-  FLAG_turbo_try_finally = true;
 
   FunctionTester T(
       "(function f() {"
@@ -98,9 +97,7 @@
 
   CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
   InstallIsOptimizedHelper(CcTest::isolate());
-#if 0  // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
   T.CheckCall(T.false_value());
-#endif
 }
 
 
diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc
index b201711..6e9ebf2 100644
--- a/test/cctest/compiler/test-run-intrinsics.cc
+++ b/test/cctest/compiler/test-run-intrinsics.cc
@@ -104,18 +104,6 @@
 }
 
 
-TEST(IsMinusZero) {
-  FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
-
-  T.CheckFalse(T.Val(1));
-  T.CheckFalse(T.Val(1.1));
-  T.CheckTrue(T.Val(-0.0));
-  T.CheckFalse(T.Val(-2));
-  T.CheckFalse(T.Val(-2.3));
-  T.CheckFalse(T.undefined());
-}
-
-
 TEST(IsRegExp) {
   FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
 
@@ -148,19 +136,6 @@
 }
 
 
-TEST(ObjectEquals) {
-  FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
-  CompileRun("var o = {}");
-
-  T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
-  T.CheckTrue(T.Val("internal"), T.Val("internal"));
-  T.CheckTrue(T.true_value(), T.true_value());
-  T.CheckFalse(T.true_value(), T.false_value());
-  T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
-  T.CheckFalse(T.Val("a"), T.Val("b"));
-}
-
-
 TEST(OneByteSeqStringGetChar) {
   FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
                    flags);
@@ -192,15 +167,6 @@
 }
 
 
-TEST(SetValueOf) {
-  FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
-
-  T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
-  T.CheckCall(T.Val(123), T.NewObject("(new Number)"), T.Val(123));
-  T.CheckCall(T.Val("x"), T.undefined(), T.Val("x"));
-}
-
-
 TEST(StringAdd) {
   FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
 
diff --git a/test/cctest/compiler/test-run-jscalls.cc b/test/cctest/compiler/test-run-jscalls.cc
index 474453d..c282958 100644
--- a/test/cctest/compiler/test-run-jscalls.cc
+++ b/test/cctest/compiler/test-run-jscalls.cc
@@ -21,37 +21,36 @@
 
 TEST(SimpleCall2) {
   FunctionTester T("(function(foo,a) { return foo(a); })");
-  Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
-  T.Compile(foo);
+  FunctionTester U("(function(a) { return a; })");
 
-  T.CheckCall(T.Val(3), foo, T.Val(3));
-  T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
-  T.CheckCall(foo, foo, foo);
-  T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
+  T.CheckCall(T.Val(3), U.function, T.Val(3));
+  T.CheckCall(T.Val(3.1), U.function, T.Val(3.1));
+  T.CheckCall(U.function, U.function, U.function);
+  T.CheckCall(T.Val("Abba"), U.function, T.Val("Abba"));
 }
 
 
 TEST(ConstCall) {
   FunctionTester T("(function(foo,a) { return foo(a,3); })");
-  Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
-  T.Compile(foo);
+  FunctionTester U("(function(a,b) { return a + b; })");
 
-  T.CheckCall(T.Val(6), foo, T.Val(3));
-  T.CheckCall(T.Val(6.1), foo, T.Val(3.1));
-  T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
-  T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+  T.CheckCall(T.Val(6), U.function, T.Val(3));
+  T.CheckCall(T.Val(6.1), U.function, T.Val(3.1));
+  T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
+              U.function);
+  T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
 }
 
 
 TEST(ConstCall2) {
   FunctionTester T("(function(foo,a) { return foo(a,\"3\"); })");
-  Handle<JSFunction> foo = T.NewFunction("(function(a,b) { return a + b; })");
-  T.Compile(foo);
+  FunctionTester U("(function(a,b) { return a + b; })");
 
-  T.CheckCall(T.Val("33"), foo, T.Val(3));
-  T.CheckCall(T.Val("3.13"), foo, T.Val(3.1));
-  T.CheckCall(T.Val("function (a,b) { return a + b; }3"), foo, foo);
-  T.CheckCall(T.Val("Abba3"), foo, T.Val("Abba"));
+  T.CheckCall(T.Val("33"), U.function, T.Val(3));
+  T.CheckCall(T.Val("3.13"), U.function, T.Val(3.1));
+  T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
+              U.function);
+  T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
 }
 
 
@@ -130,7 +129,6 @@
 }
 
 
-// TODO(titzer): factor these out into test-runtime-calls.cc
 TEST(RuntimeCallCPP2) {
   FLAG_allow_natives_syntax = true;
   FunctionTester T("(function(a,b) { return %NumberImul(a, b); })");
diff --git a/test/cctest/compiler/test-run-jsexceptions.cc b/test/cctest/compiler/test-run-jsexceptions.cc
index 37b2a2d..ab8c42a 100644
--- a/test/cctest/compiler/test-run-jsexceptions.cc
+++ b/test/cctest/compiler/test-run-jsexceptions.cc
@@ -61,7 +61,6 @@
 
 
 TEST(ThrowMessageIndirectly) {
-  i::FLAG_turbo_try_finally = true;
   static const char* src =
       "(function(a, b) {"
       "  try {"
@@ -170,7 +169,6 @@
 
 
 TEST(Finally) {
-  i::FLAG_turbo_try_finally = true;
   const char* src =
       "(function(a,b) {"
       "  var r = '-';"
@@ -188,7 +186,6 @@
 
 
 TEST(FinallyBreak) {
-  i::FLAG_turbo_try_finally = true;
   const char* src =
       "(function(a,b) {"
       "  var r = '-';"
@@ -244,7 +241,6 @@
 
 
 TEST(DeoptFinallyReturn) {
-  i::FLAG_turbo_try_finally = true;
   const char* src =
       "(function f(a) {"
       "  try {"
@@ -261,7 +257,6 @@
 
 
 TEST(DeoptFinallyReThrow) {
-  i::FLAG_turbo_try_finally = true;
   const char* src =
       "(function f(a) {"
       "  try {"
@@ -272,9 +267,7 @@
       "})";
   FunctionTester T(src);
 
-#if 0  // TODO(mstarzinger): Enable once we can.
   T.CheckThrows(T.NewObject("new Error"), T.Val(1));
-#endif
 }
 
 }  // namespace compiler
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 11a3582..fba9e0e 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -29,6 +29,25 @@
 }
 
 
+TEST(RunWord32ReverseBits) {
+  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Uint32());
+  if (!m.machine()->Word32ReverseBits().IsSupported()) {
+    // We can only test the operator if it exists on the testing platform.
+    return;
+  }
+  m.Return(m.AddNode(m.machine()->Word32ReverseBits().op(), m.Parameter(0)));
+
+  CHECK_EQ(uint32_t(0x00000000), m.Call(uint32_t(0x00000000)));
+  CHECK_EQ(uint32_t(0x12345678), m.Call(uint32_t(0x1e6a2c48)));
+  CHECK_EQ(uint32_t(0xfedcba09), m.Call(uint32_t(0x905d3b7f)));
+  CHECK_EQ(uint32_t(0x01010101), m.Call(uint32_t(0x80808080)));
+  CHECK_EQ(uint32_t(0x01020408), m.Call(uint32_t(0x10204080)));
+  CHECK_EQ(uint32_t(0xf0703010), m.Call(uint32_t(0x080c0e0f)));
+  CHECK_EQ(uint32_t(0x1f8d0a3a), m.Call(uint32_t(0x5c50b1f8)));
+  CHECK_EQ(uint32_t(0xffffffff), m.Call(uint32_t(0xffffffff)));
+}
+
+
 TEST(RunWord32Ctz) {
   BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
   if (!m.machine()->Word32Ctz().IsSupported()) {
@@ -72,7 +91,6 @@
   CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81)));
 }
 
-
 TEST(RunWord32Clz) {
   BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32());
   m.Return(m.Word32Clz(m.Parameter(0)));
@@ -133,6 +151,25 @@
 
 
 #if V8_TARGET_ARCH_64_BIT
+TEST(RunWord64ReverseBits) {
+  RawMachineAssemblerTester<uint64_t> m(MachineType::Uint64());
+  if (!m.machine()->Word64ReverseBits().IsSupported()) {
+    return;
+  }
+
+  m.Return(m.AddNode(m.machine()->Word64ReverseBits().op(), m.Parameter(0)));
+
+  CHECK_EQ(uint64_t(0x0000000000000000), m.Call(uint64_t(0x0000000000000000)));
+  CHECK_EQ(uint64_t(0x1234567890abcdef), m.Call(uint64_t(0xf7b3d5091e6a2c48)));
+  CHECK_EQ(uint64_t(0xfedcba0987654321), m.Call(uint64_t(0x84c2a6e1905d3b7f)));
+  CHECK_EQ(uint64_t(0x0101010101010101), m.Call(uint64_t(0x8080808080808080)));
+  CHECK_EQ(uint64_t(0x0102040803060c01), m.Call(uint64_t(0x803060c010204080)));
+  CHECK_EQ(uint64_t(0xf0703010e060200f), m.Call(uint64_t(0xf0040607080c0e0f)));
+  CHECK_EQ(uint64_t(0x2f8a6df01c21fa3b), m.Call(uint64_t(0xdc5f84380fb651f4)));
+  CHECK_EQ(uint64_t(0xffffffffffffffff), m.Call(uint64_t(0xffffffffffffffff)));
+}
+
+
 TEST(RunWord64Clz) {
   BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64());
   m.Return(m.Word64Clz(m.Parameter(0)));
@@ -3534,7 +3571,7 @@
   const int kNumElems = 3;
   Type buffer[kNumElems];
 
-  // initialize the buffer with raw data.
+  // initialize the buffer with some raw data.
   byte* raw = reinterpret_cast<byte*>(buffer);
   for (size_t i = 0; i < sizeof(buffer); i++) {
     raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA);
@@ -3543,14 +3580,14 @@
   // Test with various large and small offsets.
   for (int offset = -1; offset <= 200000; offset *= -5) {
     for (int i = 0; i < kNumElems; i++) {
-      RawMachineAssemblerTester<Type> m;
+      BufferedRawMachineAssemblerTester<Type> m;
       Node* base = m.PointerConstant(buffer - offset);
       Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0]));
       m.Return(m.Load(rep, base, index));
 
-      Type expected = buffer[i];
-      Type actual = m.Call();
-      CHECK(expected == actual);
+      volatile Type expected = buffer[i];
+      volatile Type actual = m.Call();
+      CHECK_EQ(expected, actual);
     }
   }
 }
@@ -3564,9 +3601,11 @@
   RunLoadImmIndex<int32_t>(MachineType::Int32());
   RunLoadImmIndex<uint32_t>(MachineType::Uint32());
   RunLoadImmIndex<int32_t*>(MachineType::AnyTagged());
-
-  // TODO(titzer): test kRepBit loads
-  // TODO(titzer): test MachineType::Float64() loads
+  RunLoadImmIndex<float>(MachineType::Float32());
+  RunLoadImmIndex<double>(MachineType::Float64());
+  if (kPointerSize == 8) {
+    RunLoadImmIndex<int64_t>(MachineType::Int64());
+  }
   // TODO(titzer): test various indexing modes.
 }
 
@@ -4124,6 +4163,43 @@
 }
 
 
+TEST(RunTruncateFloat32ToInt32) {
+  BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float32());
+  m.Return(m.TruncateFloat32ToInt32(m.Parameter(0)));
+  FOR_FLOAT32_INPUTS(i) {
+    if (*i <= static_cast<float>(std::numeric_limits<int32_t>::max()) &&
+        *i >= static_cast<float>(std::numeric_limits<int32_t>::min())) {
+      CheckFloatEq(static_cast<int32_t>(*i), m.Call(*i));
+    }
+  }
+}
+
+
+TEST(RunTruncateFloat32ToUint32) {
+  BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float32());
+  m.Return(m.TruncateFloat32ToUint32(m.Parameter(0)));
+  {
+    FOR_UINT32_INPUTS(i) {
+      float input = static_cast<float>(*i);
+      // This condition on 'input' is required because
+      // static_cast<float>(std::numeric_limits<uint32_t>::max()) results in a
+      // value outside uint32 range.
+      if (input < static_cast<float>(std::numeric_limits<uint32_t>::max())) {
+        CHECK_EQ(static_cast<uint32_t>(input), m.Call(input));
+      }
+    }
+  }
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      if (*i <= static_cast<float>(std::numeric_limits<uint32_t>::max()) &&
+          *i >= static_cast<float>(std::numeric_limits<uint32_t>::min())) {
+        CheckFloatEq(static_cast<uint32_t>(*i), m.Call(*i));
+      }
+    }
+  }
+}
+
+
 TEST(RunChangeFloat64ToInt32_A) {
   BufferedRawMachineAssemblerTester<int32_t> m;
   double magic = 11.1;
@@ -5577,6 +5653,79 @@
 }
 #endif  // USE_SIMULATOR
 
+template <typename T>
+void TestExternalReferenceFunction(
+    BufferedRawMachineAssemblerTester<int32_t>* m, ExternalReference ref,
+    T (*comparison)(T)) {
+  T parameter;
+
+  Node* function = m->ExternalConstant(ref);
+  m->CallCFunction1(MachineType::Pointer(), MachineType::Pointer(), function,
+                    m->PointerConstant(&parameter));
+  m->Return(m->Int32Constant(4356));
+  FOR_FLOAT64_INPUTS(i) {
+    parameter = *i;
+    m->Call();
+    CheckDoubleEq(comparison(*i), parameter);
+  }
+}
+
+TEST(RunCallExternalReferenceF32Trunc) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f32_trunc_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<float>(&m, ref, truncf);
+}
+
+TEST(RunCallExternalReferenceF32Floor) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f32_floor_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<float>(&m, ref, floorf);
+}
+
+TEST(RunCallExternalReferenceF32Ceil) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f32_ceil_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<float>(&m, ref, ceilf);
+}
+
+TEST(RunCallExternalReferenceF32RoundTiesEven) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f32_nearest_int_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<float>(&m, ref, nearbyintf);
+}
+
+TEST(RunCallExternalReferenceF64Trunc) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f64_trunc_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<double>(&m, ref, trunc);
+}
+
+TEST(RunCallExternalReferenceF64Floor) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f64_floor_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<double>(&m, ref, floor);
+}
+
+TEST(RunCallExternalReferenceF64Ceil) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f64_ceil_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<double>(&m, ref, ceil);
+}
+
+TEST(RunCallExternalReferenceF64RoundTiesEven) {
+  BufferedRawMachineAssemblerTester<int32_t> m;
+  ExternalReference ref =
+      ExternalReference::f64_nearest_int_wrapper_function(m.isolate());
+  TestExternalReferenceFunction<double>(&m, ref, nearbyint);
+}
+
 #if V8_TARGET_ARCH_64_BIT
 // TODO(titzer): run int64 tests on all platforms when supported.
 TEST(RunCheckedLoadInt64) {
@@ -6001,6 +6150,26 @@
 }
 
 
+TEST(RunRoundInt32ToFloat32) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Int32());
+  m.Return(m.RoundInt32ToFloat32(m.Parameter(0)));
+  FOR_INT32_INPUTS(i) {
+    volatile float expected = static_cast<float>(*i);
+    CHECK_EQ(expected, m.Call(*i));
+  }
+}
+
+
+TEST(RunRoundUint32ToFloat32) {
+  BufferedRawMachineAssemblerTester<float> m(MachineType::Uint32());
+  m.Return(m.RoundUint32ToFloat32(m.Parameter(0)));
+  FOR_UINT32_INPUTS(i) {
+    volatile float expected = static_cast<float>(*i);
+    CHECK_EQ(expected, m.Call(*i));
+  }
+}
+
+
 TEST(RunBitcastInt32ToFloat32) {
   int32_t input = 1;
   float output = 0.0;
@@ -6068,6 +6237,27 @@
   CHECK_EQ(44, r.Call(0));
 }
 
+TEST(ParentFramePointer) {
+  RawMachineAssemblerTester<int32_t> r(MachineType::Int32());
+  RawMachineLabel tlabel;
+  RawMachineLabel flabel;
+  RawMachineLabel merge;
+  Node* frame = r.LoadFramePointer();
+  Node* parent_frame = r.LoadParentFramePointer();
+  frame = r.Load(MachineType::IntPtr(), frame);
+  r.Branch(r.WordEqual(frame, parent_frame), &tlabel, &flabel);
+  r.Bind(&tlabel);
+  Node* fa = r.Int32Constant(1);
+  r.Goto(&merge);
+  r.Bind(&flabel);
+  Node* fb = r.Int32Constant(0);
+  r.Goto(&merge);
+  r.Bind(&merge);
+  Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb);
+  r.Return(phi);
+  CHECK_EQ(1, r.Call(1));
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc
index 791b0d7..8911409 100644
--- a/test/cctest/compiler/test-run-native-calls.cc
+++ b/test/cctest/compiler/test-run-native-calls.cc
@@ -1157,6 +1157,99 @@
 TEST(MixedParams_2) { MixedParamTest(2); }
 TEST(MixedParams_3) { MixedParamTest(3); }
 
+template <typename T>
+void TestStackSlot(MachineType slot_type, T expected) {
+  // Test: Generate with a function f which reserves a stack slot, call an inner
+  // function g from f which writes into the stack slot of f.
+
+  if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->num_allocatable_double_registers() < 2)
+    return;
+
+  Isolate* isolate = CcTest::InitIsolateOnce();
+
+  // Lots of code to generate the build descriptor for the inner function.
+  int parray_gp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0),
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(1)};
+  int rarray_gp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableGeneralCode(0)};
+  int parray_fp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0),
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(1)};
+  int rarray_fp[] = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN)
+          ->GetAllocatableDoubleCode(0)};
+  Allocator palloc(parray_gp, 2, parray_fp, 2);
+  Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
+  RegisterConfig config(palloc, ralloc);
+
+  Zone zone;
+  HandleScope scope(isolate);
+  MachineSignature::Builder builder(&zone, 1, 12);
+  builder.AddReturn(MachineType::Int32());
+  for (int i = 0; i < 10; i++) {
+    builder.AddParam(MachineType::Int32());
+  }
+  builder.AddParam(slot_type);
+  builder.AddParam(MachineType::Pointer());
+  MachineSignature* sig = builder.Build();
+  CallDescriptor* desc = config.Create(&zone, sig);
+
+  // Create inner function g. g has lots of parameters so that they are passed
+  // over the stack.
+  Handle<Code> inner;
+  Graph graph(&zone);
+  RawMachineAssembler g(isolate, &graph, desc);
+
+  g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10),
+          WriteBarrierKind::kNoWriteBarrier);
+  g.Return(g.Parameter(9));
+  inner = CompileGraph("Compute", desc, &graph, g.Export());
+
+  // Create function f with a stack slot which calls the inner function g.
+  BufferedRawMachineAssemblerTester<T> f(slot_type);
+  Node* target = f.HeapConstant(inner);
+  Node* stack_slot = f.StackSlot(slot_type.representation());
+  Node* args[12];
+  for (int i = 0; i < 10; i++) {
+    args[i] = f.Int32Constant(i);
+  }
+  args[10] = f.Parameter(0);
+  args[11] = stack_slot;
+
+  f.CallN(desc, target, args);
+  f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));
+
+  CHECK_EQ(expected, f.Call(expected));
+}
+
+TEST(RunStackSlotInt32) {
+  int32_t magic = 0x12345678;
+  TestStackSlot(MachineType::Int32(), magic);
+}
+
+#if !V8_TARGET_ARCH_32_BIT
+TEST(RunStackSlotInt64) {
+  int64_t magic = 0x123456789abcdef0;
+  TestStackSlot(MachineType::Int64(), magic);
+}
+#endif
+
+TEST(RunStackSlotFloat32) {
+  float magic = 1234.125f;
+  TestStackSlot(MachineType::Float32(), magic);
+}
+
+TEST(RunStackSlotFloat64) {
+  double magic = 3456.375;
+  TestStackSlot(MachineType::Float64(), magic);
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/test/cctest/compiler/test-run-properties.cc b/test/cctest/compiler/test-run-properties.cc
deleted file mode 100644
index 3c42102..0000000
--- a/test/cctest/compiler/test-run-properties.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/cctest/compiler/function-tester.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <typename U>
-static void TypedArrayLoadHelper(const char* array_type) {
-  static const uint32_t kValues[] = {
-      0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
-      0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
-      0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
-  EmbeddedVector<char, 1024> values_buffer;
-  StringBuilder values_builder(values_buffer.start(), values_buffer.length());
-  for (size_t i = 0; i < arraysize(kValues); ++i) {
-    values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
-  }
-
-  // Note that below source creates two different typed arrays with the same
-  // elements kind to get coverage for both (on heap / with external backing
-  // store) access patterns.
-  const char* source =
-      "(function(a) {"
-      "  var x = (a = new %sArray(%d)); %s;"
-      "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
-      "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
-      "  if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
-      "  function f(a,b) {"
-      "    a = a | 0; b = b | 0;"
-      "    return x[a] + y[b];"
-      "  }"
-      "  return f;"
-      "})()";
-  EmbeddedVector<char, 1024> source_buffer;
-  SNPrintF(source_buffer, source, array_type, arraysize(kValues),
-           values_buffer.start(), array_type, arraysize(kValues),
-           values_buffer.start(), array_type, array_type);
-
-  FunctionTester T(source_buffer.start(),
-                   CompilationInfo::kFunctionContextSpecializing |
-                       CompilationInfo::kTypingEnabled);
-  for (size_t i = 0; i < arraysize(kValues); ++i) {
-    for (size_t j = 0; j < arraysize(kValues); ++j) {
-      volatile U value_a = static_cast<U>(kValues[i]);
-      volatile U value_b = static_cast<U>(kValues[j]);
-      double expected =
-          static_cast<double>(value_a) + static_cast<double>(value_b);
-      T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
-                  T.Val(static_cast<double>(j)));
-    }
-  }
-}
-
-
-TEST(TypedArrayLoad) {
-  FLAG_typed_array_max_size_in_heap = 256;
-  TypedArrayLoadHelper<int8_t>("Int8");
-  TypedArrayLoadHelper<uint8_t>("Uint8");
-  TypedArrayLoadHelper<int16_t>("Int16");
-  TypedArrayLoadHelper<uint16_t>("Uint16");
-  TypedArrayLoadHelper<int32_t>("Int32");
-  TypedArrayLoadHelper<uint32_t>("Uint32");
-  TypedArrayLoadHelper<float>("Float32");
-  TypedArrayLoadHelper<double>("Float64");
-  // TODO(mstarzinger): Add tests for ClampedUint8.
-}
-
-
-template <typename U>
-static void TypedArrayStoreHelper(const char* array_type) {
-  static const uint32_t kValues[] = {
-      0x00000000, 0x00000001, 0x00000023, 0x00000042, 0x12345678, 0x87654321,
-      0x0000003f, 0x0000007f, 0x00003fff, 0x00007fff, 0x3fffffff, 0x7fffffff,
-      0x000000ff, 0x00000080, 0x0000ffff, 0x00008000, 0xffffffff, 0x80000000};
-  EmbeddedVector<char, 1024> values_buffer;
-  StringBuilder values_builder(values_buffer.start(), values_buffer.length());
-  for (size_t i = 0; i < arraysize(kValues); ++i) {
-    values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]);
-  }
-
-  // Note that below source creates two different typed arrays with the same
-  // elements kind to get coverage for both (on heap/with external backing
-  // store) access patterns.
-  const char* source =
-      "(function(a) {"
-      "  var x = (a = new %sArray(%d)); %s;"
-      "  var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);"
-      "  if (!%%HasFixed%sElements(x)) %%AbortJS('x');"
-      "  if (!%%HasFixed%sElements(y)) %%AbortJS('y');"
-      "  function f(a,b) {"
-      "    a = a | 0; b = b | 0;"
-      "    var t = x[a];"
-      "    x[a] = y[b];"
-      "    y[b] = t;"
-      "    t = y[b];"
-      "    y[b] = x[a];"
-      "    x[a] = t;"
-      "    return x[a] + y[b];"
-      "  }"
-      "  return f;"
-      "})()";
-  EmbeddedVector<char, 2048> source_buffer;
-  SNPrintF(source_buffer, source, array_type, arraysize(kValues),
-           values_buffer.start(), array_type, arraysize(kValues),
-           values_buffer.start(), array_type, array_type);
-
-  FunctionTester T(source_buffer.start(),
-                   CompilationInfo::kFunctionContextSpecializing |
-                       CompilationInfo::kTypingEnabled);
-  for (size_t i = 0; i < arraysize(kValues); ++i) {
-    for (size_t j = 0; j < arraysize(kValues); ++j) {
-      volatile U value_a = static_cast<U>(kValues[i]);
-      volatile U value_b = static_cast<U>(kValues[j]);
-      double expected =
-          static_cast<double>(value_a) + static_cast<double>(value_b);
-      T.CheckCall(T.Val(expected), T.Val(static_cast<double>(i)),
-                  T.Val(static_cast<double>(j)));
-    }
-  }
-}
-
-
-TEST(TypedArrayStore) {
-  FLAG_typed_array_max_size_in_heap = 256;
-  TypedArrayStoreHelper<int8_t>("Int8");
-  TypedArrayStoreHelper<uint8_t>("Uint8");
-  TypedArrayStoreHelper<int16_t>("Int16");
-  TypedArrayStoreHelper<uint16_t>("Uint16");
-  TypedArrayStoreHelper<int32_t>("Int32");
-  TypedArrayStoreHelper<uint32_t>("Uint32");
-  TypedArrayStoreHelper<float>("Float32");
-  TypedArrayStoreHelper<double>("Float64");
-  // TODO(mstarzinger): Add tests for ClampedUint8.
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/test/cctest/compiler/test-run-stubs.cc b/test/cctest/compiler/test-run-stubs.cc
index 7a2a094..c745219 100644
--- a/test/cctest/compiler/test-run-stubs.cc
+++ b/test/cctest/compiler/test-run-stubs.cc
@@ -27,8 +27,13 @@
   // Create code and an accompanying descriptor.
   StringLengthStub stub(isolate);
   Handle<Code> code = stub.GenerateCode();
-  CompilationInfo info(&stub, isolate, zone);
-  CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
+  CompilationInfo info("test", isolate, zone,
+                       Code::ComputeFlags(Code::HANDLER));
+  CallInterfaceDescriptor interface_descriptor =
+      stub.GetCallInterfaceDescriptor();
+  CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+      isolate, zone, interface_descriptor, stub.GetStackParameterCount(),
+      CallDescriptor::kNoFlags, Operator::kNoProperties);
 
   // Create a function to call the code using the descriptor.
   Graph graph(zone);
diff --git a/test/cctest/compiler/value-helper.h b/test/cctest/compiler/value-helper.h
index cbde9a7..83cd33c 100644
--- a/test/cctest/compiler/value-helper.h
+++ b/test/cctest/compiler/value-helper.h
@@ -312,6 +312,23 @@
 
 #define FOR_UINT32_SHIFTS(var) for (uint32_t var = 0; var < 32; var++)
 
+// TODO(bmeurer): Drop this crap once we switch to GTest/Gmock.
+static inline void CheckFloatEq(volatile float x, volatile float y) {
+  if (std::isnan(x)) {
+    CHECK(std::isnan(y));
+  } else {
+    CHECK_EQ(x, y);
+  }
+}
+
+static inline void CheckDoubleEq(volatile double x, volatile double y) {
+  if (std::isnan(x)) {
+    CHECK(std::isnan(y));
+  } else {
+    CHECK_EQ(x, y);
+  }
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8