verifier.cc 77.9 KB
Newer Older
1 2 3 4 5 6
// 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 "src/compiler/verifier.h"

7
#include <algorithm>
8 9
#include <deque>
#include <queue>
10 11
#include <sstream>
#include <string>
12

13
#include "src/compiler/all-nodes.h"
14
#include "src/compiler/common-operator.h"
15
#include "src/compiler/graph.h"
16
#include "src/compiler/js-operator.h"
17
#include "src/compiler/node-properties.h"
18
#include "src/compiler/node.h"
19
#include "src/compiler/opcodes.h"
20
#include "src/compiler/operator-properties.h"
21
#include "src/compiler/operator.h"
22
#include "src/compiler/schedule.h"
23
#include "src/compiler/simplified-operator.h"
24
#include "src/compiler/state-values-utils.h"
25
#include "src/compiler/type-cache.h"
26 27
#include "src/utils/bit-vector.h"
#include "src/utils/ostreams.h"
28 29 30 31 32 33

namespace v8 {
namespace internal {
namespace compiler {


34
class Verifier::Visitor {
35
 public:
36 37 38 39 40
  Visitor(Zone* z, Typing typed, CheckInputs check_inputs, CodeType code_type)
      : zone(z),
        typing(typed),
        check_inputs(check_inputs),
        code_type(code_type) {}
41

42
  void CheckSwitch(Node* node, const AllNodes& all);
43
  void Check(Node* node, const AllNodes& all);
44

45 46
  Zone* zone;
  Typing typing;
47
  CheckInputs check_inputs;
48
  CodeType code_type;
49 50

 private:
51 52 53
  void CheckNotTyped(Node* node) {
    if (NodeProperties::IsTyped(node)) {
      std::ostringstream str;
54 55
      str << "TypeError: node #" << node->id() << ":" << *node->op()
          << " should never have a type";
56
      FATAL("%s", str.str().c_str());
57 58
    }
  }
59
  void CheckTypeIs(Node* node, Type type) {
60
    if (typing == TYPED && !NodeProperties::GetType(node).Is(type)) {
61
      std::ostringstream str;
62 63
      str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
          << NodeProperties::GetType(node) << " is not " << type;
64
      FATAL("%s", str.str().c_str());
65 66
    }
  }
67
  void CheckTypeMaybe(Node* node, Type type) {
68
    if (typing == TYPED && !NodeProperties::GetType(node).Maybe(type)) {
69
      std::ostringstream str;
70 71
      str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
          << NodeProperties::GetType(node) << " must intersect " << type;
72
      FATAL("%s", str.str().c_str());
73 74
    }
  }
75
  void CheckValueInputIs(Node* node, int i, Type type) {
76
    Node* input = NodeProperties::GetValueInput(node, i);
77
    if (typing == TYPED && !NodeProperties::GetType(input).Is(type)) {
78
      std::ostringstream str;
79 80
      str << "TypeError: node #" << node->id() << ":" << *node->op()
          << "(input @" << i << " = " << input->opcode() << ":"
81 82
          << input->op()->mnemonic() << ") type "
          << NodeProperties::GetType(input) << " is not " << type;
83
      FATAL("%s", str.str().c_str());
84 85
    }
  }
86 87 88 89 90 91
  void CheckOutput(Node* node, Node* use, int count, const char* kind) {
    if (count <= 0) {
      std::ostringstream str;
      str << "GraphError: node #" << node->id() << ":" << *node->op()
          << " does not produce " << kind << " output used by node #"
          << use->id() << ":" << *use->op();
92
      FATAL("%s", str.str().c_str());
93 94
    }
  }
95 96
};

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
void Verifier::Visitor::CheckSwitch(Node* node, const AllNodes& all) {
  // Count the number of {kIfValue} uses.
  int case_count = 0;
  bool expect_default = true;

  // Data structure to check that each {kIfValue} has a unique value.
  std::unordered_set<int32_t> if_value_parameters;

  Node::Uses uses = node->uses();
  for (const Node* use : uses) {
    CHECK(all.IsLive(use));
    switch (use->opcode()) {
      case IrOpcode::kIfValue: {
        // Check if each value is unique.
        CHECK(
            if_value_parameters.emplace(IfValueParametersOf(use->op()).value())
                .second);
        ++case_count;
        break;
      }
      case IrOpcode::kIfDefault: {
        // We expect exactly one {kIfDefault}.
        CHECK(expect_default);
        expect_default = false;
        break;
      }
      default: {
        FATAL("Switch #%d illegally used by #%d:%s", node->id(), use->id(),
              use->op()->mnemonic());
        break;
      }
    }
  }

  CHECK(!expect_default);
  // + 1 because of the one {kIfDefault}.
  CHECK_EQ(node->op()->ControlOutputCount(), case_count + 1);
  CheckNotTyped(node);
}

137
void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
138
  int value_count = node->op()->ValueInputCount();
139
  int context_count = OperatorProperties::GetContextInputCount(node->op());
140 141
  int frame_state_count =
      OperatorProperties::GetFrameStateInputCount(node->op());
142 143
  int effect_count = node->op()->EffectInputCount();
  int control_count = node->op()->ControlInputCount();
144 145

  // Verify number of inputs matches up.
146 147 148 149
  int input_count = value_count + context_count + frame_state_count;
  if (check_inputs == kAll) {
    input_count += effect_count + control_count;
  }
150 151
  CHECK_EQ(input_count, node->InputCount());

152 153
  // If this node has any effect outputs, make sure that it is
  // consumed as an effect input somewhere else.
154
  // TODO(mvstanton): support this kind of verification for Wasm compiles, too.
155 156 157
  if (code_type != kWasm && node->op()->EffectOutputCount() > 0) {
    int effect_edges = 0;
    for (Edge edge : node->use_edges()) {
158
      if (all.IsLive(edge.from()) && NodeProperties::IsEffectEdge(edge)) {
159 160 161 162 163 164
        effect_edges++;
      }
    }
    DCHECK_GT(effect_edges, 0);
  }

165
  // Verify that frame state has been inserted for the nodes that need it.
166
  for (int i = 0; i < frame_state_count; i++) {
167
    Node* frame_state = NodeProperties::GetFrameStateInput(node);
168
    CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
169
          // kFrameState uses Start as a sentinel.
170
          (node->opcode() == IrOpcode::kFrameState &&
171
           frame_state->opcode() == IrOpcode::kStart));
172 173
  }

174 175 176
  // Verify all value inputs actually produce a value.
  for (int i = 0; i < value_count; ++i) {
    Node* value = NodeProperties::GetValueInput(node, i);
177
    CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
178 179 180 181 182
    // Verify that only parameters and projections can have input nodes with
    // multiple outputs.
    CHECK(node->opcode() == IrOpcode::kParameter ||
          node->opcode() == IrOpcode::kProjection ||
          value->op()->ValueOutputCount() <= 1);
183 184 185 186 187
  }

