1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/int64-lowering.h"
6 
7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/diamond.h"
9 #include "src/compiler/graph.h"
10 #include "src/compiler/linkage.h"
11 #include "src/compiler/machine-operator.h"
12 #include "src/compiler/node-matchers.h"
13 #include "src/compiler/node-properties.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/wasm-compiler.h"
16 // TODO(wasm): Remove this include.
17 #include "src/wasm/wasm-linkage.h"
18 #include "src/zone/zone.h"
19 
20 namespace v8 {
21 namespace internal {
22 namespace compiler {
23 
Int64Lowering(Graph * graph,MachineOperatorBuilder * machine,CommonOperatorBuilder * common,SimplifiedOperatorBuilder * simplified,Zone * zone,Signature<MachineRepresentation> * signature,std::unique_ptr<Int64LoweringSpecialCase> special_case)24 Int64Lowering::Int64Lowering(
25     Graph* graph, MachineOperatorBuilder* machine,
26     CommonOperatorBuilder* common, SimplifiedOperatorBuilder* simplified,
27     Zone* zone, Signature<MachineRepresentation>* signature,
28     std::unique_ptr<Int64LoweringSpecialCase> special_case)
29     : zone_(zone),
30       graph_(graph),
31       machine_(machine),
32       common_(common),
33       simplified_(simplified),
34       state_(graph, 3),
35       stack_(zone),
36       replacements_(nullptr),
37       signature_(signature),
38       placeholder_(graph->NewNode(common->Dead())),
39       special_case_(std::move(special_case)) {
40   DCHECK_NOT_NULL(graph);
41   DCHECK_NOT_NULL(graph->end());
42   replacements_ = zone->NewArray<Replacement>(graph->NodeCount());
43   memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
44 }
45 
LowerGraph()46 void Int64Lowering::LowerGraph() {
47   if (!machine()->Is32()) {
48     return;
49   }
50   stack_.push_back({graph()->end(), 0});
51   state_.Set(graph()->end(), State::kOnStack);
52 
53   while (!stack_.empty()) {
54     NodeState& top = stack_.back();
55     if (top.input_index == top.node->InputCount()) {
56       // All inputs of top have already been lowered, now lower top.
57       stack_.pop_back();
58       state_.Set(top.node, State::kVisited);
59       LowerNode(top.node);
60     } else {
61       // Push the next input onto the stack.
62       Node* input = top.node->InputAt(top.input_index++);
63       if (state_.Get(input) == State::kUnvisited) {
64         if (input->opcode() == IrOpcode::kPhi) {
65           // To break cycles with phi nodes we push phis on a separate stack so
66           // that they are processed after all other nodes.
67           PreparePhiReplacement(input);
68           stack_.push_front({input, 0});
69         } else if (input->opcode() == IrOpcode::kEffectPhi ||
70                    input->opcode() == IrOpcode::kLoop) {
71           stack_.push_front({input, 0});
72         } else {
73           stack_.push_back({input, 0});
74         }
75         state_.Set(input, State::kOnStack);
76       }
77     }
78   }
79 }
80 
81 namespace {
82 
GetReturnIndexAfterLowering(const CallDescriptor * call_descriptor,int old_index)83 int GetReturnIndexAfterLowering(const CallDescriptor* call_descriptor,
84                                 int old_index) {
85   int result = old_index;
86   for (int i = 0; i < old_index; i++) {
87     if (call_descriptor->GetReturnType(i).representation() ==
88         MachineRepresentation::kWord64) {
89       result++;
90     }
91   }
92   return result;
93 }
94 
GetReturnCountAfterLowering(const CallDescriptor * call_descriptor)95 int GetReturnCountAfterLowering(const CallDescriptor* call_descriptor) {
96   return GetReturnIndexAfterLowering(
97       call_descriptor, static_cast<int>(call_descriptor->ReturnCount()));
98 }
99 
GetParameterIndexAfterLowering(Signature<MachineRepresentation> * signature,int old_index)100 int GetParameterIndexAfterLowering(
101     Signature<MachineRepresentation>* signature, int old_index) {
102   int result = old_index;
103   // Be robust towards special indexes (>= param count).
104   int max_to_check =
105       std::min(old_index, static_cast<int>(signature->parameter_count()));
106   for (int i = 0; i < max_to_check; i++) {
107     if (signature->GetParam(i) == MachineRepresentation::kWord64) {
108       result++;
109     }
110   }
111   return result;
112 }
113 
GetReturnCountAfterLowering(Signature<MachineRepresentation> * signature)114 int GetReturnCountAfterLowering(Signature<MachineRepresentation>* signature) {
115   int result = static_cast<int>(signature->return_count());
116   for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
117     if (signature->GetReturn(i) == MachineRepresentation::kWord64) {
118       result++;
119     }
120   }
121   return result;
122 }
123 
124 }  // namespace
125 
LowerWord64AtomicBinop(Node * node,const Operator * op)126 void Int64Lowering::LowerWord64AtomicBinop(Node* node, const Operator* op) {
127   DCHECK_EQ(5, node->InputCount());
128   LowerMemoryBaseAndIndex(node);
129   Node* value = node->InputAt(2);
130   node->ReplaceInput(2, GetReplacementLow(value));
131   node->InsertInput(zone(), 3, GetReplacementHigh(value));
132   NodeProperties::ChangeOp(node, op);
133   ReplaceNodeWithProjections(node);
134 }
135 
LowerWord64AtomicNarrowOp(Node * node,const Operator * op)136 void Int64Lowering::LowerWord64AtomicNarrowOp(Node* node, const Operator* op) {
137   DefaultLowering(node, true);
138   NodeProperties::ChangeOp(node, op);
139   ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0)));
140 }
141 
142 // static
GetParameterCountAfterLowering(Signature<MachineRepresentation> * signature)143 int Int64Lowering::GetParameterCountAfterLowering(
144     Signature<MachineRepresentation>* signature) {
145   // GetParameterIndexAfterLowering(parameter_count) returns the parameter count
146   // after lowering.
147   return GetParameterIndexAfterLowering(
148       signature, static_cast<int>(signature->parameter_count()));
149 }
150 
GetIndexNodes(Node * index,Node ** index_low,Node ** index_high)151 void Int64Lowering::GetIndexNodes(Node* index, Node** index_low,
152                                   Node** index_high) {
153 #if defined(V8_TARGET_LITTLE_ENDIAN)
154   *index_low = index;
155   *index_high = graph()->NewNode(machine()->Int32Add(), index,
156                                  graph()->NewNode(common()->Int32Constant(4)));
157 #elif defined(V8_TARGET_BIG_ENDIAN)
158   *index_low = graph()->NewNode(machine()->Int32Add(), index,
159                                 graph()->NewNode(common()->Int32Constant(4)));
160   *index_high = index;
161 #endif
162 }
163 
LowerLoadOperator(Node * node,MachineRepresentation rep,const Operator * load_op)164 void Int64Lowering::LowerLoadOperator(Node* node, MachineRepresentation rep,
165                                       const Operator* load_op) {
166   if (rep == MachineRepresentation::kWord64) {
167     LowerMemoryBaseAndIndex(node);
168     Node* base = node->InputAt(0);
169     Node* index = node->InputAt(1);
170     Node* index_low;
171     Node* index_high;
172     GetIndexNodes(index, &index_low, &index_high);
173     Node* high_node;
174     if (node->InputCount() > 2) {
175       Node* effect_high = node->InputAt(2);
176       Node* control_high = node->InputAt(3);
177       high_node = graph()->NewNode(load_op, base, index_high, effect_high,
178                                    control_high);
179       // change the effect change from old_node --> old_effect to
180       // old_node --> high_node --> old_effect.
181       node->ReplaceInput(2, high_node);
182     } else {
183       high_node = graph()->NewNode(load_op, base, index_high);
184     }
185     node->ReplaceInput(1, index_low);
186     NodeProperties::ChangeOp(node, load_op);
187     ReplaceNode(node, node, high_node);
188   } else {
189     DefaultLowering(node);
190   }
191 }
192 
LowerStoreOperator(Node * node,MachineRepresentation rep,const Operator * store_op)193 void Int64Lowering::LowerStoreOperator(Node* node, MachineRepresentation rep,
194                                        const Operator* store_op) {
195   if (rep == MachineRepresentation::kWord64) {
196     // We change the original store node to store the low word, and create
197     // a new store node to store the high word. The effect and control edges
198     // are copied from the original store to the new store node, the effect
199     // edge of the original store is redirected to the new store.
200     LowerMemoryBaseAndIndex(node);
201     Node* base = node->InputAt(0);
202     Node* index = node->InputAt(1);
203     Node* index_low;
204     Node* index_high;
205     GetIndexNodes(index, &index_low, &index_high);
206     Node* value = node->InputAt(2);
207     DCHECK(HasReplacementLow(value));
208     DCHECK(HasReplacementHigh(value));
209 
210     Node* high_node;
211     if (node->InputCount() > 3) {
212       Node* effect_high = node->InputAt(3);
213       Node* control_high = node->InputAt(4);
214       high_node = graph()->NewNode(store_op, base, index_high,
215                                    GetReplacementHigh(value), effect_high,
216                                    control_high);
217       node->ReplaceInput(3, high_node);
218 
219     } else {
220       high_node = graph()->NewNode(store_op, base, index_high,
221                                    GetReplacementHigh(value));
222     }
223 
224     node->ReplaceInput(1, index_low);
225     node->ReplaceInput(2, GetReplacementLow(value));
226     NodeProperties::ChangeOp(node, store_op);
227     ReplaceNode(node, node, high_node);
228   } else {
229     DefaultLowering(node, true);
230   }
231 }
232 
LowerNode(Node * node)233 void Int64Lowering::LowerNode(Node* node) {
234   switch (node->opcode()) {
235     case IrOpcode::kInt64Constant: {
236       int64_t value = OpParameter<int64_t>(node->op());
237       Node* low_node = graph()->NewNode(
238           common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
239       Node* high_node = graph()->NewNode(
240           common()->Int32Constant(static_cast<int32_t>(value >> 32)));
241       ReplaceNode(node, low_node, high_node);
242       break;
243     }
244     case IrOpcode::kLoad: {
245       MachineRepresentation rep =
246           LoadRepresentationOf(node->op()).representation();
247       LowerLoadOperator(node, rep, machine()->Load(MachineType::Int32()));
248       break;
249     }
250     case IrOpcode::kUnalignedLoad: {
251       MachineRepresentation rep =
252           LoadRepresentationOf(node->op()).representation();
253       LowerLoadOperator(node, rep,
254                         machine()->UnalignedLoad(MachineType::Int32()));
255       break;
256     }
257     case IrOpcode::kLoadImmutable: {
258       MachineRepresentation rep =
259           LoadRepresentationOf(node->op()).representation();
260       LowerLoadOperator(node, rep,
261                         machine()->LoadImmutable(MachineType::Int32()));
262       break;
263     }
264     case IrOpcode::kLoadFromObject: {
265       ObjectAccess access = ObjectAccessOf(node->op());
266       LowerLoadOperator(node, access.machine_type.representation(),
267                         simplified()->LoadFromObject(ObjectAccess(
268                             MachineType::Int32(), access.write_barrier_kind)));
269       break;
270     }
271     case IrOpcode::kStore: {
272       StoreRepresentation store_rep = StoreRepresentationOf(node->op());
273       LowerStoreOperator(
274           node, store_rep.representation(),
275           machine()->Store(StoreRepresentation(
276               MachineRepresentation::kWord32, store_rep.write_barrier_kind())));
277       break;
278     }
279     case IrOpcode::kUnalignedStore: {
280       UnalignedStoreRepresentation store_rep =
281           UnalignedStoreRepresentationOf(node->op());
282       LowerStoreOperator(
283           node, store_rep,
284           machine()->UnalignedStore(MachineRepresentation::kWord32));
285       break;
286     }
287     case IrOpcode::kStoreToObject: {
288       ObjectAccess access = ObjectAccessOf(node->op());
289       LowerStoreOperator(node, access.machine_type.representation(),
290                          simplified()->StoreToObject(ObjectAccess(
291                              MachineType::Int32(), access.write_barrier_kind)));
292       break;
293     }
294     case IrOpcode::kStart: {
295       int parameter_count = GetParameterCountAfterLowering(signature());
296       // Only exchange the node if the parameter count actually changed.
297       if (parameter_count != static_cast<int>(signature()->parameter_count())) {
298         int delta =
299             parameter_count - static_cast<int>(signature()->parameter_count());
300         int new_output_count = node->op()->ValueOutputCount() + delta;
301         NodeProperties::ChangeOp(node, common()->Start(new_output_count));
302       }
303       break;
304     }
305     case IrOpcode::kParameter: {
306       DCHECK_EQ(1, node->InputCount());
307       int param_count = static_cast<int>(signature()->parameter_count());
308       // Only exchange the node if the parameter count actually changed. We do
309       // not even have to do the default lowering because the the start node,
310       // the only input of a parameter node, only changes if the parameter count
311       // changes.
312       if (GetParameterCountAfterLowering(signature()) != param_count) {
313         int old_index = ParameterIndexOf(node->op());
314         // Adjust old_index to be compliant with the signature.
315         --old_index;
316         int new_index = GetParameterIndexAfterLowering(signature(), old_index);
317         // Adjust new_index to consider the instance parameter.
318         ++new_index;
319         NodeProperties::ChangeOp(node, common()->Parameter(new_index));
320 
321         if (old_index < 0 || old_index >= param_count) {
322           // Special parameters (JS closure/context) don't have kWord64
323           // representation anyway.
324           break;
325         }
326 
327         if (signature()->GetParam(old_index) ==
328             MachineRepresentation::kWord64) {
329           Node* high_node = graph()->NewNode(common()->Parameter(new_index + 1),
330                                              graph()->start());
331           ReplaceNode(node, node, high_node);
332         }
333       }
334       break;
335     }
336     case IrOpcode::kReturn: {
337       int input_count = node->InputCount();
338       DefaultLowering(node);
339       if (input_count != node->InputCount()) {
340         int new_return_count = GetReturnCountAfterLowering(signature());
341         if (static_cast<int>(signature()->return_count()) != new_return_count) {
342           NodeProperties::ChangeOp(node, common()->Return(new_return_count));
343         }
344       }
345       break;
346     }
347     case IrOpcode::kTailCall: {
348       auto call_descriptor =
349           const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
350       bool returns_require_lowering =
351           GetReturnCountAfterLowering(call_descriptor) !=
352           static_cast<int>(call_descriptor->ReturnCount());
353       if (DefaultLowering(node) || returns_require_lowering) {
354         // Tail calls do not have return values, so adjusting the call
355         // descriptor is enough.
356         NodeProperties::ChangeOp(
357             node, common()->TailCall(LowerCallDescriptor(call_descriptor)));
358       }
359       break;
360     }
361     case IrOpcode::kCall: {
362       auto call_descriptor = CallDescriptorOf(node->op());
363 
364       bool returns_require_lowering =
365           GetReturnCountAfterLowering(call_descriptor) !=
366           static_cast<int>(call_descriptor->ReturnCount());
367       if (DefaultLowering(node) || returns_require_lowering) {
368         // We have to adjust the call descriptor.
369         NodeProperties::ChangeOp(
370             node, common()->Call(LowerCallDescriptor(call_descriptor)));
371       }
372       if (returns_require_lowering) {
373         size_t return_arity = call_descriptor->ReturnCount();
374         if (return_arity == 1) {
375           // We access the additional return values through projections.
376           ReplaceNodeWithProjections(node);
377         } else {
378           ZoneVector<Node*> projections(return_arity, zone());
379           NodeProperties::CollectValueProjections(node, projections.data(),
380                                                   return_arity);
381           for (size_t old_index = 0, new_index = 0; old_index < return_arity;
382                ++old_index, ++new_index) {
383             Node* use_node = projections[old_index];
384             DCHECK_EQ(ProjectionIndexOf(use_node->op()), old_index);
385             DCHECK_EQ(GetReturnIndexAfterLowering(call_descriptor,
386                                                   static_cast<int>(old_index)),
387                       static_cast<int>(new_index));
388             if (new_index != old_index) {
389               NodeProperties::ChangeOp(
390                   use_node, common()->Projection(new_index));
391             }
392             if (call_descriptor->GetReturnType(old_index).representation() ==
393                 MachineRepresentation::kWord64) {
394               Node* high_node = graph()->NewNode(
395                   common()->Projection(new_index + 1), node, graph()->start());
396               ReplaceNode(use_node, use_node, high_node);
397               ++new_index;
398             }
399           }
400         }
401       }
402       break;
403     }
404     case IrOpcode::kWord64And: {
405       DCHECK_EQ(2, node->InputCount());
406       Node* left = node->InputAt(0);
407       Node* right = node->InputAt(1);
408 
409       Node* low_node =
410           graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
411                            GetReplacementLow(right));
412       Node* high_node =
413           graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
414                            GetReplacementHigh(right));
415       ReplaceNode(node, low_node, high_node);
416       break;
417     }
418     case IrOpcode::kTruncateInt64ToInt32: {
419       DCHECK_EQ(1, node->InputCount());
420       Node* input = node->InputAt(0);
421       ReplaceNode(node, GetReplacementLow(input), nullptr);
422       node->NullAllInputs();
423       break;
424     }
425     case IrOpcode::kInt64Add: {
426       DCHECK_EQ(2, node->InputCount());
427 
428       Node* right = node->InputAt(1);
429       node->ReplaceInput(1, GetReplacementLow(right));
430       node->AppendInput(zone(), GetReplacementHigh(right));
431 
432       Node* left = node->InputAt(0);
433       node->ReplaceInput(0, GetReplacementLow(left));
434       node->InsertInput(zone(), 1, GetReplacementHigh(left));
435 
436       NodeProperties::ChangeOp(node, machine()->Int32PairAdd());
437       // We access the additional return values through projections.
438       ReplaceNodeWithProjections(node);
439       break;
440     }
441     case IrOpcode::kInt64Sub: {
442       DCHECK_EQ(2, node->InputCount());
443 
444       Node* right = node->InputAt(1);
445       node->ReplaceInput(1, GetReplacementLow(right));
446       node->AppendInput(zone(), GetReplacementHigh(right));
447 
448       Node* left = node->InputAt(0);
449       node->ReplaceInput(0, GetReplacementLow(left));
450       node->InsertInput(zone(), 1, GetReplacementHigh(left));
451 
452       NodeProperties::ChangeOp(node, machine()->Int32PairSub());
453       // We access the additional return values through projections.
454       ReplaceNodeWithProjections(node);
455       break;
456     }
457     case IrOpcode::kInt64Mul: {
458       DCHECK_EQ(2, node->InputCount());
459 
460       Node* right = node->InputAt(1);
461       node->ReplaceInput(1, GetReplacementLow(right));
462       node->AppendInput(zone(), GetReplacementHigh(right));
463 
464       Node* left = node->InputAt(0);
465       node->ReplaceInput(0, GetReplacementLow(left));
466       node->InsertInput(zone(), 1, GetReplacementHigh(left));
467 
468       NodeProperties::ChangeOp(node, machine()->Int32PairMul());
469       // We access the additional return values through projections.
470       ReplaceNodeWithProjections(node);
471       break;
472     }
473     case IrOpcode::kWord64Or: {
474       DCHECK_EQ(2, node->InputCount());
475       Node* left = node->InputAt(0);
476       Node* right = node->InputAt(1);
477 
478       Node* low_node =
479           graph()->NewNode(machine()->Word32Or(), GetReplacementLow(left),
480                            GetReplacementLow(right));
481       Node* high_node =
482           graph()->NewNode(machine()->Word32Or(), GetReplacementHigh(left),
483                            GetReplacementHigh(right));
484       ReplaceNode(node, low_node, high_node);
485       break;
486     }
487     case IrOpcode::kWord64Xor: {
488       DCHECK_EQ(2, node->InputCount());
489       Node* left = node->InputAt(0);
490       Node* right = node->InputAt(1);
491 
492       Node* low_node =
493           graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left),
494                            GetReplacementLow(right));
495       Node* high_node =
496           graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left),
497                            GetReplacementHigh(right));
498       ReplaceNode(node, low_node, high_node);
499       break;
500     }
501     case IrOpcode::kWord64Shl: {
502       // TODO(turbofan): if the shift count >= 32, then we can set the low word
503       // of the output to 0 and just calculate the high word.
504       DCHECK_EQ(2, node->InputCount());
505       Node* shift = node->InputAt(1);
506       if (HasReplacementLow(shift)) {
507         // We do not have to care about the high word replacement, because
508         // the shift can only be between 0 and 63 anyways.
509         node->ReplaceInput(1, GetReplacementLow(shift));
510       }
511 
512       Node* value = node->InputAt(0);
513       node->ReplaceInput(0, GetReplacementLow(value));
514       node->InsertInput(zone(), 1, GetReplacementHigh(value));
515 
516       NodeProperties::ChangeOp(node, machine()->Word32PairShl());
517       // We access the additional return values through projections.
518       ReplaceNodeWithProjections(node);
519       break;
520     }
521     case IrOpcode::kWord64Shr: {
522       // TODO(turbofan): if the shift count >= 32, then we can set the low word
523       // of the output to 0 and just calculate the high word.
524       DCHECK_EQ(2, node->InputCount());
525       Node* shift = node->InputAt(1);
526       if (HasReplacementLow(shift)) {
527         // We do not have to care about the high word replacement, because
528         // the shift can only be between 0 and 63 anyways.
529         node->ReplaceInput(1, GetReplacementLow(shift));
530       }
531 
532       Node* value = node->InputAt(0);
533       node->ReplaceInput(0, GetReplacementLow(value));
534       node->InsertInput(zone(), 1, GetReplacementHigh(value));
535 
536       NodeProperties::ChangeOp(node, machine()->Word32PairShr());
537       // We access the additional return values through projections.
538       ReplaceNodeWithProjections(node);
539       break;
540     }
541     case IrOpcode::kWord64Sar: {
542       // TODO(turbofan): if the shift count >= 32, then we can set the low word
543       // of the output to 0 and just calculate the high word.
544       DCHECK_EQ(2, node->InputCount());
545       Node* shift = node->InputAt(1);
546       if (HasReplacementLow(shift)) {
547         // We do not have to care about the high word replacement, because
548         // the shift can only be between 0 and 63 anyways.
549         node->ReplaceInput(1, GetReplacementLow(shift));
550       }
551 
552       Node* value = node->InputAt(0);
553       node->ReplaceInput(0, GetReplacementLow(value));
554       node->InsertInput(zone(), 1, GetReplacementHigh(value));
555 
556       NodeProperties::ChangeOp(node, machine()->Word32PairSar());
557       // We access the additional return values through projections.
558       ReplaceNodeWithProjections(node);
559       break;
560     }
561     case IrOpcode::kWord64Equal: {
562       DCHECK_EQ(2, node->InputCount());
563       Node* left = node->InputAt(0);
564       Node* right = node->InputAt(1);
565 
566       // TODO(wasm): Use explicit comparisons and && here?
567       Node* replacement = graph()->NewNode(
568           machine()->Word32Equal(),
569           graph()->NewNode(
570               machine()->Word32Or(),
571               graph()->NewNode(machine()->Word32Xor(), GetReplacementLow(left),
572                                GetReplacementLow(right)),
573               graph()->NewNode(machine()->Word32Xor(), GetReplacementHigh(left),
574                                GetReplacementHigh(right))),
575           graph()->NewNode(common()->Int32Constant(0)));
576 
577       ReplaceNode(node, replacement, nullptr);
578       break;
579     }
580     case IrOpcode::kInt64LessThan: {
581       LowerComparison(node, machine()->Int32LessThan(),
582                       machine()->Uint32LessThan());
583       break;
584     }
585     case IrOpcode::kInt64LessThanOrEqual: {
586       LowerComparison(node, machine()->Int32LessThan(),
587                       machine()->Uint32LessThanOrEqual());
588       break;
589     }
590     case IrOpcode::kUint64LessThan: {
591       LowerComparison(node, machine()->Uint32LessThan(),
592                       machine()->Uint32LessThan());
593       break;
594     }
595     case IrOpcode::kUint64LessThanOrEqual: {
596       LowerComparison(node, machine()->Uint32LessThan(),
597                       machine()->Uint32LessThanOrEqual());
598       break;
599     }
600     case IrOpcode::kSignExtendWord32ToInt64:
601     case IrOpcode::kChangeInt32ToInt64: {
602       DCHECK_EQ(1, node->InputCount());
603       Node* input = node->InputAt(0);
604       if (HasReplacementLow(input)) {
605         input = GetReplacementLow(input);
606       }
607       // We use SAR to preserve the sign in the high word.
608       ReplaceNode(
609           node, input,
610           graph()->NewNode(machine()->Word32Sar(), input,
611                            graph()->NewNode(common()->Int32Constant(31))));
612       node->NullAllInputs();
613       break;
614     }
615     case IrOpcode::kChangeUint32ToUint64: {
616       DCHECK_EQ(1, node->InputCount());
617       Node* input = node->InputAt(0);
618       if (HasReplacementLow(input)) {
619         input = GetReplacementLow(input);
620       }
621       ReplaceNode(node, input, graph()->NewNode(common()->Int32Constant(0)));
622       node->NullAllInputs();
623       break;
624     }
625     case IrOpcode::kBitcastInt64ToFloat64: {
626       DCHECK_EQ(1, node->InputCount());
627       Node* input = node->InputAt(0);
628       Node* stack_slot = graph()->NewNode(
629           machine()->StackSlot(MachineRepresentation::kWord64));
630 
631       Node* store_high_word = graph()->NewNode(
632           machine()->Store(
633               StoreRepresentation(MachineRepresentation::kWord32,
634                                   WriteBarrierKind::kNoWriteBarrier)),
635           stack_slot,
636           graph()->NewNode(
637               common()->Int32Constant(kInt64UpperHalfMemoryOffset)),
638           GetReplacementHigh(input), graph()->start(), graph()->start());
639 
640       Node* store_low_word = graph()->NewNode(
641           machine()->Store(
642               StoreRepresentation(MachineRepresentation::kWord32,
643                                   WriteBarrierKind::kNoWriteBarrier)),
644           stack_slot,
645           graph()->NewNode(
646               common()->Int32Constant(kInt64LowerHalfMemoryOffset)),
647           GetReplacementLow(input), store_high_word, graph()->start());
648 
649       Node* load =
650           graph()->NewNode(machine()->Load(MachineType::Float64()), stack_slot,
651                            graph()->NewNode(common()->Int32Constant(0)),
652                            store_low_word, graph()->start());
653 
654       ReplaceNode(node, load, nullptr);
655       break;
656     }
657     case IrOpcode::kBitcastFloat64ToInt64: {
658       DCHECK_EQ(1, node->InputCount());
659       Node* input = node->InputAt(0);
660       if (HasReplacementLow(input)) {
661         input = GetReplacementLow(input);
662       }
663       Node* stack_slot = graph()->NewNode(
664           machine()->StackSlot(MachineRepresentation::kWord64));
665       Node* store = graph()->NewNode(
666           machine()->Store(
667               StoreRepresentation(MachineRepresentation::kFloat64,
668                                   WriteBarrierKind::kNoWriteBarrier)),
669           stack_slot, graph()->NewNode(common()->Int32Constant(0)), input,
670           graph()->start(), graph()->start());
671 
672       Node* high_node = graph()->NewNode(
673           machine()->Load(MachineType::Int32()), stack_slot,
674           graph()->NewNode(
675               common()->Int32Constant(kInt64UpperHalfMemoryOffset)),
676           store, graph()->start());
677 
678       Node* low_node = graph()->NewNode(
679           machine()->Load(MachineType::Int32()), stack_slot,
680           graph()->NewNode(
681               common()->Int32Constant(kInt64LowerHalfMemoryOffset)),
682           store, graph()->start());
683       ReplaceNode(node, low_node, high_node);
684       break;
685     }
686     case IrOpcode::kWord64RolLowerable:
687       DCHECK(machine()->Word32Rol().IsSupported());
688       V8_FALLTHROUGH;
689     case IrOpcode::kWord64RorLowerable: {
690       DCHECK_EQ(3, node->InputCount());
691       Node* input = node->InputAt(0);
692       Node* shift = HasReplacementLow(node->InputAt(1))
693                         ? GetReplacementLow(node->InputAt(1))
694                         : node->InputAt(1);
695       Int32Matcher m(shift);
696       if (m.HasResolvedValue()) {
697         // Precondition: 0 <= shift < 64.
698         int32_t shift_value = m.ResolvedValue() & 0x3F;
699         if (shift_value == 0) {
700           ReplaceNode(node, GetReplacementLow(input),
701                       GetReplacementHigh(input));
702         } else if (shift_value == 32) {
703           ReplaceNode(node, GetReplacementHigh(input),
704                       GetReplacementLow(input));
705         } else {
706           Node* low_input;
707           Node* high_input;
708           if (shift_value < 32) {
709             low_input = GetReplacementLow(input);
710             high_input = GetReplacementHigh(input);
711           } else {
712             low_input = GetReplacementHigh(input);
713             high_input = GetReplacementLow(input);
714           }
715           int32_t masked_shift_value = shift_value & 0x1F;
716           Node* masked_shift =
717               graph()->NewNode(common()->Int32Constant(masked_shift_value));
718           Node* inv_shift = graph()->NewNode(
719               common()->Int32Constant(32 - masked_shift_value));
720 
721           auto* op1 = machine()->Word32Shr();
722           auto* op2 = machine()->Word32Shl();
723           bool is_ror = node->opcode() == IrOpcode::kWord64RorLowerable;
724           if (!is_ror) std::swap(op1, op2);
725 
726           Node* low_node =
727               graph()->NewNode(machine()->Word32Or(),
728                                graph()->NewNode(op1, low_input, masked_shift),
729                                graph()->NewNode(op2, high_input, inv_shift));
730           Node* high_node =
731               graph()->NewNode(machine()->Word32Or(),
732                                graph()->NewNode(op1, high_input, masked_shift),
733                                graph()->NewNode(op2, low_input, inv_shift));
734           ReplaceNode(node, low_node, high_node);
735         }
736       } else {
737         Node* safe_shift = shift;
738         if (!machine()->Word32ShiftIsSafe()) {
739           safe_shift =
740               graph()->NewNode(machine()->Word32And(), shift,
741                                graph()->NewNode(common()->Int32Constant(0x1F)));
742         }
743 
744         bool is_ror = node->opcode() == IrOpcode::kWord64RorLowerable;
745         Node* inv_mask =
746             is_ror ? graph()->NewNode(
747                          machine()->Word32Xor(),
748                          graph()->NewNode(
749                              machine()->Word32Shr(),
750                              graph()->NewNode(common()->Int32Constant(-1)),
751                              safe_shift),
752                          graph()->NewNode(common()->Int32Constant(-1)))
753                    : graph()->NewNode(
754                          machine()->Word32Shl(),
755                          graph()->NewNode(common()->Int32Constant(-1)),
756                          safe_shift);
757 
758         Node* bit_mask =
759             graph()->NewNode(machine()->Word32Xor(), inv_mask,
760                              graph()->NewNode(common()->Int32Constant(-1)));
761 
762         // We have to mask the shift value for this comparison. If
763         // !machine()->Word32ShiftIsSafe() then the masking should already be
764         // part of the graph.
765         Node* masked_shift6 = shift;
766         if (machine()->Word32ShiftIsSafe()) {
767           masked_shift6 =
768               graph()->NewNode(machine()->Word32And(), shift,
769                                graph()->NewNode(common()->Int32Constant(0x3F)));
770         }
771 
772         Diamond lt32(
773             graph(), common(),
774             graph()->NewNode(machine()->Int32LessThan(), masked_shift6,
775                              graph()->NewNode(common()->Int32Constant(32))));
776         lt32.Chain(NodeProperties::GetControlInput(node));
777 
778         // The low word and the high word can be swapped either at the input or
779         // at the output. We swap the inputs so that shift does not have to be
780         // kept for so long in a register.
781         Node* input_low =
782             lt32.Phi(MachineRepresentation::kWord32, GetReplacementLow(input),
783                      GetReplacementHigh(input));
784         Node* input_high =
785             lt32.Phi(MachineRepresentation::kWord32, GetReplacementHigh(input),
786                      GetReplacementLow(input));
787 
788         const Operator* oper =
789             is_ror ? machine()->Word32Ror() : machine()->Word32Rol().op();
790 
791         Node* rotate_low = graph()->NewNode(oper, input_low, safe_shift);
792         Node* rotate_high = graph()->NewNode(oper, input_high, safe_shift);
793 
794         auto* mask1 = bit_mask;
795         auto* mask2 = inv_mask;
796         if (!is_ror) std::swap(mask1, mask2);
797 
798         Node* low_node = graph()->NewNode(
799             machine()->Word32Or(),
800             graph()->NewNode(machine()->Word32And(), rotate_low, mask1),
801             graph()->NewNode(machine()->Word32And(), rotate_high, mask2));
802         Node* high_node = graph()->NewNode(
803             machine()->Word32Or(),
804             graph()->NewNode(machine()->Word32And(), rotate_high, mask1),
805             graph()->NewNode(machine()->Word32And(), rotate_low, mask2));
806         ReplaceNode(node, low_node, high_node);
807       }
808       break;
809     }
810     case IrOpcode::kWord64ClzLowerable: {
811       DCHECK_EQ(2, node->InputCount());
812       Node* input = node->InputAt(0);
813       Diamond d(
814           graph(), common(),
815           graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(input),
816                            graph()->NewNode(common()->Int32Constant(0))));
817       d.Chain(NodeProperties::GetControlInput(node));
818 
819       Node* low_node = d.Phi(
820           MachineRepresentation::kWord32,
821           graph()->NewNode(machine()->Int32Add(),
822                            graph()->NewNode(machine()->Word32Clz(),
823                                             GetReplacementLow(input)),
824                            graph()->NewNode(common()->Int32Constant(32))),
825           graph()->NewNode(machine()->Word32Clz(), GetReplacementHigh(input)));
826       ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
827       break;
828     }
829     case IrOpcode::kWord64CtzLowerable: {
830       DCHECK_EQ(2, node->InputCount());
831       DCHECK(machine()->Word32Ctz().IsSupported());
832       Node* input = node->InputAt(0);
833       Diamond d(
834           graph(), common(),
835           graph()->NewNode(machine()->Word32Equal(), GetReplacementLow(input),
836                            graph()->NewNode(common()->Int32Constant(0))));
837       d.Chain(NodeProperties::GetControlInput(node));
838 
839       Node* low_node =
840           d.Phi(MachineRepresentation::kWord32,
841                 graph()->NewNode(machine()->Int32Add(),
842                                  graph()->NewNode(machine()->Word32Ctz().op(),
843                                                   GetReplacementHigh(input)),
844                                  graph()->NewNode(common()->Int32Constant(32))),
845                 graph()->NewNode(machine()->Word32Ctz().op(),
846                                  GetReplacementLow(input)));
847       ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
848       break;
849     }
850     case IrOpcode::kWord64Ror:
851     case IrOpcode::kWord64Rol:
852     case IrOpcode::kWord64Ctz:
853     case IrOpcode::kWord64Clz:
854       FATAL("%s operator should not be used in 32-bit systems",
855             node->op()->mnemonic());
856     case IrOpcode::kWord64Popcnt: {
857       DCHECK_EQ(1, node->InputCount());
858       Node* input = node->InputAt(0);
859       // We assume that a Word64Popcnt node only has been created if
860       // Word32Popcnt is actually supported.
861       DCHECK(machine()->Word32Popcnt().IsSupported());
862       ReplaceNode(node, graph()->NewNode(
863                             machine()->Int32Add(),
864                             graph()->NewNode(machine()->Word32Popcnt().op(),
865                                              GetReplacementLow(input)),
866                             graph()->NewNode(machine()->Word32Popcnt().op(),
867                                              GetReplacementHigh(input))),
868                   graph()->NewNode(common()->Int32Constant(0)));
869       break;
870     }
871     case IrOpcode::kPhi: {
872       MachineRepresentation rep = PhiRepresentationOf(node->op());
873       if (rep == MachineRepresentation::kWord64) {
874         // The replacement nodes have already been created, we only have to
875         // replace placeholder nodes.
876         Node* low_node = GetReplacementLow(node);
877         Node* high_node = GetReplacementHigh(node);
878         for (int i = 0; i < node->op()->ValueInputCount(); i++) {
879           low_node->ReplaceInput(i, GetReplacementLow(node->InputAt(i)));
880           high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i)));
881         }
882       } else {
883         DefaultLowering(node);
884       }
885       break;
886     }
887     case IrOpcode::kLoopExitValue: {
888       MachineRepresentation rep = LoopExitValueRepresentationOf(node->op());
889       if (rep == MachineRepresentation::kWord64) {
890         Node* low_node = graph()->NewNode(
891             common()->LoopExitValue(MachineRepresentation::kWord32),
892             GetReplacementLow(node->InputAt(0)), node->InputAt(1));
893         Node* high_node = graph()->NewNode(
894             common()->LoopExitValue(MachineRepresentation::kWord32),
895             GetReplacementHigh(node->InputAt(0)), node->InputAt(1));
896         ReplaceNode(node, low_node, high_node);
897       } else {
898         DefaultLowering(node);
899       }
900       break;
901     }
902     case IrOpcode::kWord64ReverseBytes: {
903       Node* input = node->InputAt(0);
904       ReplaceNode(node,
905                   graph()->NewNode(machine()->Word32ReverseBytes(),
906                                    GetReplacementHigh(input)),
907                   graph()->NewNode(machine()->Word32ReverseBytes(),
908                                    GetReplacementLow(input)));
909       break;
910     }
911     case IrOpcode::kSignExtendWord8ToInt64: {
912       DCHECK_EQ(1, node->InputCount());
913       Node* input = node->InputAt(0);
914       if (HasReplacementLow(input)) {
915         input = GetReplacementLow(input);
916       }
917       // Sign extend low node to Int32
918       input = graph()->NewNode(machine()->SignExtendWord8ToInt32(), input);
919 
920       // We use SAR to preserve the sign in the high word.
921       ReplaceNode(
922           node, input,
923           graph()->NewNode(machine()->Word32Sar(), input,
924                            graph()->NewNode(common()->Int32Constant(31))));
925       node->NullAllInputs();
926       break;
927     }
928     case IrOpcode::kSignExtendWord16ToInt64: {
929       DCHECK_EQ(1, node->InputCount());
930       Node* input = node->InputAt(0);
931       if (HasReplacementLow(input)) {
932         input = GetReplacementLow(input);
933       }
934       // Sign extend low node to Int32
935       input = graph()->NewNode(machine()->SignExtendWord16ToInt32(), input);
936 
937       // We use SAR to preserve the sign in the high word.
938       ReplaceNode(
939           node, input,
940           graph()->NewNode(machine()->Word32Sar(), input,
941                            graph()->NewNode(common()->Int32Constant(31))));
942       node->NullAllInputs();
943       break;
944     }
945     case IrOpcode::kWord64AtomicLoad: {
946       DCHECK_EQ(4, node->InputCount());
947       AtomicLoadParameters params = AtomicLoadParametersOf(node->op());
948       DefaultLowering(node, true);
949       if (params.representation() == MachineType::Uint64()) {
950         NodeProperties::ChangeOp(
951             node, machine()->Word32AtomicPairLoad(params.order()));
952         ReplaceNodeWithProjections(node);
953       } else {
954         NodeProperties::ChangeOp(node, machine()->Word32AtomicLoad(params));
955         ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0)));
956       }
957       break;
958     }
959     case IrOpcode::kWord64AtomicStore: {
960       DCHECK_EQ(5, node->InputCount());
961       AtomicStoreParameters params = AtomicStoreParametersOf(node->op());
962       if (params.representation() == MachineRepresentation::kWord64) {
963         LowerMemoryBaseAndIndex(node);
964         Node* value = node->InputAt(2);
965         node->ReplaceInput(2, GetReplacementLow(value));
966         node->InsertInput(zone(), 3, GetReplacementHigh(value));
967         NodeProperties::ChangeOp(
968             node, machine()->Word32AtomicPairStore(params.order()));
969       } else {
970         DefaultLowering(node, true);
971         NodeProperties::ChangeOp(node, machine()->Word32AtomicStore(params));
972       }
973       break;
974     }
975 #define ATOMIC_CASE(name)                                                   \
976   case IrOpcode::kWord64Atomic##name: {                                     \
977     MachineType type = AtomicOpType(node->op());                            \
978     if (type == MachineType::Uint64()) {                                    \
979       LowerWord64AtomicBinop(node, machine()->Word32AtomicPair##name());    \
980     } else {                                                                \
981       LowerWord64AtomicNarrowOp(node, machine()->Word32Atomic##name(type)); \
982     }                                                                       \
983     break;                                                                  \
984   }
985       ATOMIC_CASE(Add)
986       ATOMIC_CASE(Sub)
987       ATOMIC_CASE(And)
988       ATOMIC_CASE(Or)
989       ATOMIC_CASE(Xor)
990       ATOMIC_CASE(Exchange)
991 #undef ATOMIC_CASE
992     case IrOpcode::kWord64AtomicCompareExchange: {
993       MachineType type = AtomicOpType(node->op());
994       if (type == MachineType::Uint64()) {
995         LowerMemoryBaseAndIndex(node);
996         Node* old_value = node->InputAt(2);
997         Node* new_value = node->InputAt(3);
998         node->ReplaceInput(2, GetReplacementLow(old_value));
999         node->ReplaceInput(3, GetReplacementHigh(old_value));
1000         node->InsertInput(zone(), 4, GetReplacementLow(new_value));
1001         node->InsertInput(zone(), 5, GetReplacementHigh(new_value));
1002         NodeProperties::ChangeOp(node,
1003                                  machine()->Word32AtomicPairCompareExchange());
1004         ReplaceNodeWithProjections(node);
1005       } else {
1006         DCHECK(type == MachineType::Uint32() || type == MachineType::Uint16() ||
1007                type == MachineType::Uint8());
1008         DefaultLowering(node, true);
1009         NodeProperties::ChangeOp(node,
1010                                  machine()->Word32AtomicCompareExchange(type));
1011         ReplaceNode(node, node, graph()->NewNode(common()->Int32Constant(0)));
1012       }
1013       break;
1014     }
1015     case IrOpcode::kI64x2Splat: {
1016       DCHECK_EQ(1, node->InputCount());
1017       Node* input = node->InputAt(0);
1018       node->ReplaceInput(0, GetReplacementLow(input));
1019       node->AppendInput(zone(), GetReplacementHigh(input));
1020       NodeProperties::ChangeOp(node, machine()->I64x2SplatI32Pair());
1021       break;
1022     }
1023     case IrOpcode::kI64x2ExtractLane: {
1024       DCHECK_EQ(1, node->InputCount());
1025       Node* input = node->InputAt(0);
1026       int32_t lane = OpParameter<int32_t>(node->op());
1027       ReplaceNode(
1028           node, graph()->NewNode(machine()->I32x4ExtractLane(lane * 2), input),
1029           graph()->NewNode(machine()->I32x4ExtractLane(lane * 2 + 1), input));
1030       break;
1031     }
1032     case IrOpcode::kI64x2ReplaceLane: {
1033       DCHECK_EQ(2, node->InputCount());
1034       int32_t lane = OpParameter<int32_t>(node->op());
1035       Node* input = node->InputAt(1);
1036       node->ReplaceInput(1, GetReplacementLow(input));
1037       node->AppendInput(zone(), GetReplacementHigh(input));
1038       NodeProperties::ChangeOp(node, machine()->I64x2ReplaceLaneI32Pair(lane));
1039       break;
1040     }
1041 
1042     default: { DefaultLowering(node); }
1043   }
1044 }
1045 
LowerComparison(Node * node,const Operator * high_word_op,const Operator * low_word_op)1046 void Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op,
1047                                     const Operator* low_word_op) {
1048   DCHECK_EQ(2, node->InputCount());
1049   Node* left = node->InputAt(0);
1050   Node* right = node->InputAt(1);
1051   Node* replacement = graph()->NewNode(
1052       machine()->Word32Or(),
1053       graph()->NewNode(high_word_op, GetReplacementHigh(left),
1054                        GetReplacementHigh(right)),
1055       graph()->NewNode(
1056           machine()->Word32And(),
1057           graph()->NewNode(machine()->Word32Equal(), GetReplacementHigh(left),
1058                            GetReplacementHigh(right)),
1059           graph()->NewNode(low_word_op, GetReplacementLow(left),
1060                            GetReplacementLow(right))));
1061 
1062   ReplaceNode(node, replacement, nullptr);
1063 }
1064 
DefaultLowering(Node * node,bool low_word_only)1065 bool Int64Lowering::DefaultLowering(Node* node, bool low_word_only) {
1066   bool something_changed = false;
1067   for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
1068     Node* input = node->InputAt(i);
1069     if (HasReplacementLow(input)) {
1070       something_changed = true;
1071       node->ReplaceInput(i, GetReplacementLow(input));
1072     }
1073     if (!low_word_only && HasReplacementHigh(input)) {
1074       something_changed = true;
1075       node->InsertInput(zone(), i + 1, GetReplacementHigh(input));
1076     }
1077   }
1078   return something_changed;
1079 }
1080 
LowerCallDescriptor(const CallDescriptor * call_descriptor)1081 const CallDescriptor* Int64Lowering::LowerCallDescriptor(
1082     const CallDescriptor* call_descriptor) {
1083   if (special_case_) {
1084     auto replacement = special_case_->replacements.find(call_descriptor);
1085     if (replacement != special_case_->replacements.end()) {
1086       return replacement->second;
1087     }
1088   }
1089   return GetI32WasmCallDescriptor(zone(), call_descriptor);
1090 }
1091 
ReplaceNode(Node * old,Node * new_low,Node * new_high)1092 void Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) {
1093   // if new_low == nullptr, then also new_high == nullptr.
1094   DCHECK(new_low != nullptr || new_high == nullptr);
1095   replacements_[old->id()].low = new_low;
1096   replacements_[old->id()].high = new_high;
1097 }
1098 
HasReplacementLow(Node * node)1099 bool Int64Lowering::HasReplacementLow(Node* node) {
1100   return replacements_[node->id()].low != nullptr;
1101 }
1102 
GetReplacementLow(Node * node)1103 Node* Int64Lowering::GetReplacementLow(Node* node) {
1104   Node* result = replacements_[node->id()].low;
1105   DCHECK(result);
1106   return result;
1107 }
1108 
HasReplacementHigh(Node * node)1109 bool Int64Lowering::HasReplacementHigh(Node* node) {
1110   return replacements_[node->id()].high != nullptr;
1111 }
1112 
GetReplacementHigh(Node * node)1113 Node* Int64Lowering::GetReplacementHigh(Node* node) {
1114   Node* result = replacements_[node->id()].high;
1115   DCHECK(result);
1116   return result;
1117 }
1118 
PreparePhiReplacement(Node * phi)1119 void Int64Lowering::PreparePhiReplacement(Node* phi) {
1120   MachineRepresentation rep = PhiRepresentationOf(phi->op());
1121   if (rep == MachineRepresentation::kWord64) {
1122     // We have to create the replacements for a phi node before we actually
1123     // lower the phi to break potential cycles in the graph. The replacements of
1124     // input nodes do not exist yet, so we use a placeholder node to pass the
1125     // graph verifier.
1126     int value_count = phi->op()->ValueInputCount();
1127     Node** inputs_low = zone()->NewArray<Node*>(value_count + 1);
1128     Node** inputs_high = zone()->NewArray<Node*>(value_count + 1);
1129     for (int i = 0; i < value_count; i++) {
1130       inputs_low[i] = placeholder_;
1131       inputs_high[i] = placeholder_;
1132     }
1133     inputs_low[value_count] = NodeProperties::GetControlInput(phi, 0);
1134     inputs_high[value_count] = NodeProperties::GetControlInput(phi, 0);
1135     ReplaceNode(phi,
1136                 graph()->NewNode(
1137                     common()->Phi(MachineRepresentation::kWord32, value_count),
1138                     value_count + 1, inputs_low, false),
1139                 graph()->NewNode(
1140                     common()->Phi(MachineRepresentation::kWord32, value_count),
1141                     value_count + 1, inputs_high, false));
1142   }
1143 }
1144 
ReplaceNodeWithProjections(Node * node)1145 void Int64Lowering::ReplaceNodeWithProjections(Node* node) {
1146   DCHECK(node != nullptr);
1147   Node* low_node =
1148       graph()->NewNode(common()->Projection(0), node, graph()->start());
1149   Node* high_node =
1150       graph()->NewNode(common()->Projection(1), node, graph()->start());
1151   ReplaceNode(node, low_node, high_node);
1152 }
1153 
LowerMemoryBaseAndIndex(Node * node)1154 void Int64Lowering::LowerMemoryBaseAndIndex(Node* node) {
1155   DCHECK(node != nullptr);
1156   // Low word only replacements for memory operands for 32-bit address space.
1157   Node* base = node->InputAt(0);
1158   Node* index = node->InputAt(1);
1159   if (HasReplacementLow(base)) {
1160     node->ReplaceInput(0, GetReplacementLow(base));
1161   }
1162   if (HasReplacementLow(index)) {
1163     node->ReplaceInput(1, GetReplacementLow(index));
1164   }
1165 }
1166 
1167 }  // namespace compiler
1168 }  // namespace internal
1169 }  // namespace v8
1170