  // Verify all context inputs are value nodes.
  for (int i = 0; i < context_count; ++i) {
    Node* context = NodeProperties::GetContextInput(node);
188
    CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
189 190
  }

191 192 193 194 195 196
  if (check_inputs == kAll) {
    // Verify all effect inputs actually have an effect.
    for (int i = 0; i < effect_count; ++i) {
      Node* effect = NodeProperties::GetEffectInput(node);
      CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
    }
197

198 199 200 201 202 203
    // Verify all control inputs are control nodes.
    for (int i = 0; i < control_count; ++i) {
      Node* control = NodeProperties::GetControlInput(node, i);
      CheckOutput(control, node, control->op()->ControlOutputCount(),
                  "control");
    }
204

205 206
    // Verify that nodes that can throw either have both IfSuccess/IfException
    // projections as the only control uses or no projections at all.
207
    if (!node->op()->HasProperty(Operator::kNoThrow)) {
208 209
      Node* discovered_if_exception = nullptr;
      Node* discovered_if_success = nullptr;
210
      Node* discovered_direct_use = nullptr;
211
      int total_number_of_control_uses = 0;
212 213 214 215
      for (Edge edge : node->use_edges()) {
        if (!NodeProperties::IsControlEdge(edge)) {
          continue;
        }
216
        total_number_of_control_uses++;
217
        Node* control_use = edge.from();
218 219 220
        if (control_use->opcode() == IrOpcode::kIfSuccess) {
          CHECK_NULL(discovered_if_success);  // Only one allowed.
          discovered_if_success = control_use;
221
        } else if (control_use->opcode() == IrOpcode::kIfException) {
222 223
          CHECK_NULL(discovered_if_exception);  // Only one allowed.
          discovered_if_exception = control_use;
224 225
        } else {
          discovered_direct_use = control_use;
226 227 228
        }
      }
      if (discovered_if_success && !discovered_if_exception) {
229 230 231 232 233
        FATAL(
            "#%d:%s should be followed by IfSuccess/IfException, but is "
            "only followed by single #%d:%s",
            node->id(), node->op()->mnemonic(), discovered_if_success->id(),
            discovered_if_success->op()->mnemonic());
234 235
      }
      if (discovered_if_exception && !discovered_if_success) {
236 237 238 239 240
        FATAL(
            "#%d:%s should be followed by IfSuccess/IfException, but is "
            "only followed by single #%d:%s",
            node->id(), node->op()->mnemonic(), discovered_if_exception->id(),
            discovered_if_exception->op()->mnemonic());
241
      }
242 243 244 245 246 247 248
      if ((discovered_if_success || discovered_if_exception) &&
          total_number_of_control_uses != 2) {
        FATAL(
            "#%d:%s if followed by IfSuccess/IfException, there should be "
            "no direct control uses, but direct use #%d:%s was found",
            node->id(), node->op()->mnemonic(), discovered_direct_use->id(),
            discovered_direct_use->op()->mnemonic());
249 250
      }
    }
251 252
  }

253 254 255 256 257 258
  switch (node->opcode()) {
    case IrOpcode::kStart:
      // Start has no inputs.
      CHECK_EQ(0, input_count);
      // Type is a tuple.
      // TODO(rossberg): Multiple outputs are currently typed as Internal.
259
      CheckTypeIs(node, Type::Internal());
260 261 262
      break;
    case IrOpcode::kEnd:
      // End has no outputs.
263 264 265
      CHECK_EQ(0, node->op()->ValueOutputCount());
      CHECK_EQ(0, node->op()->EffectOutputCount());
      CHECK_EQ(0, node->op()->ControlOutputCount());
266 267 268 269
      // All inputs are graph terminators.
      for (const Node* input : node->inputs()) {
        CHECK(IrOpcode::IsGraphTerminator(input->opcode()));
      }
270 271
      CheckNotTyped(node);
      break;
272
    case IrOpcode::kDead:
273
      // Dead is never connected to the graph.
274
      UNREACHABLE();
275
    case IrOpcode::kDeadValue:
276
      CheckValueInputIs(node, 0, Type::None());
277 278 279
      CheckTypeIs(node, Type::None());
      break;
    case IrOpcode::kUnreachable:
280 281 282 283 284 285 286 287 288
      CheckTypeIs(node, Type::None());
      for (Edge edge : node->use_edges()) {
        Node* use = edge.from();
        if (NodeProperties::IsValueEdge(edge) && all.IsLive(use)) {
          // {Unreachable} nodes can only be used by {DeadValue}, because they
          // don't actually produce a value.
          CHECK_EQ(IrOpcode::kDeadValue, use->opcode());
        }
      }
289
      break;
290 291 292
    case IrOpcode::kBranch: {
      // Branch uses are IfTrue and IfFalse.
      int count_true = 0, count_false = 0;
293
      for (const Node* use : node->uses()) {
294 295
        CHECK(all.IsLive(use) && (use->opcode() == IrOpcode::kIfTrue ||
                                  use->opcode() == IrOpcode::kIfFalse));
296 297
        if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
        if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
298
      }
299 300
      CHECK_EQ(1, count_true);
      CHECK_EQ(1, count_false);
301 302
      // The condition must be a Boolean.
      CheckValueInputIs(node, 0, Type::Boolean());
303 304 305 306
      CheckNotTyped(node);
      break;
    }
    case IrOpcode::kIfTrue:
307 308
    case IrOpcode::kIfFalse: {
      Node* control = NodeProperties::GetControlInput(node, 0);
309
      CHECK_EQ(IrOpcode::kBranch, control->opcode());
310 311
      CheckNotTyped(node);
      break;
312
    }
313
    case IrOpcode::kIfSuccess: {
314 315 316 317 318 319
      // IfSuccess and IfException continuation only on throwing nodes.
      Node* input = NodeProperties::GetControlInput(node, 0);
      CHECK(!input->op()->HasProperty(Operator::kNoThrow));
      CheckNotTyped(node);
      break;
    }
320 321 322 323
    case IrOpcode::kIfException: {
      // IfSuccess and IfException continuation only on throwing nodes.
      Node* input = NodeProperties::GetControlInput(node, 0);
      CHECK(!input->op()->HasProperty(Operator::kNoThrow));
324
      CheckTypeIs(node, Type::Any());
325 326
      break;
    }
327
    case IrOpcode::kSwitch: {
328
      CheckSwitch(node, all);
329 330
      break;
    }
331 332
    case IrOpcode::kIfValue:
    case IrOpcode::kIfDefault:
333 334 335 336
      CHECK_EQ(IrOpcode::kSwitch,
               NodeProperties::GetControlInput(node)->opcode());
      CheckNotTyped(node);
      break;
337 338 339 340 341 342 343
    case IrOpcode::kLoop: {
      CHECK_EQ(control_count, input_count);
      CheckNotTyped(node);
      // All loops need to be connected to a {Terminate} node to ensure they
      // stay connected to the graph end.
      bool has_terminate = false;
      for (const Node* use : node->uses()) {
344
        if (all.IsLive(use) && use->opcode() == IrOpcode::kTerminate) {
345 346 347 348 349 350 351
          has_terminate = true;
          break;
        }
      }
      CHECK(has_terminate);
      break;
    }
352 353 354 355
    case IrOpcode::kMerge:
      CHECK_EQ(control_count, input_count);
      CheckNotTyped(node);
      break;
356 357 358 359
    case IrOpcode::kDeoptimizeIf:
    case IrOpcode::kDeoptimizeUnless:
      CheckNotTyped(node);
      break;
360 361 362 363
    case IrOpcode::kTrapIf:
    case IrOpcode::kTrapUnless:
      CheckNotTyped(node);
      break;
364
    case IrOpcode::kDeoptimize:
365
    case IrOpcode::kReturn:
366 367
    case IrOpcode::kThrow:
      // Deoptimize, Return and Throw uses are End.
368
      for (const Node* use : node->uses()) {
369 370 371
        if (all.IsLive(use)) {
          CHECK_EQ(IrOpcode::kEnd, use->opcode());
        }
372
      }
373 374
      CheckNotTyped(node);
      break;
375
    case IrOpcode::kTerminate:
376 377 378 379
      // Terminates take one loop and effect.
      CHECK_EQ(1, control_count);
      CHECK_EQ(1, effect_count);
      CHECK_EQ(2, input_count);
380 381
      CHECK_EQ(IrOpcode::kLoop,
               NodeProperties::GetControlInput(node)->opcode());
382
      // Terminate uses are End.
383
      for (const Node* use : node->uses()) {
384 385 386
        if (all.IsLive(use)) {
          CHECK_EQ(IrOpcode::kEnd, use->opcode());
        }
387
      }
388 389
      CheckNotTyped(node);
      break;
390 391 392 393 394 395 396

    // Common operators
    // ----------------
    case IrOpcode::kParameter: {
      // Parameters have the start node as inputs.
      CHECK_EQ(1, input_count);
      // Parameter has an input that produces enough values.
397 398 399
      int const index = ParameterIndexOf(node->op());
      Node* const start = NodeProperties::GetValueInput(node, 0);
      CHECK_EQ(IrOpcode::kStart, start->opcode());
400
      // Currently, parameter indices start at -1 instead of 0.
401 402
      CHECK_LE(-1, index);
      CHECK_LT(index + 1, start->op()->ValueOutputCount());
403
      CheckTypeIs(node, Type::Any());
404 405
      break;
    }
406 407
    case IrOpcode::kInt32Constant:  // TODO(turbofan): rename Word32Constant?
    case IrOpcode::kInt64Constant:  // TODO(turbofan): rename Word64Constant?
408
    case IrOpcode::kTaggedIndexConstant:
409 410 411 412
    case IrOpcode::kFloat32Constant:
    case IrOpcode::kFloat64Constant:
    case IrOpcode::kRelocatableInt32Constant:
    case IrOpcode::kRelocatableInt64Constant:
413 414
      // Constants have no inputs.
      CHECK_EQ(0, input_count);
415
      CheckNotTyped(node);
416 417 418 419
      break;
    case IrOpcode::kNumberConstant:
      // Constants have no inputs.
      CHECK_EQ(0, input_count);
420
      CheckTypeIs(node, Type::Number());
421 422
      break;
    case IrOpcode::kHeapConstant:
423
    case IrOpcode::kCompressedHeapConstant:
424 425
      // Constants have no inputs.
      CHECK_EQ(0, input_count);
426
      CheckTypeIs(node, Type::Any());
427 428
      break;
    case IrOpcode::kExternalConstant:
429
    case IrOpcode::kPointerConstant:
430 431
      // Constants have no inputs.
      CHECK_EQ(0, input_count);
432
      CheckTypeIs(node, Type::ExternalPointer());
433
      break;
434 435 436 437 438
    case IrOpcode::kOsrValue:
      // OSR values have a value and a control input.
      CHECK_EQ(1, control_count);
      CHECK_EQ(1, input_count);
      // Type is merged from other values in the graph and could be any.
439
      CheckTypeIs(node, Type::Any());
440
      break;
441 442
    case IrOpcode::kProjection: {
      // Projection has an input that produces enough values.
443
      int index = static_cast<int>(ProjectionIndexOf(node->op()));
444
      Node* input = NodeProperties::GetValueInput(node, 0);
445
      CHECK_GT(input->op()->ValueOutputCount(), index);
446
      CheckTypeIs(node, Type::Any());
447 448
      break;
    }
449 450 451 452
    case IrOpcode::kSelect: {
      CHECK_EQ(0, effect_count);
      CHECK_EQ(0, control_count);
      CHECK_EQ(3, value_count);
453 454 455
      // The condition must be a Boolean.
      CheckValueInputIs(node, 0, Type::Boolean());
      CheckTypeIs(node, Type::Any());
456 457
      break;
    }
458 459 460 461 462
    case IrOpcode::kPhi: {
      // Phi input count matches parent control node.
      CHECK_EQ(0, effect_count);
      CHECK_EQ(1, control_count);
      Node* control = NodeProperties::GetControlInput(node, 0);
463
      CHECK_EQ(value_count, control->op()->ControlInputCount());
464 465 466 467 468
      CHECK_EQ(input_count, 1 + value_count);
      // Type must be subsumed by all input types.
      // TODO(rossberg): for now at least, narrowing does not really hold.
      /*
      for (int i = 0; i < value_count; ++i) {
469
        CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
470
      }
471 472 473
      */
      break;
    }
474 475 476 477
    case IrOpcode::kInductionVariablePhi: {
      // This is only a temporary node for the typer.
      UNREACHABLE();
    }
478 479 480 481 482
    case IrOpcode::kEffectPhi: {
      // EffectPhi input count matches parent control node.
      CHECK_EQ(0, value_count);
      CHECK_EQ(1, control_count);
      Node* control = NodeProperties::GetControlInput(node, 0);
483
      CHECK_EQ(effect_count, control->op()->ControlInputCount());
484
      CHECK_EQ(input_count, 1 + effect_count);
485 486 487 488 489 490 491 492 493 494 495 496
      // If the control input is a Merge, then make sure that at least one
      // of it's usages is non-phi.
      if (control->opcode() == IrOpcode::kMerge) {
        bool non_phi_use_found = false;
        for (Node* use : control->uses()) {
          if (all.IsLive(use) && use->opcode() != IrOpcode::kEffectPhi &&
              use->opcode() != IrOpcode::kPhi) {
            non_phi_use_found = true;
          }
        }
        CHECK(non_phi_use_found);
      }
497 498
      break;
    }
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    case IrOpcode::kLoopExit: {
      CHECK_EQ(2, control_count);
      Node* loop = NodeProperties::GetControlInput(node, 1);
      CHECK_EQ(IrOpcode::kLoop, loop->opcode());
      break;
    }
    case IrOpcode::kLoopExitValue: {
      CHECK_EQ(1, control_count);
      Node* loop_exit = NodeProperties::GetControlInput(node, 0);
      CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
      break;
    }
    case IrOpcode::kLoopExitEffect: {
      CHECK_EQ(1, control_count);
      Node* loop_exit = NodeProperties::GetControlInput(node, 0);
      CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
      break;
    }
517
    case IrOpcode::kCheckpoint:
518 519
      CheckNotTyped(node);
      break;
520
    case IrOpcode::kBeginRegion:
521 522
      // TODO(rossberg): what are the constraints on these?
      break;
523
    case IrOpcode::kFinishRegion: {
524 525 526
      // TODO(rossberg): what are the constraints on these?
      // Type must be subsumed by input type.
      if (typing == TYPED) {
527
        Node* val = NodeProperties::GetValueInput(node, 0);
528
        CHECK(NodeProperties::GetType(val).Is(NodeProperties::GetType(node)));
529
      }
530 531
      break;
    }
532
    case IrOpcode::kFrameState: {
533
      // TODO(jarin): what are the constraints on these?
534 535 536 537
      CHECK_EQ(5, value_count);
      CHECK_EQ(0, control_count);
      CHECK_EQ(0, effect_count);
      CHECK_EQ(6, input_count);
538 539 540
      // Check that the parameters and registers are kStateValues or
      // kTypedStateValues.
      for (int i = 0; i < 2; ++i) {
541 542 543 544 545
        CHECK(NodeProperties::GetValueInput(node, i)->opcode() ==
                  IrOpcode::kStateValues ||
              NodeProperties::GetValueInput(node, i)->opcode() ==
                  IrOpcode::kTypedStateValues);
      }
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573

      // Checks that the state input is empty for all but kInterpretedFunction
      // frames, where it should have size one.
      {
        const FrameStateInfo& state_info = FrameStateInfoOf(node->op());
        const FrameStateFunctionInfo* func_info = state_info.function_info();
        CHECK_EQ(func_info->parameter_count(),
                 StateValuesAccess(node->InputAt(kFrameStateParametersInput))
                     .size());
        CHECK_EQ(
            func_info->local_count(),
            StateValuesAccess(node->InputAt(kFrameStateLocalsInput)).size());

        Node* accumulator = node->InputAt(kFrameStateStackInput);
        if (func_info->type() == FrameStateType::kInterpretedFunction) {
          // The accumulator (InputAt(2)) cannot be kStateValues.
          // It can be kTypedStateValues (to signal the type) and it can have
          // other Node types including that of the optimized_out HeapConstant.
          CHECK_NE(accumulator->opcode(), IrOpcode::kStateValues);
          if (accumulator->opcode() == IrOpcode::kTypedStateValues) {
            CHECK_EQ(1, StateValuesAccess(accumulator).size());
          }
        } else {
          CHECK(accumulator->opcode() == IrOpcode::kTypedStateValues ||
                accumulator->opcode() == IrOpcode::kStateValues);
          CHECK_EQ(0, StateValuesAccess(accumulator).size());
        }
      }
574
      break;
575
    }
576 577
    case IrOpcode::kObjectId:
      CheckTypeIs(node, Type::Object());
578
      break;
579
    case IrOpcode::kStateValues:
580
    case IrOpcode::kTypedStateValues:
581
    case IrOpcode::kArgumentsElementsState:
582
    case IrOpcode::kArgumentsLengthState:
583 584
    case IrOpcode::kObjectState:
    case IrOpcode::kTypedObjectState:
585 586 587 588 589
      // TODO(jarin): what are the constraints on these?
      break;
    case IrOpcode::kCall:
      // TODO(rossberg): what are the constraints on these?
      break;
590 591 592
    case IrOpcode::kTailCall:
      // TODO(bmeurer): what are the constraints on these?
      break;
593 594 595 596 597 598 599 600 601

    // JavaScript operators
    // --------------------
    case IrOpcode::kJSEqual:
    case IrOpcode::kJSStrictEqual:
    case IrOpcode::kJSLessThan:
    case IrOpcode::kJSGreaterThan:
    case IrOpcode::kJSLessThanOrEqual:
    case IrOpcode::kJSGreaterThanOrEqual:
602
      CheckTypeIs(node, Type::Boolean());
603 604
      break;

605 606 607
    case IrOpcode::kJSAdd:
      CheckTypeIs(node, Type::NumericOrString());
      break;
608 609 610 611 612 613 614 615 616 617
    case IrOpcode::kJSBitwiseOr:
    case IrOpcode::kJSBitwiseXor:
    case IrOpcode::kJSBitwiseAnd:
    case IrOpcode::kJSShiftLeft:
    case IrOpcode::kJSShiftRight:
    case IrOpcode::kJSShiftRightLogical:
    case IrOpcode::kJSSubtract:
    case IrOpcode::kJSMultiply:
    case IrOpcode::kJSDivide:
    case IrOpcode::kJSModulus:
618
    case IrOpcode::kJSExponentiate:
619
    case IrOpcode::kJSBitwiseNot:
620 621
    case IrOpcode::kJSDecrement:
    case IrOpcode::kJSIncrement:
622 623 624 625
    case IrOpcode::kJSNegate:
      CheckTypeIs(node, Type::Numeric());
      break;

626
    case IrOpcode::kToBoolean:
627
      CheckTypeIs(node, Type::Boolean());
628
      break;
629
    case IrOpcode::kJSToLength:
630
      CheckTypeIs(node, Type::Range(0, kMaxSafeInteger, zone));
631 632
      break;
    case IrOpcode::kJSToName:
633
      CheckTypeIs(node, Type::Name());
634
      break;
635
    case IrOpcode::kJSToNumber:
636
    case IrOpcode::kJSToNumberConvertBigInt:
637
      CheckTypeIs(node, Type::Number());
638
      break;
639 640 641
    case IrOpcode::kJSToNumeric:
      CheckTypeIs(node, Type::Numeric());
      break;
642
    case IrOpcode::kJSToString:
643
      CheckTypeIs(node, Type::String());
644 645
      break;
    case IrOpcode::kJSToObject:
646
      CheckTypeIs(node, Type::Receiver());
647
      break;
648 649 650 651 652
    case IrOpcode::kJSParseInt:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Number());
      break;
653 654 655 656 657
    case IrOpcode::kJSRegExpTest:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::String());
      CheckTypeIs(node, Type::Boolean());
      break;
658
    case IrOpcode::kJSCreate:
659
      CheckTypeIs(node, Type::Object());
660
      break;
661
    case IrOpcode::kJSCreateArguments:
662
      CheckTypeIs(node, Type::ArrayOrOtherObject());
663
      break;
664
    case IrOpcode::kJSCreateArray:
665
      CheckTypeIs(node, Type::Array());
666
      break;
667
    case IrOpcode::kJSCreateArrayIterator:
668 669
      CheckTypeIs(node, Type::OtherObject());
      break;
670 671 672
    case IrOpcode::kJSCreateAsyncFunctionObject:
      CheckTypeIs(node, Type::OtherObject());
      break;
673
    case IrOpcode::kJSCreateCollectionIterator:
674 675
      CheckTypeIs(node, Type::OtherObject());
      break;
676 677 678
    case IrOpcode::kJSCreateBoundFunction:
      CheckTypeIs(node, Type::BoundFunction());
      break;
679
    case IrOpcode::kJSCreateClosure:
680
      CheckTypeIs(node, Type::Function());
681
      break;
682
    case IrOpcode::kJSCreateIterResultObject:
683
      CheckTypeIs(node, Type::OtherObject());
684
      break;
685 686 687
    case IrOpcode::kJSCreateStringIterator:
      CheckTypeIs(node, Type::OtherObject());
      break;
688 689 690
    case IrOpcode::kJSCreateKeyValueArray:
      CheckTypeIs(node, Type::OtherObject());
      break;
691 692 693
    case IrOpcode::kJSCreateObject:
      CheckTypeIs(node, Type::OtherObject());
      break;
694 695 696
    case IrOpcode::kJSCreatePromise:
      CheckTypeIs(node, Type::OtherObject());
      break;
697 698 699
    case IrOpcode::kJSCreateTypedArray:
      CheckTypeIs(node, Type::OtherObject());
      break;
700
    case IrOpcode::kJSCreateLiteralArray:
701 702
      CheckTypeIs(node, Type::Array());
      break;
703 704 705
    case IrOpcode::kJSCreateEmptyLiteralArray:
      CheckTypeIs(node, Type::Array());
      break;
706 707 708
    case IrOpcode::kJSCreateArrayFromIterable:
      CheckTypeIs(node, Type::Array());
      break;
709
    case IrOpcode::kJSCreateLiteralObject:
710
    case IrOpcode::kJSCreateEmptyLiteralObject:
711
    case IrOpcode::kJSCloneObject:
712
    case IrOpcode::kJSCreateLiteralRegExp:
713
      CheckTypeIs(node, Type::OtherObject());
714
      break;
715 716 717
    case IrOpcode::kJSGetTemplateObject:
      CheckTypeIs(node, Type::Array());
      break;
718
    case IrOpcode::kJSLoadProperty:
719 720 721
      CheckTypeIs(node, Type::Any());
      CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
      break;
722
    case IrOpcode::kJSLoadNamed:
723 724
      CheckTypeIs(node, Type::Any());
      break;
725
    case IrOpcode::kJSLoadGlobal:
726
      CheckTypeIs(node, Type::Any());
727
      CHECK(LoadGlobalParametersOf(node->op()).feedback().IsValid());
728 729
      break;
    case IrOpcode::kJSStoreProperty:
730 731 732
      CheckNotTyped(node);
      CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
      break;
733
    case IrOpcode::kJSStoreNamed:
734 735
      CheckNotTyped(node);
      break;
736
    case IrOpcode::kJSStoreGlobal:
737 738 739
      CheckNotTyped(node);
      CHECK(StoreGlobalParametersOf(node->op()).feedback().IsValid());
      break;
740 741 742 743
    case IrOpcode::kJSStoreNamedOwn:
      CheckNotTyped(node);
      CHECK(StoreNamedOwnParametersOf(node->op()).feedback().IsValid());
      break;
744 745 746 747
    case IrOpcode::kJSGetIterator:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Any());
      break;
748
    case IrOpcode::kJSStoreDataPropertyInLiteral:
749
    case IrOpcode::kJSStoreInArrayLiteral:
750
      CheckNotTyped(node);
751
      CHECK(FeedbackParameterOf(node->op()).feedback().IsValid());
752 753 754
      break;
    case IrOpcode::kJSDeleteProperty:
    case IrOpcode::kJSHasProperty:
755
    case IrOpcode::kJSHasInPrototypeChain:
756
    case IrOpcode::kJSInstanceOf:
757
    case IrOpcode::kJSOrdinaryHasInstance:
758
      CheckTypeIs(node, Type::Boolean());
759
      break;
760
    case IrOpcode::kTypeOf:
761
      CheckTypeIs(node, Type::InternalizedString());
762
      break;
763 764 765 766
    case IrOpcode::kUpdateInterruptBudget:
      CheckValueInputIs(node, 0, Type::Any());
      CheckNotTyped(node);
      break;
767
    case IrOpcode::kJSGetSuperConstructor:
768 769
      // We don't check the input for Type::Function because this_function can
      // be context-allocated.
770 771 772
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Callable());
      break;
773

774 775 776
    case IrOpcode::kJSHasContextExtension:
      CheckTypeIs(node, Type::Boolean());
      break;
777
    case IrOpcode::kJSLoadContext:
778
      CheckTypeIs(node, Type::Any());
779 780 781 782 783 784 785
      break;
    case IrOpcode::kJSStoreContext:
      CheckNotTyped(node);
      break;
    case IrOpcode::kJSCreateFunctionContext:
    case IrOpcode::kJSCreateCatchContext:
    case IrOpcode::kJSCreateWithContext:
786
    case IrOpcode::kJSCreateBlockContext: {
787
      CheckTypeIs(node, Type::OtherInternal());
788 789
      break;
    }
790

791
    case IrOpcode::kJSConstructForwardVarargs:
792
    case IrOpcode::kJSConstruct:
793
    case IrOpcode::kJSConstructWithArrayLike:
794
    case IrOpcode::kJSConstructWithSpread:
795
      CheckTypeIs(node, Type::Receiver());
796
      break;
797
    case IrOpcode::kJSCallForwardVarargs:
798
    case IrOpcode::kJSCall:
799
    case IrOpcode::kJSCallWithArrayLike:
800
    case IrOpcode::kJSCallWithSpread:
801
    case IrOpcode::kJSCallRuntime:
802
      CheckTypeIs(node, Type::Any());
803 804
      break;

805 806 807 808 809
    case IrOpcode::kJSForInEnumerate:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::OtherInternal());
      break;
    case IrOpcode::kJSForInPrepare:
810
      CheckTypeIs(node, Type::Any());
811
      break;
812
    case IrOpcode::kJSForInNext:
813
      CheckTypeIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
814 815
      break;

816 817 818 819
    case IrOpcode::kJSLoadMessage:
    case IrOpcode::kJSStoreMessage:
      break;

820 821 822 823 824 825 826
    case IrOpcode::kJSLoadModule:
      CheckTypeIs(node, Type::Any());
      break;
    case IrOpcode::kJSStoreModule:
      CheckNotTyped(node);
      break;

827 828 829 830
    case IrOpcode::kJSGetImportMeta:
      CheckTypeIs(node, Type::Any());
      break;

831 832 833 834
    case IrOpcode::kJSGeneratorStore:
      CheckNotTyped(node);
      break;

835 836 837 838
    case IrOpcode::kJSCreateGeneratorObject:
      CheckTypeIs(node, Type::OtherObject());
      break;

839
    case IrOpcode::kJSGeneratorRestoreContinuation:
840
      CheckTypeIs(node, Type::SignedSmall());
841 842
      break;

843 844 845 846
    case IrOpcode::kJSGeneratorRestoreContext:
      CheckTypeIs(node, Type::Any());
      break;

847
    case IrOpcode::kJSGeneratorRestoreRegister:
848
      CheckTypeIs(node, Type::Any());
849 850
      break;

851 852 853 854
    case IrOpcode::kJSGeneratorRestoreInputOrDebugPos:
      CheckTypeIs(node, Type::Any());
      break;

855
    case IrOpcode::kJSStackCheck:
856
    case IrOpcode::kJSDebugger:
857 858 859
      CheckNotTyped(node);
      break;

860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
    case IrOpcode::kJSAsyncFunctionEnter:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::OtherObject());
      break;
    case IrOpcode::kJSAsyncFunctionReject:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckValueInputIs(node, 2, Type::Boolean());
      CheckTypeIs(node, Type::OtherObject());
      break;
    case IrOpcode::kJSAsyncFunctionResolve:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckValueInputIs(node, 2, Type::Boolean());
      CheckTypeIs(node, Type::OtherObject());
      break;
877 878 879 880 881
    case IrOpcode::kJSFulfillPromise:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Undefined());
      break;
882 883 884 885 886
    case IrOpcode::kJSPerformPromiseThen:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckValueInputIs(node, 2, Type::Any());
      CheckValueInputIs(node, 3, Type::Any());
887 888 889 890 891 892
      CheckTypeIs(node, Type::Receiver());
      break;
    case IrOpcode::kJSPromiseResolve:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Receiver());
893
      break;
894 895 896 897 898 899 900 901 902 903 904
    case IrOpcode::kJSRejectPromise:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckValueInputIs(node, 2, Type::Any());
      CheckTypeIs(node, Type::Undefined());
      break;
    case IrOpcode::kJSResolvePromise:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Undefined());
      break;
905 906 907 908
    case IrOpcode::kJSObjectIsArray:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Boolean());
      break;
909

910
    case IrOpcode::kComment:
911
    case IrOpcode::kAbortCSAAssert:
912 913 914
    case IrOpcode::kDebugBreak:
    case IrOpcode::kRetain:
    case IrOpcode::kUnsafePointerAdd:
915
    case IrOpcode::kRuntimeAbort:
916 917 918
      CheckNotTyped(node);
      break;

919 920 921 922
    // Simplified operators
    // -------------------------------
    case IrOpcode::kBooleanNot:
      CheckValueInputIs(node, 0, Type::Boolean());
923
      CheckTypeIs(node, Type::Boolean());
924 925
      break;
    case IrOpcode::kNumberEqual:
926 927
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
928
      CheckTypeIs(node, Type::Boolean());
929
      break;
930 931
    case IrOpcode::kNumberLessThan:
    case IrOpcode::kNumberLessThanOrEqual:
932 933
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
934
      CheckTypeIs(node, Type::Boolean());
935
      break;
936 937
    case IrOpcode::kSpeculativeSafeIntegerAdd:
    case IrOpcode::kSpeculativeSafeIntegerSubtract:
938 939
    case IrOpcode::kSpeculativeNumberAdd:
    case IrOpcode::kSpeculativeNumberSubtract:
940 941 942
    case IrOpcode::kSpeculativeNumberMultiply:
    case IrOpcode::kSpeculativeNumberDivide:
    case IrOpcode::kSpeculativeNumberModulus:
943
      CheckTypeIs(node, Type::Number());
944 945 946 947
      break;
    case IrOpcode::kSpeculativeNumberEqual:
    case IrOpcode::kSpeculativeNumberLessThan:
    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
948
      CheckTypeIs(node, Type::Boolean());
949
      break;
950
    case IrOpcode::kSpeculativeBigIntAdd:
951
    case IrOpcode::kSpeculativeBigIntSubtract:
952 953
      CheckTypeIs(node, Type::BigInt());
      break;
954 955 956
    case IrOpcode::kSpeculativeBigIntNegate:
      CheckTypeIs(node, Type::BigInt());
      break;
957 958 959 960
    case IrOpcode::kBigIntAsUintN:
      CheckValueInputIs(node, 0, Type::BigInt());
      CheckTypeIs(node, Type::BigInt());
      break;
961
    case IrOpcode::kBigIntAdd:
962
    case IrOpcode::kBigIntSubtract:
963 964 965 966 967 968 969 970
      CheckValueInputIs(node, 0, Type::BigInt());
      CheckValueInputIs(node, 1, Type::BigInt());
      CheckTypeIs(node, Type::BigInt());
      break;
    case IrOpcode::kBigIntNegate:
      CheckValueInputIs(node, 0, Type::BigInt());
      CheckTypeIs(node, Type::BigInt());
      break;
971 972 973 974
    case IrOpcode::kNumberAdd:
    case IrOpcode::kNumberSubtract:
    case IrOpcode::kNumberMultiply:
    case IrOpcode::kNumberDivide:
975 976
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
977
      CheckTypeIs(node, Type::Number());
978
      break;
979 980 981
    case IrOpcode::kNumberModulus:
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
982
      CheckTypeIs(node, Type::Number());
983
      break;
984 985 986 987 988
    case IrOpcode::kNumberBitwiseOr:
    case IrOpcode::kNumberBitwiseXor:
    case IrOpcode::kNumberBitwiseAnd:
      CheckValueInputIs(node, 0, Type::Signed32());
      CheckValueInputIs(node, 1, Type::Signed32());
989
      CheckTypeIs(node, Type::Signed32());
990
      break;
991 992 993
    case IrOpcode::kSpeculativeNumberBitwiseOr:
    case IrOpcode::kSpeculativeNumberBitwiseXor:
    case IrOpcode::kSpeculativeNumberBitwiseAnd:
994
      CheckTypeIs(node, Type::Signed32());
995
      break;
996 997 998 999
    case IrOpcode::kNumberShiftLeft:
    case IrOpcode::kNumberShiftRight:
      CheckValueInputIs(node, 0, Type::Signed32());
      CheckValueInputIs(node, 1, Type::Unsigned32());
1000
      CheckTypeIs(node, Type::Signed32());
1001
      break;
1002
    case IrOpcode::kSpeculativeNumberShiftLeft:
1003
    case IrOpcode::kSpeculativeNumberShiftRight:
1004
      CheckTypeIs(node, Type::Signed32());
1005
      break;
1006 1007 1008
    case IrOpcode::kNumberShiftRightLogical:
      CheckValueInputIs(node, 0, Type::Unsigned32());
      CheckValueInputIs(node, 1, Type::Unsigned32());
1009
      CheckTypeIs(node, Type::Unsigned32());
1010
      break;
1011
    case IrOpcode::kSpeculativeNumberShiftRightLogical:
1012
      CheckTypeIs(node, Type::Unsigned32());
1013
      break;
1014 1015 1016
    case IrOpcode::kNumberImul:
      CheckValueInputIs(node, 0, Type::Unsigned32());
      CheckValueInputIs(node, 1, Type::Unsigned32());
1017
      CheckTypeIs(node, Type::Signed32());
1018
      break;
1019 1020
    case IrOpcode::kNumberClz32:
      CheckValueInputIs(node, 0, Type::Unsigned32());
1021
      CheckTypeIs(node, Type::Unsigned32());
1022
      break;
1023
    case IrOpcode::kNumberAtan2:
1024 1025
    case IrOpcode::kNumberMax:
    case IrOpcode::kNumberMin:
1026
    case IrOpcode::kNumberPow:
1027 1028
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
1029
      CheckTypeIs(node, Type::Number());
1030
      break;
1031
    case IrOpcode::kNumberAbs:
1032
    case IrOpcode::kNumberCeil:
1033
    case IrOpcode::kNumberFloor:
1034
    case IrOpcode::kNumberFround:
1035 1036 1037 1038
    case IrOpcode::kNumberAcos:
    case IrOpcode::kNumberAcosh:
    case IrOpcode::kNumberAsin:
    case IrOpcode::kNumberAsinh:
1039
    case IrOpcode::kNumberAtan:
1040
    case IrOpcode::kNumberAtanh:
1041
    case IrOpcode::kNumberCos:
1042
    case IrOpcode::kNumberCosh:
1043
    case IrOpcode::kNumberExp:
1044
    case IrOpcode::kNumberExpm1:
1045
    case IrOpcode::kNumberLog:
1046
    case IrOpcode::kNumberLog1p:
1047 1048
    case IrOpcode::kNumberLog2:
    case IrOpcode::kNumberLog10:
1049
    case IrOpcode::kNumberCbrt:
1050
    case IrOpcode::kNumberRound:
1051
    case IrOpcode::kNumberSign:
1052
    case IrOpcode::kNumberSin:
1053
    case IrOpcode::kNumberSinh:
1054
    case IrOpcode::kNumberSqrt:
1055
    case IrOpcode::kNumberTan:
1056
    case IrOpcode::kNumberTanh:
1057
    case IrOpcode::kNumberTrunc:
1058
      CheckValueInputIs(node, 0, Type::Number());
1059
      CheckTypeIs(node, Type::Number());
1060
      break;
1061 1062 1063 1064
    case IrOpcode::kNumberToBoolean:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1065
    case IrOpcode::kNumberToInt32:
1066
      CheckValueInputIs(node, 0, Type::Number());
1067
      CheckTypeIs(node, Type::Signed32());
1068
      break;
1069 1070 1071 1072
    case IrOpcode::kNumberToString:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::String());
      break;
1073
    case IrOpcode::kNumberToUint32:
1074
    case IrOpcode::kNumberToUint8Clamped:
1075
      CheckValueInputIs(node, 0, Type::Number());
1076
      CheckTypeIs(node, Type::Unsigned32());
1077
      break;
1078 1079 1080 1081
    case IrOpcode::kSpeculativeToNumber:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Number());
      break;
1082
    case IrOpcode::kPlainPrimitiveToNumber:
1083
      CheckValueInputIs(node, 0, Type::PlainPrimitive());
1084
      CheckTypeIs(node, Type::Number());
1085 1086
      break;
    case IrOpcode::kPlainPrimitiveToWord32:
1087
      CheckValueInputIs(node, 0, Type::PlainPrimitive());
1088
      CheckTypeIs(node, Type::Integral32());
1089 1090
      break;
    case IrOpcode::kPlainPrimitiveToFloat64:
1091
      CheckValueInputIs(node, 0, Type::PlainPrimitive());
1092
      CheckTypeIs(node, Type::Number());
1093
      break;
1094
    case IrOpcode::kStringConcat:
1095
      CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1096 1097 1098 1099
      CheckValueInputIs(node, 1, Type::String());
      CheckValueInputIs(node, 2, Type::String());
      CheckTypeIs(node, Type::String());
      break;
1100 1101 1102 1103 1104
    case IrOpcode::kStringEqual:
    case IrOpcode::kStringLessThan:
    case IrOpcode::kStringLessThanOrEqual:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::String());
1105
      CheckTypeIs(node, Type::Boolean());
1106
      break;
1107 1108 1109 1110
    case IrOpcode::kStringToNumber:
      CheckValueInputIs(node, 0, Type::String());
      CheckTypeIs(node, Type::Number());
      break;
1111 1112 1113
    case IrOpcode::kStringCharCodeAt:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::Unsigned32());
1114
      CheckTypeIs(node, Type::UnsignedSmall());
1115
      break;
1116 1117 1118 1119 1120
    case IrOpcode::kStringCodePointAt:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::Unsigned32());
      CheckTypeIs(node, Type::UnsignedSmall());
      break;
1121
    case IrOpcode::kStringFromSingleCharCode:
1122
      CheckValueInputIs(node, 0, Type::Number());
1123
      CheckTypeIs(node, Type::String());
1124
      break;
1125
    case IrOpcode::kStringFromSingleCodePoint:
1126 1127 1128
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::String());
      break;
1129 1130 1131 1132 1133
    case IrOpcode::kStringFromCodePointAt:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::Unsigned32());
      CheckTypeIs(node, Type::String());
      break;
1134 1135 1136 1137 1138 1139
    case IrOpcode::kStringIndexOf:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::String());
      CheckValueInputIs(node, 2, Type::SignedSmall());
      CheckTypeIs(node, Type::SignedSmall());
      break;
1140 1141
    case IrOpcode::kStringLength:
      CheckValueInputIs(node, 0, Type::String());
1142
      CheckTypeIs(node, TypeCache::Get()->kStringLengthType);
1143
      break;
1144 1145 1146 1147 1148
    case IrOpcode::kStringToLowerCaseIntl:
    case IrOpcode::kStringToUpperCaseIntl:
      CheckValueInputIs(node, 0, Type::String());
      CheckTypeIs(node, Type::String());
      break;
1149 1150 1151 1152 1153 1154
    case IrOpcode::kStringSubstring:
      CheckValueInputIs(node, 0, Type::String());
      CheckValueInputIs(node, 1, Type::SignedSmall());
      CheckValueInputIs(node, 2, Type::SignedSmall());
      CheckTypeIs(node, Type::String());
      break;
1155
    case IrOpcode::kReferenceEqual:
1156
      CheckTypeIs(node, Type::Boolean());
1157
      break;
1158
    case IrOpcode::kSameValue:
1159
    case IrOpcode::kSameValueNumbersOnly:
1160 1161 1162 1163
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Boolean());
      break;
1164 1165 1166 1167 1168
    case IrOpcode::kNumberSameValue:
      CheckValueInputIs(node, 0, Type::Number());
      CheckValueInputIs(node, 1, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1169
    case IrOpcode::kObjectIsArrayBufferView:
1170
    case IrOpcode::kObjectIsBigInt:
1171
    case IrOpcode::kObjectIsCallable:
1172
    case IrOpcode::kObjectIsConstructor:
1173
    case IrOpcode::kObjectIsDetectableCallable:
1174
    case IrOpcode::kObjectIsMinusZero:
1175
    case IrOpcode::kObjectIsNaN:
1176
    case IrOpcode::kObjectIsNonCallable:
1177
    case IrOpcode::kObjectIsNumber:
1178
    case IrOpcode::kObjectIsReceiver:
1179
    case IrOpcode::kObjectIsSmi:
1180
    case IrOpcode::kObjectIsString:
1181
    case IrOpcode::kObjectIsSymbol:
1182
    case IrOpcode::kObjectIsUndetectable:
1183
      CheckValueInputIs(node, 0, Type::Any());
1184
      CheckTypeIs(node, Type::Boolean());
1185
      break;
1186 1187
    case IrOpcode::kNumberIsFloat64Hole:
      CheckValueInputIs(node, 0, Type::NumberOrHole());
1188 1189 1190 1191 1192 1193
      CheckTypeIs(node, Type::Boolean());
      break;
    case IrOpcode::kNumberIsFinite:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1194
    case IrOpcode::kNumberIsMinusZero:
1195 1196 1197 1198
    case IrOpcode::kNumberIsNaN:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1199 1200
    case IrOpcode::kObjectIsFiniteNumber:
      CheckValueInputIs(node, 0, Type::Any());
1201 1202 1203 1204 1205 1206
      CheckTypeIs(node, Type::Boolean());
      break;
    case IrOpcode::kNumberIsInteger:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1207 1208 1209 1210 1211 1212 1213 1214
    case IrOpcode::kObjectIsSafeInteger:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Boolean());
      break;
    case IrOpcode::kNumberIsSafeInteger:
      CheckValueInputIs(node, 0, Type::Number());
      CheckTypeIs(node, Type::Boolean());
      break;
1215 1216
    case IrOpcode::kObjectIsInteger:
      CheckValueInputIs(node, 0, Type::Any());
1217 1218
      CheckTypeIs(node, Type::Boolean());
      break;
1219
    case IrOpcode::kFindOrderedHashMapEntry:
1220 1221 1222
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::SignedSmall());
      break;
1223
    case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
1224
      CheckValueInputIs(node, 0, Type::Any());
1225
      CheckValueInputIs(node, 1, Type::Signed32());
1226 1227
      CheckTypeIs(node, Type::SignedSmall());
      break;
1228
    case IrOpcode::kArgumentsLength:
1229
    case IrOpcode::kRestLength:
1230
      CheckValueInputIs(node, 0, Type::ExternalPointer());
1231
      CheckTypeIs(node, TypeCache::Get()->kArgumentsLengthType);
1232 1233 1234 1235
      break;
    case IrOpcode::kArgumentsFrame:
      CheckTypeIs(node, Type::ExternalPointer());
      break;
1236 1237
    case IrOpcode::kNewDoubleElements:
    case IrOpcode::kNewSmiOrObjectElements:
1238 1239 1240 1241
      CheckValueInputIs(node, 0,
                        Type::Range(0.0, FixedArray::kMaxLength, zone));
      CheckTypeIs(node, Type::OtherInternal());
      break;
1242
    case IrOpcode::kNewArgumentsElements:
1243
      CheckValueInputIs(node, 0, Type::ExternalPointer());
1244 1245
      CheckValueInputIs(node, 1,
                        Type::Range(0.0, FixedArray::kMaxLength, zone));
1246 1247
      CheckTypeIs(node, Type::OtherInternal());
      break;
1248
    case IrOpcode::kNewConsString:
1249 1250 1251 1252
      CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
      CheckValueInputIs(node, 1, Type::String());
      CheckValueInputIs(node, 2, Type::String());
      CheckTypeIs(node, Type::String());
1253
      break;
1254 1255 1256
    case IrOpcode::kDelayedStringConstant:
      CheckTypeIs(node, Type::String());
      break;
1257 1258 1259
    case IrOpcode::kAllocate:
      CheckValueInputIs(node, 0, Type::PlainNumber());
      break;
1260 1261 1262
    case IrOpcode::kAllocateRaw:
      // CheckValueInputIs(node, 0, Type::PlainNumber());
      break;
1263 1264 1265
    case IrOpcode::kEnsureWritableFastElements:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Internal());
1266
      CheckTypeIs(node, Type::Internal());
1267
      break;
1268 1269 1270 1271 1272
    case IrOpcode::kMaybeGrowFastElements:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Internal());
      CheckValueInputIs(node, 2, Type::Unsigned31());
      CheckValueInputIs(node, 3, Type::Unsigned31());
1273
      CheckTypeIs(node, Type::Internal());
1274
      break;
1275 1276 1277 1278
    case IrOpcode::kTransitionElementsKind:
      CheckValueInputIs(node, 0, Type::Any());
      CheckNotTyped(node);
      break;
1279

1280
    case IrOpcode::kChangeTaggedSignedToInt32: {
1281 1282
      // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1283 1284
      // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
      // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1285
      // CheckValueInputIs(node, 0, from));
1286
      // CheckTypeIs(node, to));
1287 1288
      break;
    }
1289 1290
    case IrOpcode::kChangeTaggedSignedToInt64:
      break;
1291 1292 1293
    case IrOpcode::kChangeTaggedToInt32: {
      // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1294 1295
      // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
      // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1296
      // CheckValueInputIs(node, 0, from));
1297
      // CheckTypeIs(node, to));
1298 1299
      break;
    }
1300 1301
    case IrOpcode::kChangeTaggedToInt64:
      break;
1302 1303 1304
    case IrOpcode::kChangeTaggedToUint32: {
      // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1305 1306
      // Type from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
      // Type to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
1307
      // CheckValueInputIs(node, 0, from));
1308
      // CheckTypeIs(node, to));
1309 1310 1311
      break;
    }
    case IrOpcode::kChangeTaggedToFloat64: {
1312
      // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1313
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1314 1315
      // Type from = Type::Intersect(Type::Number(), Type::Tagged());
      // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1316
      // CheckValueInputIs(node, 0, from));
1317
      // CheckTypeIs(node, to));
1318 1319
      break;
    }
1320
    case IrOpcode::kChangeTaggedToTaggedSigned:      // Fall through.
1321
      break;
1322 1323 1324
    case IrOpcode::kTruncateTaggedToFloat64: {
      // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1325
      // Type from = Type::Intersect(Type::NumberOrUndefined(),
1326
      // Type::Tagged());
1327
      // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1328
      // CheckValueInputIs(node, 0, from));
1329
      // CheckTypeIs(node, to));
1330 1331
      break;
    }
1332
    case IrOpcode::kChangeInt31ToTaggedSigned: {
1333 1334
      // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1335 1336
      // Type from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
      // Type to = Type::Intersect(Type::Signed31(), Type::Tagged());
1337
      // CheckValueInputIs(node, 0, from));
1338
      // CheckTypeIs(node, to));
1339 1340
      break;
    }
1341 1342 1343
    case IrOpcode::kChangeInt32ToTagged: {
      // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1344 1345
      // Type from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
      // Type to = Type::Intersect(Type::Signed32(), Type::Tagged());
1346
      // CheckValueInputIs(node, 0, from));
1347
      // CheckTypeIs(node, to));
1348 1349
      break;
    }
1350 1351
    case IrOpcode::kChangeInt64ToTagged:
      break;
1352 1353 1354
    case IrOpcode::kChangeUint32ToTagged: {
      // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1355 1356
      // Type from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
      // Type to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1357
      // CheckValueInputIs(node, 0, from));
1358
      // CheckTypeIs(node, to));
1359 1360
      break;
    }
1361 1362
    case IrOpcode::kChangeUint64ToTagged:
      break;
1363 1364 1365
    case IrOpcode::kChangeFloat64ToTagged: {
      // Number /\ UntaggedFloat64 -> Number /\ Tagged
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1366 1367
      // Type from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
      // Type to = Type::Intersect(Type::Number(), Type::Tagged());
1368
      // CheckValueInputIs(node, 0, from));
1369
      // CheckTypeIs(node, to));
1370 1371
      break;
    }
1372 1373
    case IrOpcode::kChangeFloat64ToTaggedPointer:
      break;
1374
    case IrOpcode::kChangeTaggedToBit: {
1375 1376
      // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1377 1378
      // Type from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
      // Type to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1379
      // CheckValueInputIs(node, 0, from));
1380
      // CheckTypeIs(node, to));
1381 1382
      break;
    }
1383
    case IrOpcode::kChangeBitToTagged: {
1384 1385
      // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1386 1387
      // Type from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
      // Type to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1388
      // CheckValueInputIs(node, 0, from));
1389
      // CheckTypeIs(node, to));
1390 1391
      break;
    }
1392 1393 1394
    case IrOpcode::kTruncateTaggedToWord32: {
      // Number /\ Tagged -> Signed32 /\ UntaggedInt32
      // TODO(neis): Activate once ChangeRepresentation works in typer.
1395 1396
      // Type from = Type::Intersect(Type::Number(), Type::Tagged());
      // Type to = Type::Intersect(Type::Number(), Type::UntaggedInt32());
1397
      // CheckValueInputIs(node, 0, from));
1398
      // CheckTypeIs(node, to));
1399 1400
      break;
    }
1401 1402 1403 1404 1405 1406 1407 1408
    case IrOpcode::kTruncateBigIntToUint64:
      CheckValueInputIs(node, 0, Type::BigInt());
      CheckTypeIs(node, Type::BigInt());
      break;
    case IrOpcode::kChangeUint64ToBigInt:
      CheckValueInputIs(node, 0, Type::BigInt());
      CheckTypeIs(node, Type::BigInt());
      break;
1409
    case IrOpcode::kTruncateTaggedToBit:
1410
    case IrOpcode::kTruncateTaggedPointerToBit:
1411 1412
      break;

1413 1414
    case IrOpcode::kCheckBounds:
      CheckValueInputIs(node, 0, Type::Any());
1415 1416
      CheckValueInputIs(node, 1, TypeCache::Get()->kPositiveSafeInteger);
      CheckTypeIs(node, TypeCache::Get()->kPositiveSafeInteger);
1417
      break;
1418
    case IrOpcode::kPoisonIndex:
1419 1420 1421
      CheckValueInputIs(node, 0, Type::Unsigned32());
      CheckTypeIs(node, Type::Unsigned32());
      break;
1422 1423 1424 1425 1426
    case IrOpcode::kCheckClosure:
      // Any -> Function
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Function());
      break;
1427 1428 1429 1430 1431 1432 1433
    case IrOpcode::kCheckHeapObject:
      CheckValueInputIs(node, 0, Type::Any());
      break;
    case IrOpcode::kCheckIf:
      CheckValueInputIs(node, 0, Type::Boolean());
      CheckNotTyped(node);
      break;
1434 1435 1436 1437
    case IrOpcode::kCheckInternalizedString:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::InternalizedString());
      break;
1438 1439
    case IrOpcode::kCheckMaps:
      CheckValueInputIs(node, 0, Type::Any());
1440 1441
      CheckNotTyped(node);
      break;
1442 1443 1444 1445
    case IrOpcode::kDynamicCheckMaps:
      CheckValueInputIs(node, 0, Type::Any());
      CheckNotTyped(node);
      break;
1446 1447 1448 1449
    case IrOpcode::kCompareMaps:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Boolean());
      break;
1450 1451
    case IrOpcode::kCheckNumber:
      CheckValueInputIs(node, 0, Type::Any());
1452
      CheckTypeIs(node, Type::Number());
1453
      break;
1454 1455 1456 1457
    case IrOpcode::kCheckReceiver:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Receiver());
      break;
1458
    case IrOpcode::kCheckReceiverOrNullOrUndefined:
1459
      CheckValueInputIs(node, 0, Type::Any());
1460
      CheckTypeIs(node, Type::ReceiverOrNullOrUndefined());
1461
      break;
1462
    case IrOpcode::kCheckSmi:
1463 1464
      CheckValueInputIs(node, 0, Type::Any());
      break;
1465
    case IrOpcode::kCheckString:
1466
      CheckValueInputIs(node, 0, Type::Any());
1467
      CheckTypeIs(node, Type::String());
1468
      break;
1469 1470 1471
    case IrOpcode::kCheckSymbol:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::Symbol());
1472
      break;
1473 1474 1475 1476 1477 1478
    case IrOpcode::kConvertReceiver:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::Any());
      CheckTypeIs(node, Type::Receiver());
      break;

1479 1480
    case IrOpcode::kCheckedInt32Add:
    case IrOpcode::kCheckedInt32Sub:
1481 1482
    case IrOpcode::kCheckedInt32Div:
    case IrOpcode::kCheckedInt32Mod:
1483 1484
    case IrOpcode::kCheckedUint32Div:
    case IrOpcode::kCheckedUint32Mod:
1485
    case IrOpcode::kCheckedInt32Mul:
1486
    case IrOpcode::kCheckedInt32ToTaggedSigned:
1487 1488
    case IrOpcode::kCheckedInt64ToInt32:
    case IrOpcode::kCheckedInt64ToTaggedSigned:
1489
    case IrOpcode::kCheckedUint32Bounds:
1490
    case IrOpcode::kCheckedUint32ToInt32:
1491
    case IrOpcode::kCheckedUint32ToTaggedSigned:
1492
    case IrOpcode::kCheckedUint64Bounds:
1493 1494
    case IrOpcode::kCheckedUint64ToInt32:
    case IrOpcode::kCheckedUint64ToTaggedSigned:
1495
    case IrOpcode::kCheckedFloat64ToInt32:
1496
    case IrOpcode::kCheckedFloat64ToInt64:
1497
    case IrOpcode::kCheckedTaggedSignedToInt32:
1498
    case IrOpcode::kCheckedTaggedToInt32:
1499
    case IrOpcode::kCheckedTaggedToArrayIndex:
1500
    case IrOpcode::kCheckedTaggedToInt64:
1501
    case IrOpcode::kCheckedTaggedToFloat64:
1502
    case IrOpcode::kCheckedTaggedToTaggedSigned:
1503
    case IrOpcode::kCheckedTaggedToTaggedPointer:
1504
    case IrOpcode::kCheckedTruncateTaggedToWord32:
1505
    case IrOpcode::kAssertType:
1506 1507
      break;

1508
    case IrOpcode::kCheckFloat64Hole:
1509 1510
      CheckValueInputIs(node, 0, Type::NumberOrHole());
      CheckTypeIs(node, Type::NumberOrUndefined());
1511
      break;
1512 1513
    case IrOpcode::kCheckNotTaggedHole:
      CheckValueInputIs(node, 0, Type::Any());
1514
      CheckTypeIs(node, Type::NonInternal());
1515 1516 1517
      break;
    case IrOpcode::kConvertTaggedHoleToUndefined:
      CheckValueInputIs(node, 0, Type::Any());
1518
      CheckTypeIs(node, Type::NonInternal());
1519 1520
      break;

1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
    case IrOpcode::kCheckEqualsInternalizedString:
      CheckValueInputIs(node, 0, Type::InternalizedString());
      CheckValueInputIs(node, 1, Type::Any());
      CheckNotTyped(node);
      break;
    case IrOpcode::kCheckEqualsSymbol:
      CheckValueInputIs(node, 0, Type::Symbol());
      CheckValueInputIs(node, 1, Type::Any());
      CheckNotTyped(node);
      break;

1532 1533 1534 1535 1536
    case IrOpcode::kLoadFieldByIndex:
      CheckValueInputIs(node, 0, Type::Any());
      CheckValueInputIs(node, 1, Type::SignedSmall());
      CheckTypeIs(node, Type::NonInternal());
      break;
1537
    case IrOpcode::kLoadField:
1538
    case IrOpcode::kLoadMessage:
1539 1540 1541
      // Object -> fieldtype
      // TODO(rossberg): activate once machine ops are typed.
      // CheckValueInputIs(node, 0, Type::Object());
1542
      // CheckTypeIs(node, FieldAccessOf(node->op()).type);
1543 1544
      break;
    case IrOpcode::kLoadElement:
1545
    case IrOpcode::kLoadStackArgument:
1546 1547 1548
      // Object -> elementtype
      // TODO(rossberg): activate once machine ops are typed.
      // CheckValueInputIs(node, 0, Type::Object());
1549
      // CheckTypeIs(node, ElementAccessOf(node->op()).type));
1550
      break;
1551
    case IrOpcode::kLoadFromObject:
1552
      CheckValueInputIs(node, 0, Type::Receiver());
1553
      break;
1554 1555
    case IrOpcode::kLoadTypedElement:
      break;
1556 1557
    case IrOpcode::kLoadDataViewElement:
      break;
1558
    case IrOpcode::kStoreField:
1559
    case IrOpcode::kStoreMessage:
1560 1561 1562
      // (Object, fieldtype) -> _|_
      // TODO(rossberg): activate once machine ops are typed.
      // CheckValueInputIs(node, 0, Type::Object());
1563
      // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
1564 1565 1566 1567 1568 1569
      CheckNotTyped(node);
      break;
    case IrOpcode::kStoreElement:
      // (Object, elementtype) -> _|_
      // TODO(rossberg): activate once machine ops are typed.
      // CheckValueInputIs(node, 0, Type::Object());
1570
      // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
1571 1572
      CheckNotTyped(node);
      break;
1573 1574 1575
    case IrOpcode::kStoreToObject:
      // TODO(gsps): Can we check some types here?
      break;
1576 1577 1578
    case IrOpcode::kTransitionAndStoreElement:
      CheckNotTyped(node);
      break;
1579 1580 1581 1582 1583 1584
    case IrOpcode::kTransitionAndStoreNumberElement:
      CheckNotTyped(node);
      break;
    case IrOpcode::kTransitionAndStoreNonNumberElement:
      CheckNotTyped(node);
      break;
1585 1586 1587
    case IrOpcode::kStoreSignedSmallElement:
      CheckNotTyped(node);
      break;
1588 1589 1590
    case IrOpcode::kStoreTypedElement:
      CheckNotTyped(node);
      break;
1591 1592 1593
    case IrOpcode::kStoreDataViewElement:
      CheckNotTyped(node);
      break;
1594
    case IrOpcode::kNumberSilenceNaN:
1595
      CheckValueInputIs(node, 0, Type::Number());
1596
      CheckTypeIs(node, Type::Number());
1597
      break;
1598 1599 1600
    case IrOpcode::kMapGuard:
      CheckNotTyped(node);
      break;
1601
    case IrOpcode::kTypeGuard:
1602
      CheckTypeIs(node, TypeGuardTypeOf(node->op()));
1603
      break;
1604 1605 1606 1607
    case IrOpcode::kFoldConstant:
      if (typing == TYPED) {
        Type type = NodeProperties::GetType(node);
        CHECK(type.IsSingleton());
1608
        CHECK(type.Equals(NodeProperties::GetType(node->InputAt(0))));
1609 1610 1611
        CHECK(type.Equals(NodeProperties::GetType(node->InputAt(1))));
      }
      break;
1612 1613 1614 1615
    case IrOpcode::kDateNow:
      CHECK_EQ(0, value_count);
      CheckTypeIs(node, Type::Number());
      break;
1616 1617 1618
    case IrOpcode::kCheckBigInt:
      CheckValueInputIs(node, 0, Type::Any());
      CheckTypeIs(node, Type::BigInt());
1619 1620
      break;
    case IrOpcode::kFastApiCall:
1621 1622 1623
      CHECK_GE(value_count, 2);
      CheckValueInputIs(node, 0, Type::ExternalPointer());  // callee
      CheckValueInputIs(node, 1, Type::Any());              // receiver
1624
      break;
1625 1626 1627 1628

    // Machine operators
    // -----------------------
    case IrOpcode::kLoad:
1629
    case IrOpcode::kPoisonedLoad:
1630
    case IrOpcode::kProtectedLoad:
1631
    case IrOpcode::kProtectedStore:
1632
    case IrOpcode::kStore:
1633
    case IrOpcode::kStackSlot:
1634 1635 1636 1637 1638 1639
    case IrOpcode::kWord32And:
    case IrOpcode::kWord32Or:
    case IrOpcode::kWord32Xor:
    case IrOpcode::kWord32Shl:
    case IrOpcode::kWord32Shr:
    case IrOpcode::kWord32Sar:
1640
    case IrOpcode::kWord32Rol:
1641 1642
    case IrOpcode::kWord32Ror:
    case IrOpcode::kWord32Equal:
1643
    case IrOpcode::kWord32Clz:
1644
    case IrOpcode::kWord32Ctz:
1645
    case IrOpcode::kWord32ReverseBits:
1646
    case IrOpcode::kWord32ReverseBytes:
1647
    case IrOpcode::kInt32AbsWithOverflow:
1648
    case IrOpcode::kWord32Popcnt:
1649 1650 1651 1652 1653 1654
    case IrOpcode::kWord64And:
    case IrOpcode::kWord64Or:
    case IrOpcode::kWord64Xor:
    case IrOpcode::kWord64Shl:
    case IrOpcode::kWord64Shr:
    case IrOpcode::kWord64Sar:
1655
    case IrOpcode::kWord64Rol:
1656
    case IrOpcode::kWord64Ror:
1657
    case IrOpcode::kWord64Clz:
1658
    case IrOpcode::kWord64Popcnt:
1659
    case IrOpcode::kWord64Ctz:
1660
    case IrOpcode::kWord64ReverseBits:
1661
    case IrOpcode::kWord64ReverseBytes:
1662
    case IrOpcode::kSimd128ReverseBytes:
1663
    case IrOpcode::kInt64AbsWithOverflow:
1664 1665 1666 1667 1668 1669
    case IrOpcode::kWord64Equal:
    case IrOpcode::kInt32Add:
    case IrOpcode::kInt32AddWithOverflow:
    case IrOpcode::kInt32Sub:
    case IrOpcode::kInt32SubWithOverflow:
    case IrOpcode::kInt32Mul:
1670
    case IrOpcode::kInt32MulWithOverflow:
1671 1672 1673 1674 1675 1676 1677
    case IrOpcode::kInt32MulHigh:
    case IrOpcode::kInt32Div:
    case IrOpcode::kInt32Mod:
    case IrOpcode::kInt32LessThan:
    case IrOpcode::kInt32LessThanOrEqual:
    case IrOpcode::kUint32Div:
    case IrOpcode::kUint32Mod:
1678
    case IrOpcode::kUint32MulHigh:
1679 1680 1681
    case IrOpcode::kUint32LessThan:
    case IrOpcode::kUint32LessThanOrEqual:
    case IrOpcode::kInt64Add:
1682
    case IrOpcode::kInt64AddWithOverflow:
1683
    case IrOpcode::kInt64Sub:
1684
    case IrOpcode::kInt64SubWithOverflow:
1685 1686 1687 1688 1689 1690 1691 1692
    case IrOpcode::kInt64Mul:
    case IrOpcode::kInt64Div:
    case IrOpcode::kInt64Mod:
    case IrOpcode::kInt64LessThan:
    case IrOpcode::kInt64LessThanOrEqual:
    case IrOpcode::kUint64Div:
    case IrOpcode::kUint64Mod:
    case IrOpcode::kUint64LessThan:
1693
    case IrOpcode::kUint64LessThanOrEqual:
1694 1695
    case IrOpcode::kFloat32Add:
    case IrOpcode::kFloat32Sub:
1696
    case IrOpcode::kFloat32Neg:
1697 1698
    case IrOpcode::kFloat32Mul:
    case IrOpcode::kFloat32Div:
1699
    case IrOpcode::kFloat32Abs:
1700 1701 1702 1703
    case IrOpcode::kFloat32Sqrt:
    case IrOpcode::kFloat32Equal:
    case IrOpcode::kFloat32LessThan:
    case IrOpcode::kFloat32LessThanOrEqual:
1704 1705
    case IrOpcode::kFloat32Max:
    case IrOpcode::kFloat32Min:
1706 1707
    case IrOpcode::kFloat64Add:
    case IrOpcode::kFloat64Sub:
1708
    case IrOpcode::kFloat64Neg:
1709 1710 1711
    case IrOpcode::kFloat64Mul:
    case IrOpcode::kFloat64Div:
    case IrOpcode::kFloat64Mod:
1712 1713
    case IrOpcode::kFloat64Max:
    case IrOpcode::kFloat64Min:
1714
    case IrOpcode::kFloat64Abs:
1715 1716 1717 1718
    case IrOpcode::kFloat64Acos:
    case IrOpcode::kFloat64Acosh:
    case IrOpcode::kFloat64Asin:
    case IrOpcode::kFloat64Asinh:
1719 1720
    case IrOpcode::kFloat64Atan:
    case IrOpcode::kFloat64Atan2:
1721
    case IrOpcode::kFloat64Atanh:
1722
    case IrOpcode::kFloat64Cbrt:
1723
    case IrOpcode::kFloat64Cos:
1724
    case IrOpcode::kFloat64Cosh:
1725
    case IrOpcode::kFloat64Exp:
1726
    case IrOpcode::kFloat64Expm1:
1727
    case IrOpcode::kFloat64Log:
1728
    case IrOpcode::kFloat64Log1p:
1729
    case IrOpcode::kFloat64Log10:
1730 1731
    case IrOpcode::kFloat64Log2:
    case IrOpcode::kFloat64Pow:
1732
    case IrOpcode::kFloat64Sin:
1733
    case IrOpcode::kFloat64Sinh:
1734
    case IrOpcode::kFloat64Sqrt:
1735
    case IrOpcode::kFloat64Tan:
1736
    case IrOpcode::kFloat64Tanh:
1737
    case IrOpcode::kFloat32RoundDown:
1738
    case IrOpcode::kFloat64RoundDown:
1739
    case IrOpcode::kFloat32RoundUp:
1740
    case IrOpcode::kFloat64RoundUp:
1741
    case IrOpcode::kFloat32RoundTruncate:
1742 1743
    case IrOpcode::kFloat64RoundTruncate:
    case IrOpcode::kFloat64RoundTiesAway:
1744
    case IrOpcode::kFloat32RoundTiesEven:
1745
    case IrOpcode::kFloat64RoundTiesEven:
1746 1747 1748 1749
    case IrOpcode::kFloat64Equal:
    case IrOpcode::kFloat64LessThan:
    case IrOpcode::kFloat64LessThanOrEqual:
    case IrOpcode::kTruncateInt64ToInt32:
1750
    case IrOpcode::kRoundFloat64ToInt32:
1751
    case IrOpcode::kRoundInt32ToFloat32:
1752
    case IrOpcode::kRoundInt64ToFloat32:
1753
    case IrOpcode::kRoundInt64ToFloat64:
1754
    case IrOpcode::kRoundUint32ToFloat32:
1755
    case IrOpcode::kRoundUint64ToFloat64:
1756
    case IrOpcode::kRoundUint64ToFloat32:
1757
    case IrOpcode::kTruncateFloat64ToFloat32:
1758
    case IrOpcode::kTruncateFloat64ToWord32:
1759 1760 1761 1762
    case IrOpcode::kBitcastFloat32ToInt32:
    case IrOpcode::kBitcastFloat64ToInt64:
    case IrOpcode::kBitcastInt32ToFloat32:
    case IrOpcode::kBitcastInt64ToFloat64:
1763
    case IrOpcode::kBitcastTaggedToWord:
1764
    case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits:
1765
    case IrOpcode::kBitcastWordToTagged:
1766
    case IrOpcode::kBitcastWordToTaggedSigned:
1767
    case IrOpcode::kBitcastWord32ToWord64:
1768 1769 1770
    case IrOpcode::kChangeInt32ToInt64:
    case IrOpcode::kChangeUint32ToUint64:
    case IrOpcode::kChangeInt32ToFloat64:
1771
    case IrOpcode::kChangeInt64ToFloat64:
1772 1773 1774
    case IrOpcode::kChangeUint32ToFloat64:
    case IrOpcode::kChangeFloat32ToFloat64:
    case IrOpcode::kChangeFloat64ToInt32:
1775
    case IrOpcode::kChangeFloat64ToInt64:
1776
    case IrOpcode::kChangeFloat64ToUint32:
1777
    case IrOpcode::kChangeFloat64ToUint64:
1778
    case IrOpcode::kFloat64SilenceNaN:
1779
    case IrOpcode::kTruncateFloat64ToInt64:
1780
    case IrOpcode::kTruncateFloat64ToUint32:
1781
    case IrOpcode::kTruncateFloat32ToInt32:
1782
    case IrOpcode::kTruncateFloat32ToUint32:
1783
    case IrOpcode::kTryTruncateFloat32ToInt64:
1784
    case IrOpcode::kTryTruncateFloat64ToInt64:
1785
    case IrOpcode::kTryTruncateFloat32ToUint64:
1786
    case IrOpcode::kTryTruncateFloat64ToUint64:
1787 1788 1789 1790
    case IrOpcode::kFloat64ExtractLowWord32:
    case IrOpcode::kFloat64ExtractHighWord32:
    case IrOpcode::kFloat64InsertLowWord32:
    case IrOpcode::kFloat64InsertHighWord32:
1791
    case IrOpcode::kInt32PairAdd:
1792
    case IrOpcode::kInt32PairSub:
1793
    case IrOpcode::kInt32PairMul:
1794
    case IrOpcode::kWord32PairShl:
1795 1796
    case IrOpcode::kWord32PairShr:
    case IrOpcode::kWord32PairSar:
1797 1798 1799
    case IrOpcode::kTaggedPoisonOnSpeculation:
    case IrOpcode::kWord32PoisonOnSpeculation:
    case IrOpcode::kWord64PoisonOnSpeculation:
1800
    case IrOpcode::kLoadStackCheckOffset:
1801
    case IrOpcode::kLoadFramePointer:
1802
    case IrOpcode::kLoadParentFramePointer:
1803 1804
    case IrOpcode::kUnalignedLoad:
    case IrOpcode::kUnalignedStore:
1805
    case IrOpcode::kMemoryBarrier:
1806 1807 1808 1809 1810 1811 1812 1813 1814
    case IrOpcode::kWord32AtomicLoad:
    case IrOpcode::kWord32AtomicStore:
    case IrOpcode::kWord32AtomicExchange:
    case IrOpcode::kWord32AtomicCompareExchange:
    case IrOpcode::kWord32AtomicAdd:
    case IrOpcode::kWord32AtomicSub:
    case IrOpcode::kWord32AtomicAnd:
    case IrOpcode::kWord32AtomicOr:
    case IrOpcode::kWord32AtomicXor:
1815 1816
    case IrOpcode::kWord64AtomicLoad:
    case IrOpcode::kWord64AtomicStore:
1817 1818 1819 1820 1821
    case IrOpcode::kWord64AtomicAdd:
    case IrOpcode::kWord64AtomicSub:
    case IrOpcode::kWord64AtomicAnd:
    case IrOpcode::kWord64AtomicOr:
    case IrOpcode::kWord64AtomicXor:
1822 1823
    case IrOpcode::kWord64AtomicExchange:
    case IrOpcode::kWord64AtomicCompareExchange:
1824 1825
    case IrOpcode::kWord32AtomicPairLoad:
    case IrOpcode::kWord32AtomicPairStore:
1826 1827 1828 1829 1830
    case IrOpcode::kWord32AtomicPairAdd:
    case IrOpcode::kWord32AtomicPairSub:
    case IrOpcode::kWord32AtomicPairAnd:
    case IrOpcode::kWord32AtomicPairOr:
    case IrOpcode::kWord32AtomicPairXor:
1831 1832
    case IrOpcode::kWord32AtomicPairExchange:
    case IrOpcode::kWord32AtomicPairCompareExchange:
1833 1834 1835 1836 1837
    case IrOpcode::kSignExtendWord8ToInt32:
    case IrOpcode::kSignExtendWord16ToInt32:
    case IrOpcode::kSignExtendWord8ToInt64:
    case IrOpcode::kSignExtendWord16ToInt64:
    case IrOpcode::kSignExtendWord32ToInt64:
1838
    case IrOpcode::kStaticAssert:
1839
    case IrOpcode::kStackPointerGreaterThan:
1840 1841 1842 1843 1844

#define SIMD_MACHINE_OP_CASE(Name) case IrOpcode::k##Name:
      MACHINE_SIMD_OP_LIST(SIMD_MACHINE_OP_CASE)
#undef SIMD_MACHINE_OP_CASE

1845 1846
      // TODO(rossberg): Check.
      break;
1847
  }
1848
}  // NOLINT(readability/fn_size)
1849

1850 1851
void Verifier::Run(Graph* graph, Typing typing, CheckInputs check_inputs,
                   CodeType code_type) {
1852 1853
  CHECK_NOT_NULL(graph->start());
  CHECK_NOT_NULL(graph->end());
1854
  Zone zone(graph->zone()->allocator(), ZONE_NAME);
1855
  Visitor visitor(&zone, typing, check_inputs, code_type);
1856
  AllNodes all(&zone, graph);
1857
  for (Node* node : all.reachable) visitor.Check(node, all);
1858 1859

  // Check the uniqueness of projections.
1860
  for (Node* proj : all.reachable) {
1861 1862 1863 1864 1865
    if (proj->opcode() != IrOpcode::kProjection) continue;
    Node* node = proj->InputAt(0);
    for (Node* other : node->uses()) {
      if (all.IsLive(other) && other != proj &&
          other->opcode() == IrOpcode::kProjection &&
1866
          other->InputAt(0) == node &&
1867
          ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
1868 1869
        FATAL("Node #%d:%s has duplicate projections #%d and #%d", node->id(),
              node->op()->mnemonic(), proj->id(), other->id());
1870 1871 1872
      }
    }
  }
1873
}
1874 1875


1876 1877
// -----------------------------------------------------------------------------

1878 1879 1880 1881 1882 1883
static bool HasDominatingDef(Schedule* schedule, Node* node,
                             BasicBlock* container, BasicBlock* use_block,
                             int use_pos) {
  BasicBlock* block = use_block;
  while (true) {
    while (use_pos >= 0) {
1884
      if (block->NodeAt(use_pos) == node) return true;
1885 1886
      use_pos--;
    }
1887
    block = block->dominator();
1888
    if (block == nullptr) break;
1889 1890
    use_pos = static_cast<int>(block->NodeCount()) - 1;
    if (node == block->control_input()) return true;
1891 1892 1893 1894 1895
  }
  return false;
}


1896 1897 1898
static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
  BasicBlock* dom = schedule->block(dominator);
  BasicBlock* sub = schedule->block(dominatee);
1899
  while (sub != nullptr) {
1900 1901 1902 1903 1904 1905 1906 1907 1908
    if (sub == dom) {
      return true;
    }
    sub = sub->dominator();
  }
  return false;
}


1909 1910
static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
                                Node* node, int use_pos) {
1911
  for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
1912 1913 1914
    BasicBlock* use_block = block;
    if (node->opcode() == IrOpcode::kPhi) {
      use_block = use_block->PredecessorAt(j);
1915
      use_pos = static_cast<int>(use_block->NodeCount()) - 1;
1916 1917 1918 1919
    }
    Node* input = node->InputAt(j);
    if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
                          use_pos)) {
1920 1921 1922
      FATAL("Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
            node->id(), node->op()->mnemonic(), block->rpo_number(), j,
            input->id(), input->op()->mnemonic());
1923
    }
1924 1925 1926 1927
  }
  // Ensure that nodes are dominated by their control inputs;
  // kEnd is an exception, as unreachable blocks resulting from kMerge
  // are not in the RPO.
1928
  if (node->op()->ControlInputCount() == 1 &&
1929 1930 1931
      node->opcode() != IrOpcode::kEnd) {
    Node* ctl = NodeProperties::GetControlInput(node);
    if (!Dominates(schedule, ctl, node)) {
1932 1933 1934
      FATAL("Node #%d:%s in B%d is not dominated by control input #%d:%s",
            node->id(), node->op()->mnemonic(), block->rpo_number(), ctl->id(),
            ctl->op()->mnemonic());
1935
    }
1936 1937 1938 1939 1940
  }
}


void ScheduleVerifier::Run(Schedule* schedule) {
1941
  const size_t count = schedule->BasicBlockCount();
1942
  Zone tmp_zone(schedule->zone()->allocator(), ZONE_NAME);
1943 1944 1945 1946 1947
  Zone* zone = &tmp_zone;
  BasicBlock* start = schedule->start();
  BasicBlockVector* rpo_order = schedule->rpo_order();

  // Verify the RPO order contains only blocks from this schedule.
1948
  CHECK_GE(count, rpo_order->size());
1949 1950 1951
  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
       ++b) {
    CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
1952
    // All predecessors and successors should be in rpo and in this schedule.
1953 1954 1955
    for (BasicBlock const* predecessor : (*b)->predecessors()) {
      CHECK_GE(predecessor->rpo_number(), 0);
      CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
1956
    }
1957 1958 1959
    for (BasicBlock const* successor : (*b)->successors()) {
      CHECK_GE(successor->rpo_number(), 0);
      CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
1960
    }
1961 1962 1963 1964 1965 1966
  }

  // Verify RPO numbers of blocks.
  CHECK_EQ(start, rpo_order->at(0));  // Start should be first.
  for (size_t b = 0; b < rpo_order->size(); b++) {
    BasicBlock* block = rpo_order->at(b);
1967 1968
    CHECK_EQ(static_cast<int>(b), block->rpo_number());
    BasicBlock* dom = block->dominator();
1969 1970
    if (b == 0) {
      // All blocks except start should have a dominator.
1971
      CHECK_NULL(dom);
1972 1973
    } else {
      // Check that the immediate dominator appears somewhere before the block.
1974
      CHECK_NOT_NULL(dom);
1975
      CHECK_LT(dom->rpo_number(), block->rpo_number());
1976 1977 1978 1979
    }
  }

  // Verify that all blocks reachable from start are in the RPO.
1980
  BoolVector marked(static_cast<int>(count), false, zone);
1981
  {
1982
    ZoneQueue<BasicBlock*> queue(zone);
1983
    queue.push(start);
1984
    marked[start->id().ToSize()] = true;
1985 1986 1987
    while (!queue.empty()) {
      BasicBlock* block = queue.front();
      queue.pop();
1988
      for (size_t s = 0; s < block->SuccessorCount(); s++) {
1989
        BasicBlock* succ = block->SuccessorAt(s);
1990 1991
        if (!marked[succ->id().ToSize()]) {
          marked[succ->id().ToSize()] = true;
1992 1993 1994 1995 1996 1997
          queue.push(succ);
        }
      }
    }
  }
  // Verify marked blocks are in the RPO.
1998 1999
  for (size_t i = 0; i < count; i++) {
    BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
2000
    if (marked[i]) {
2001 2002
      CHECK_GE(block->rpo_number(), 0);
      CHECK_EQ(block, rpo_order->at(block->rpo_number()));
2003 2004 2005 2006
    }
  }
  // Verify RPO blocks are marked.
  for (size_t b = 0; b < rpo_order->size(); b++) {
2007
    CHECK(marked[rpo_order->at(b)->id().ToSize()]);
2008 2009 2010 2011
  }

  {
    // Verify the dominance relation.
2012
    ZoneVector<BitVector*> dominators(zone);
2013
    dominators.resize(count, nullptr);
2014 2015 2016

    // Compute a set of all the nodes that dominate a given node by using
    // a forward fixpoint. O(n^2).
2017
    ZoneQueue<BasicBlock*> queue(zone);
2018
    queue.push(start);
2019
    dominators[start->id().ToSize()] =
2020
        zone->New<BitVector>(static_cast<int>(count), zone);
2021 2022 2023
    while (!queue.empty()) {
      BasicBlock* block = queue.front();
      queue.pop();
2024 2025
      BitVector* block_doms = dominators[block->id().ToSize()];
      BasicBlock* idom = block->dominator();
2026
      if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
2027 2028
        FATAL("Block B%d is not dominated by B%d", block->rpo_number(),
              idom->rpo_number());
2029
      }
2030
      for (size_t s = 0; s < block->SuccessorCount(); s++) {
2031
        BasicBlock* succ = block->SuccessorAt(s);
2032
        BitVector* succ_doms = dominators[succ->id().ToSize()];
2033

2034
        if (succ_doms == nullptr) {
2035
          // First time visiting the node. S.doms = B U B.doms
2036
          succ_doms = zone->New<BitVector>(static_cast<int>(count), zone);
2037
          succ_doms->CopyFrom(*block_doms);
2038 2039
          succ_doms->Add(block->id().ToInt());
          dominators[succ->id().ToSize()] = succ_doms;
2040 2041
          queue.push(succ);
        } else {
2042
          // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
2043 2044
          bool had = succ_doms->Contains(block->id().ToInt());
          if (had) succ_doms->Remove(block->id().ToInt());
2045
          if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
2046
          if (had) succ_doms->Add(block->id().ToInt());
2047 2048 2049 2050 2051 2052 2053 2054
        }
      }
    }

    // Verify the immediateness of dominators.
    for (BasicBlockVector::iterator b = rpo_order->begin();
         b != rpo_order->end(); ++b) {
      BasicBlock* block = *b;
2055
      BasicBlock* idom = block->dominator();
2056
      if (idom == nullptr) continue;
2057
      BitVector* block_doms = dominators[block->id().ToSize()];
2058 2059

      for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
2060 2061 2062 2063
        BasicBlock* dom =
            schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
        if (dom != idom &&
            !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
2064 2065
          FATAL("Block B%d is not immediately dominated by B%d",
                block->rpo_number(), idom->rpo_number());
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
        }
      }
    }
  }

  // Verify phis are placed in the block of their control input.
  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
       ++b) {
    for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
      Node* phi = *i;
      if (phi->opcode() != IrOpcode::kPhi) continue;
      // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
      // schedules don't have control inputs.
2079
      if (phi->InputCount() > phi->op()->ValueInputCount()) {
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
        Node* control = NodeProperties::GetControlInput(phi);
        CHECK(control->opcode() == IrOpcode::kMerge ||
              control->opcode() == IrOpcode::kLoop);
        CHECK_EQ((*b), schedule->block(control));
      }
    }
  }

  // Verify that all uses are dominated by their definitions.
  for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
       ++b) {
    BasicBlock* block = *b;

    // Check inputs to control for this block.
2094
    Node* control = block->control_input();
2095
    if (control != nullptr) {
2096 2097
      CHECK_EQ(block, schedule->block(control));
      CheckInputsDominate(schedule, block, control,
2098
                          static_cast<int>(block->NodeCount()) - 1);
2099 2100
    }
    // Check inputs for all nodes in the block.
2101 2102
    for (size_t i = 0; i < block->NodeCount(); i++) {
      Node* node = block->NodeAt(i);
2103 2104 2105 2106
      CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
    }
  }
}
2107 2108 2109 2110 2111 2112


#ifdef DEBUG

// static
void Verifier::VerifyNode(Node* node) {
2113 2114
  DCHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
            node->InputCount());
2115
  // If this node has no effect or no control outputs,
2116
  // we check that none of its uses are effect or control inputs.
2117 2118 2119
  bool check_no_control = node->op()->ControlOutputCount() == 0;
  bool check_no_effect = node->op()->EffectOutputCount() == 0;
  bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
2120
  int effect_edges = 0;
2121 2122 2123
  if (check_no_effect || check_no_control) {
    for (Edge edge : node->use_edges()) {
      Node* const user = edge.from();
2124
      DCHECK(!user->IsDead());
2125
      if (NodeProperties::IsControlEdge(edge)) {
2126
        DCHECK(!check_no_control);
2127
      } else if (NodeProperties::IsEffectEdge(edge)) {
2128
        DCHECK(!check_no_effect);
2129
        effect_edges++;
2130
      } else if (NodeProperties::IsFrameStateEdge(edge)) {
2131
        DCHECK(!check_no_frame_state);
2132 2133 2134
      }
    }
  }
2135

2136 2137 2138
  // Frame state input should be a frame state (or sentinel).
  if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
    Node* input = NodeProperties::GetFrameStateInput(node);
2139 2140
    DCHECK(input->opcode() == IrOpcode::kFrameState ||
           input->opcode() == IrOpcode::kStart ||
2141 2142
           input->opcode() == IrOpcode::kDead ||
           input->opcode() == IrOpcode::kDeadValue);
2143 2144 2145 2146
  }
  // Effect inputs should be effect-producing nodes (or sentinels).
  for (int i = 0; i < node->op()->EffectInputCount(); i++) {
    Node* input = NodeProperties::GetEffectInput(node, i);
2147 2148
    DCHECK(input->op()->EffectOutputCount() > 0 ||
           input->opcode() == IrOpcode::kDead);
2149 2150 2151 2152
  }
  // Control inputs should be control-producing nodes (or sentinels).
  for (int i = 0; i < node->op()->ControlInputCount(); i++) {
    Node* input = NodeProperties::GetControlInput(node, i);
2153 2154
    DCHECK(input->op()->ControlOutputCount() > 0 ||
           input->opcode() == IrOpcode::kDead);
2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166
  }
}


void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
                                          const Node* replacement) {
  // Check that the user does not misuse the replacement.
  DCHECK(!NodeProperties::IsControlEdge(edge) ||
         replacement->op()->ControlOutputCount() > 0);
  DCHECK(!NodeProperties::IsEffectEdge(edge) ||
         replacement->op()->EffectOutputCount() > 0);
  DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
2167 2168 2169
         replacement->opcode() == IrOpcode::kFrameState ||
         replacement->opcode() == IrOpcode::kDead ||
         replacement->opcode() == IrOpcode::kDeadValue);
2170 2171 2172 2173
}

#endif  // DEBUG

2174 2175 2176
}  // namespace compiler
}  // namespace internal
}  // namespace v8