blob: 08f30387541d9ed0e39f4abb0885b784c40407ee [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// Copyright 2016 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#include "src/compiler/common-operator.h"
7#include "src/compiler/linkage.h"
8#include "src/compiler/machine-operator.h"
9#include "src/compiler/node.h"
10
11#include "src/compiler/node-properties.h"
12
13#include "src/signature.h"
14
15#include "src/wasm/wasm-module.h"
16
17#include "test/unittests/compiler/graph-unittest.h"
18#include "test/unittests/compiler/node-test-utils.h"
19#include "testing/gmock-support.h"
20
21using testing::AllOf;
22using testing::Capture;
23using testing::CaptureEq;
24
25namespace v8 {
26namespace internal {
27namespace compiler {
28
29class Int64LoweringTest : public GraphTest {
30 public:
Ben Murdochda12d292016-06-02 14:46:10 +010031 Int64LoweringTest()
32 : GraphTest(),
33 machine_(zone(), MachineRepresentation::kWord32,
34 MachineOperatorBuilder::Flag::kAllOptionalOps) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010035 value_[0] = 0x1234567890abcdef;
36 value_[1] = 0x1edcba098765432f;
37 value_[2] = 0x1133557799886644;
38 }
39
40 MachineOperatorBuilder* machine() { return &machine_; }
41
42 void LowerGraph(Node* node, Signature<MachineRepresentation>* signature) {
43 Node* ret = graph()->NewNode(common()->Return(), node, graph()->start(),
44 graph()->start());
45 NodeProperties::MergeControlToEnd(graph(), common(), ret);
46
47 Int64Lowering lowering(graph(), machine(), common(), zone(), signature);
48 lowering.LowerGraph();
49 }
50
51 void LowerGraph(Node* node, MachineRepresentation return_type,
52 MachineRepresentation rep = MachineRepresentation::kWord32,
53 int num_params = 0) {
54 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1,
55 num_params);
56 sig_builder.AddReturn(return_type);
57 for (int i = 0; i < num_params; i++) {
58 sig_builder.AddParam(rep);
59 }
60 LowerGraph(node, sig_builder.Build());
61 }
62
63 void CompareCallDescriptors(const CallDescriptor* lhs,
64 const CallDescriptor* rhs) {
65 EXPECT_THAT(lhs->CalleeSavedFPRegisters(), rhs->CalleeSavedFPRegisters());
66 EXPECT_THAT(lhs->CalleeSavedRegisters(), rhs->CalleeSavedRegisters());
67 EXPECT_THAT(lhs->FrameStateCount(), rhs->FrameStateCount());
68 EXPECT_THAT(lhs->InputCount(), rhs->InputCount());
69 for (size_t i = 0; i < lhs->InputCount(); i++) {
70 EXPECT_THAT(lhs->GetInputLocation(i), rhs->GetInputLocation(i));
71 EXPECT_THAT(lhs->GetInputType(i), rhs->GetInputType(i));
72 }
73 EXPECT_THAT(lhs->ReturnCount(), rhs->ReturnCount());
74 for (size_t i = 0; i < lhs->ReturnCount(); i++) {
75 EXPECT_THAT(lhs->GetReturnLocation(i), rhs->GetReturnLocation(i));
76 EXPECT_THAT(lhs->GetReturnType(i), rhs->GetReturnType(i));
77 }
78 EXPECT_THAT(lhs->flags(), rhs->flags());
79 EXPECT_THAT(lhs->kind(), rhs->kind());
80 }
81
82 int64_t value(int i) { return value_[i]; }
83
84 int32_t low_word_value(int i) {
85 return static_cast<int32_t>(value_[i] & 0xffffffff);
86 }
87
88 int32_t high_word_value(int i) {
89 return static_cast<int32_t>(value_[i] >> 32);
90 }
91
Ben Murdochda12d292016-06-02 14:46:10 +010092 void TestComparison(
93 const Operator* op,
94 Matcher<Node*> (*high_word_matcher)(const Matcher<Node*>& lhs_matcher,
95 const Matcher<Node*>& rhs_matcher),
96 Matcher<Node*> (*low_word_matcher)(const Matcher<Node*>& lhs_matcher,
97 const Matcher<Node*>& rhs_matcher)) {
98 LowerGraph(
99 graph()->NewNode(op, Int64Constant(value(0)), Int64Constant(value(1))),
100 MachineRepresentation::kWord32);
101 EXPECT_THAT(
102 graph()->end()->InputAt(1),
103 IsReturn(IsWord32Or(
104 high_word_matcher(IsInt32Constant(high_word_value(0)),
105 IsInt32Constant(high_word_value(1))),
106 IsWord32And(
107 IsWord32Equal(IsInt32Constant(high_word_value(0)),
108 IsInt32Constant(high_word_value(1))),
109 low_word_matcher(IsInt32Constant(low_word_value(0)),
110 IsInt32Constant(low_word_value(1))))),
111 start(), start()));
112 }
113
Ben Murdoch097c5b22016-05-18 11:27:45 +0100114 private:
115 MachineOperatorBuilder machine_;
116 int64_t value_[3];
117};
118
119TEST_F(Int64LoweringTest, Int64Constant) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100120 LowerGraph(Int64Constant(value(0)), MachineRepresentation::kWord64);
121 EXPECT_THAT(graph()->end()->InputAt(1),
122 IsReturn2(IsInt32Constant(low_word_value(0)),
123 IsInt32Constant(high_word_value(0)), start(), start()));
124}
125
126TEST_F(Int64LoweringTest, Int64Load) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100127 int32_t base = 0x1234;
128 int32_t index = 0x5678;
129
130 LowerGraph(graph()->NewNode(machine()->Load(MachineType::Int64()),
131 Int32Constant(base), Int32Constant(index),
132 start(), start()),
133 MachineRepresentation::kWord64);
134
135 Capture<Node*> high_word_load;
136 Matcher<Node*> high_word_load_matcher =
137 IsLoad(MachineType::Int32(), IsInt32Constant(base),
138 IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)), start(),
139 start());
140
141 EXPECT_THAT(
142 graph()->end()->InputAt(1),
143 IsReturn2(IsLoad(MachineType::Int32(), IsInt32Constant(base),
144 IsInt32Constant(index), AllOf(CaptureEq(&high_word_load),
145 high_word_load_matcher),
146 start()),
147 AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
148 start(), start()));
149}
150
151TEST_F(Int64LoweringTest, Int64Store) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100152 // We have to build the TF graph explicitly here because Store does not return
153 // a value.
154
155 int32_t base = 1111;
156 int32_t index = 2222;
157 int32_t return_value = 0x5555;
158
159 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 0);
160 sig_builder.AddReturn(MachineRepresentation::kWord32);
161
162 Node* store = graph()->NewNode(
163 machine()->Store(StoreRepresentation(MachineRepresentation::kWord64,
164 WriteBarrierKind::kNoWriteBarrier)),
165 Int32Constant(base), Int32Constant(index), Int64Constant(value(0)),
166 start(), start());
167
168 Node* ret = graph()->NewNode(common()->Return(), Int32Constant(return_value),
169 store, start());
170
171 NodeProperties::MergeControlToEnd(graph(), common(), ret);
172
173 Int64Lowering lowering(graph(), machine(), common(), zone(),
174 sig_builder.Build());
175 lowering.LowerGraph();
176
177 const StoreRepresentation rep(MachineRepresentation::kWord32,
178 kNoWriteBarrier);
179
180 EXPECT_THAT(
181 graph()->end()->InputAt(1),
182 IsReturn(
183 IsInt32Constant(return_value),
184 IsStore(
185 rep, IsInt32Constant(base), IsInt32Constant(index),
186 IsInt32Constant(low_word_value(0)),
187 IsStore(rep, IsInt32Constant(base),
188 IsInt32Add(IsInt32Constant(index), IsInt32Constant(4)),
189 IsInt32Constant(high_word_value(0)), start(), start()),
190 start()),
191 start()));
192}
193
194TEST_F(Int64LoweringTest, Int64And) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195 LowerGraph(graph()->NewNode(machine()->Word64And(), Int64Constant(value(0)),
196 Int64Constant(value(1))),
197 MachineRepresentation::kWord64);
198 EXPECT_THAT(graph()->end()->InputAt(1),
199 IsReturn2(IsWord32And(IsInt32Constant(low_word_value(0)),
200 IsInt32Constant(low_word_value(1))),
201 IsWord32And(IsInt32Constant(high_word_value(0)),
202 IsInt32Constant(high_word_value(1))),
203 start(), start()));
204}
205
206TEST_F(Int64LoweringTest, TruncateInt64ToInt32) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207 LowerGraph(graph()->NewNode(machine()->TruncateInt64ToInt32(),
208 Int64Constant(value(0))),
209 MachineRepresentation::kWord32);
210 EXPECT_THAT(graph()->end()->InputAt(1),
211 IsReturn(IsInt32Constant(low_word_value(0)), start(), start()));
212}
213
214TEST_F(Int64LoweringTest, Parameter) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100215 LowerGraph(Parameter(0), MachineRepresentation::kWord64,
216 MachineRepresentation::kWord64, 1);
217
218 EXPECT_THAT(graph()->end()->InputAt(1),
219 IsReturn2(IsParameter(0), IsParameter(1), start(), start()));
220}
221
222TEST_F(Int64LoweringTest, Parameter2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 5);
224 sig_builder.AddReturn(MachineRepresentation::kWord32);
225
226 sig_builder.AddParam(MachineRepresentation::kWord32);
227 sig_builder.AddParam(MachineRepresentation::kWord64);
228 sig_builder.AddParam(MachineRepresentation::kFloat64);
229 sig_builder.AddParam(MachineRepresentation::kWord64);
230 sig_builder.AddParam(MachineRepresentation::kWord32);
231
232 int start_parameter = start()->op()->ValueOutputCount();
233 LowerGraph(Parameter(4), sig_builder.Build());
234
235 EXPECT_THAT(graph()->end()->InputAt(1),
236 IsReturn(IsParameter(6), start(), start()));
237 // The parameter of the start node should increase by 2, because we lowered
238 // two parameter nodes.
239 EXPECT_THAT(start()->op()->ValueOutputCount(), start_parameter + 2);
240}
241
242TEST_F(Int64LoweringTest, CallI64Return) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100243 int32_t function = 0x9999;
244
245 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 0);
246 sig_builder.AddReturn(MachineRepresentation::kWord64);
247
248 compiler::CallDescriptor* desc =
249 wasm::ModuleEnv::GetWasmCallDescriptor(zone(), sig_builder.Build());
250
251 LowerGraph(graph()->NewNode(common()->Call(desc), Int32Constant(function),
252 start(), start()),
253 MachineRepresentation::kWord64);
254
255 Capture<Node*> call;
256 Matcher<Node*> call_matcher =
257 IsCall(testing::_, IsInt32Constant(function), start(), start());
258
259 EXPECT_THAT(graph()->end()->InputAt(1),
260 IsReturn2(IsProjection(0, AllOf(CaptureEq(&call), call_matcher)),
261 IsProjection(1, AllOf(CaptureEq(&call), call_matcher)),
262 start(), start()));
263
264 CompareCallDescriptors(
265 OpParameter<const CallDescriptor*>(
266 graph()->end()->InputAt(1)->InputAt(0)->InputAt(0)),
267 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), desc));
268}
269
270TEST_F(Int64LoweringTest, CallI64Parameter) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100271 int32_t function = 0x9999;
272
273 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 3);
274 sig_builder.AddReturn(MachineRepresentation::kWord32);
275 sig_builder.AddParam(MachineRepresentation::kWord64);
276 sig_builder.AddParam(MachineRepresentation::kWord32);
277 sig_builder.AddParam(MachineRepresentation::kWord64);
278
279 compiler::CallDescriptor* desc =
280 wasm::ModuleEnv::GetWasmCallDescriptor(zone(), sig_builder.Build());
281
282 LowerGraph(graph()->NewNode(common()->Call(desc), Int32Constant(function),
283 Int64Constant(value(0)),
284 Int32Constant(low_word_value(1)),
285 Int64Constant(value(2)), start(), start()),
286 MachineRepresentation::kWord32);
287
288 EXPECT_THAT(
289 graph()->end()->InputAt(1),
290 IsReturn(IsCall(testing::_, IsInt32Constant(function),
291 IsInt32Constant(low_word_value(0)),
292 IsInt32Constant(high_word_value(0)),
293 IsInt32Constant(low_word_value(1)),
294 IsInt32Constant(low_word_value(2)),
295 IsInt32Constant(high_word_value(2)), start(), start()),
296 start(), start()));
297
298 CompareCallDescriptors(
299 OpParameter<const CallDescriptor*>(
300 graph()->end()->InputAt(1)->InputAt(0)),
301 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), desc));
302}
303
Ben Murdochda12d292016-06-02 14:46:10 +0100304// todo(ahaas): I added a list of missing instructions here to make merging
305// easier when I do them one by one.
306// kExprI64Add:
307TEST_F(Int64LoweringTest, Int64Add) {
308 LowerGraph(graph()->NewNode(machine()->Int64Add(), Int64Constant(value(0)),
309 Int64Constant(value(1))),
310 MachineRepresentation::kWord64);
311
312 Capture<Node*> add;
313 Matcher<Node*> add_matcher = IsInt32PairAdd(
314 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
315 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
316
317 EXPECT_THAT(graph()->end()->InputAt(1),
318 IsReturn2(IsProjection(0, AllOf(CaptureEq(&add), add_matcher)),
319 IsProjection(1, AllOf(CaptureEq(&add), add_matcher)),
320 start(), start()));
321}
322// kExprI64Sub:
323TEST_F(Int64LoweringTest, Int64Sub) {
324 LowerGraph(graph()->NewNode(machine()->Int64Sub(), Int64Constant(value(0)),
325 Int64Constant(value(1))),
326 MachineRepresentation::kWord64);
327
328 Capture<Node*> sub;
329 Matcher<Node*> sub_matcher = IsInt32PairSub(
330 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
331 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
332
333 EXPECT_THAT(graph()->end()->InputAt(1),
334 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sub), sub_matcher)),
335 IsProjection(1, AllOf(CaptureEq(&sub), sub_matcher)),
336 start(), start()));
337}
338
339// kExprI64Mul:
340TEST_F(Int64LoweringTest, Int64Mul) {
341 LowerGraph(graph()->NewNode(machine()->Int64Mul(), Int64Constant(value(0)),
342 Int64Constant(value(1))),
343 MachineRepresentation::kWord64);
344
345 Capture<Node*> mul_capture;
346 Matcher<Node*> mul_matcher = IsInt32PairMul(
347 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
348 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
349
350 EXPECT_THAT(
351 graph()->end()->InputAt(1),
352 IsReturn2(IsProjection(0, AllOf(CaptureEq(&mul_capture), mul_matcher)),
353 IsProjection(1, AllOf(CaptureEq(&mul_capture), mul_matcher)),
354 start(), start()));
355}
356
357// kExprI64DivS:
358// kExprI64DivU:
359// kExprI64RemS:
360// kExprI64RemU:
361// kExprI64Ior:
362TEST_F(Int64LoweringTest, Int64Ior) {
363 LowerGraph(graph()->NewNode(machine()->Word64Or(), Int64Constant(value(0)),
364 Int64Constant(value(1))),
365 MachineRepresentation::kWord64);
366 EXPECT_THAT(graph()->end()->InputAt(1),
367 IsReturn2(IsWord32Or(IsInt32Constant(low_word_value(0)),
368 IsInt32Constant(low_word_value(1))),
369 IsWord32Or(IsInt32Constant(high_word_value(0)),
370 IsInt32Constant(high_word_value(1))),
371 start(), start()));
372}
373
374// kExprI64Xor:
375TEST_F(Int64LoweringTest, Int64Xor) {
376 LowerGraph(graph()->NewNode(machine()->Word64Xor(), Int64Constant(value(0)),
377 Int64Constant(value(1))),
378 MachineRepresentation::kWord64);
379 EXPECT_THAT(graph()->end()->InputAt(1),
380 IsReturn2(IsWord32Xor(IsInt32Constant(low_word_value(0)),
381 IsInt32Constant(low_word_value(1))),
382 IsWord32Xor(IsInt32Constant(high_word_value(0)),
383 IsInt32Constant(high_word_value(1))),
384 start(), start()));
385}
386// kExprI64Shl:
387TEST_F(Int64LoweringTest, Int64Shl) {
388 LowerGraph(graph()->NewNode(machine()->Word64Shl(), Int64Constant(value(0)),
389 Int64Constant(value(1))),
390 MachineRepresentation::kWord64);
391
392 Capture<Node*> shl;
393 Matcher<Node*> shl_matcher = IsWord32PairShl(
394 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
395 IsInt32Constant(low_word_value(1)));
396
397 EXPECT_THAT(graph()->end()->InputAt(1),
398 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shl), shl_matcher)),
399 IsProjection(1, AllOf(CaptureEq(&shl), shl_matcher)),
400 start(), start()));
401}
402// kExprI64ShrU:
403TEST_F(Int64LoweringTest, Int64ShrU) {
404 LowerGraph(graph()->NewNode(machine()->Word64Shr(), Int64Constant(value(0)),
405 Int64Constant(value(1))),
406 MachineRepresentation::kWord64);
407
408 Capture<Node*> shr;
409 Matcher<Node*> shr_matcher = IsWord32PairShr(
410 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
411 IsInt32Constant(low_word_value(1)));
412
413 EXPECT_THAT(graph()->end()->InputAt(1),
414 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shr), shr_matcher)),
415 IsProjection(1, AllOf(CaptureEq(&shr), shr_matcher)),
416 start(), start()));
417}
418// kExprI64ShrS:
419TEST_F(Int64LoweringTest, Int64ShrS) {
420 LowerGraph(graph()->NewNode(machine()->Word64Sar(), Int64Constant(value(0)),
421 Int64Constant(value(1))),
422 MachineRepresentation::kWord64);
423
424 Capture<Node*> sar;
425 Matcher<Node*> sar_matcher = IsWord32PairSar(
426 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
427 IsInt32Constant(low_word_value(1)));
428
429 EXPECT_THAT(graph()->end()->InputAt(1),
430 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sar), sar_matcher)),
431 IsProjection(1, AllOf(CaptureEq(&sar), sar_matcher)),
432 start(), start()));
433}
434// kExprI64Eq:
435TEST_F(Int64LoweringTest, Int64Eq) {
436 LowerGraph(graph()->NewNode(machine()->Word64Equal(), Int64Constant(value(0)),
437 Int64Constant(value(1))),
438 MachineRepresentation::kWord32);
439 EXPECT_THAT(
440 graph()->end()->InputAt(1),
441 IsReturn(IsWord32Equal(
442 IsWord32Or(IsWord32Xor(IsInt32Constant(low_word_value(0)),
443 IsInt32Constant(low_word_value(1))),
444 IsWord32Xor(IsInt32Constant(high_word_value(0)),
445 IsInt32Constant(high_word_value(1)))),
446 IsInt32Constant(0)),
447 start(), start()));
448}
449
450// kExprI64LtS:
451TEST_F(Int64LoweringTest, Int64LtS) {
452 TestComparison(machine()->Int64LessThan(), IsInt32LessThan, IsUint32LessThan);
453}
454// kExprI64LeS:
455TEST_F(Int64LoweringTest, Int64LeS) {
456 TestComparison(machine()->Int64LessThanOrEqual(), IsInt32LessThan,
457 IsUint32LessThanOrEqual);
458}
459// kExprI64LtU:
460TEST_F(Int64LoweringTest, Int64LtU) {
461 TestComparison(machine()->Uint64LessThan(), IsUint32LessThan,
462 IsUint32LessThan);
463}
464// kExprI64LeU:
465TEST_F(Int64LoweringTest, Int64LeU) {
466 TestComparison(machine()->Uint64LessThanOrEqual(), IsUint32LessThan,
467 IsUint32LessThanOrEqual);
468}
469
470// kExprI32ConvertI64:
471TEST_F(Int64LoweringTest, I32ConvertI64) {
472 LowerGraph(graph()->NewNode(machine()->TruncateInt64ToInt32(),
473 Int64Constant(value(0))),
474 MachineRepresentation::kWord32);
475 EXPECT_THAT(graph()->end()->InputAt(1),
476 IsReturn(IsInt32Constant(low_word_value(0)), start(), start()));
477}
478// kExprI64SConvertI32:
479TEST_F(Int64LoweringTest, I64SConvertI32) {
480 LowerGraph(graph()->NewNode(machine()->ChangeInt32ToInt64(),
481 Int32Constant(low_word_value(0))),
482 MachineRepresentation::kWord64);
483
484 EXPECT_THAT(graph()->end()->InputAt(1),
485 IsReturn2(IsInt32Constant(low_word_value(0)),
486 IsWord32Sar(IsInt32Constant(low_word_value(0)),
487 IsInt32Constant(31)),
488 start(), start()));
489}
490
491TEST_F(Int64LoweringTest, I64SConvertI32_2) {
492 LowerGraph(
493 graph()->NewNode(machine()->ChangeInt32ToInt64(),
494 graph()->NewNode(machine()->TruncateInt64ToInt32(),
495 Int64Constant(value(0)))),
496 MachineRepresentation::kWord64);
497
498 EXPECT_THAT(graph()->end()->InputAt(1),
499 IsReturn2(IsInt32Constant(low_word_value(0)),
500 IsWord32Sar(IsInt32Constant(low_word_value(0)),
501 IsInt32Constant(31)),
502 start(), start()));
503}
504// kExprI64UConvertI32:
505TEST_F(Int64LoweringTest, I64UConvertI32) {
506 LowerGraph(graph()->NewNode(machine()->ChangeUint32ToUint64(),
507 Int32Constant(low_word_value(0))),
508 MachineRepresentation::kWord64);
509
510 EXPECT_THAT(graph()->end()->InputAt(1),
511 IsReturn2(IsInt32Constant(low_word_value(0)), IsInt32Constant(0),
512 start(), start()));
513}
514
515TEST_F(Int64LoweringTest, I64UConvertI32_2) {
516 LowerGraph(
517 graph()->NewNode(machine()->ChangeUint32ToUint64(),
518 graph()->NewNode(machine()->TruncateInt64ToInt32(),
519 Int64Constant(value(0)))),
520 MachineRepresentation::kWord64);
521
522 EXPECT_THAT(graph()->end()->InputAt(1),
523 IsReturn2(IsInt32Constant(low_word_value(0)), IsInt32Constant(0),
524 start(), start()));
525}
526// kExprF64ReinterpretI64:
527TEST_F(Int64LoweringTest, F64ReinterpretI64) {
528 LowerGraph(graph()->NewNode(machine()->BitcastInt64ToFloat64(),
529 Int64Constant(value(0))),
530 MachineRepresentation::kFloat64);
531
532 Capture<Node*> stack_slot_capture;
533 Matcher<Node*> stack_slot_matcher =
534 IsStackSlot(MachineRepresentation::kWord64);
535
536 Capture<Node*> store_capture;
537 Matcher<Node*> store_matcher =
538 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
539 WriteBarrierKind::kNoWriteBarrier),
540 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
541 IsInt32Constant(0), IsInt32Constant(low_word_value(0)),
542 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
543 WriteBarrierKind::kNoWriteBarrier),
544 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
545 IsInt32Constant(4), IsInt32Constant(high_word_value(0)),
546 start(), start()),
547 start());
548
549 EXPECT_THAT(
550 graph()->end()->InputAt(1),
551 IsReturn(IsLoad(MachineType::Float64(),
552 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
553 IsInt32Constant(0),
554 AllOf(CaptureEq(&store_capture), store_matcher), start()),
555 start(), start()));
556}
557// kExprI64ReinterpretF64:
558TEST_F(Int64LoweringTest, I64ReinterpretF64) {
559 LowerGraph(graph()->NewNode(machine()->BitcastFloat64ToInt64(),
560 Float64Constant(bit_cast<double>(value(0)))),
561 MachineRepresentation::kWord64);
562
563 Capture<Node*> stack_slot;
564 Matcher<Node*> stack_slot_matcher =
565 IsStackSlot(MachineRepresentation::kWord64);
566
567 Capture<Node*> store;
568 Matcher<Node*> store_matcher = IsStore(
569 StoreRepresentation(MachineRepresentation::kFloat64,
570 WriteBarrierKind::kNoWriteBarrier),
571 AllOf(CaptureEq(&stack_slot), stack_slot_matcher), IsInt32Constant(0),
572 IsFloat64Constant(bit_cast<double>(value(0))), start(), start());
573
574 EXPECT_THAT(
575 graph()->end()->InputAt(1),
576 IsReturn2(IsLoad(MachineType::Int32(),
577 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
578 IsInt32Constant(0),
579 AllOf(CaptureEq(&store), store_matcher), start()),
580 IsLoad(MachineType::Int32(),
581 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
582 IsInt32Constant(0x4),
583 AllOf(CaptureEq(&store), store_matcher), start()),
584 start(), start()));
585}
586// kExprI64Clz:
587TEST_F(Int64LoweringTest, I64Clz) {
588 LowerGraph(graph()->NewNode(machine()->Word64Clz(), Int64Constant(value(0))),
589 MachineRepresentation::kWord64);
590
591 Capture<Node*> branch_capture;
592 Matcher<Node*> branch_matcher = IsBranch(
593 IsWord32Equal(IsInt32Constant(high_word_value(0)), IsInt32Constant(0)),
594 start());
595
596 EXPECT_THAT(
597 graph()->end()->InputAt(1),
598 IsReturn2(
599 IsPhi(MachineRepresentation::kWord32,
600 IsInt32Add(IsWord32Clz(IsInt32Constant(low_word_value(0))),
601 IsInt32Constant(32)),
602 IsWord32Clz(IsInt32Constant(high_word_value(0))),
603 IsMerge(
604 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
605 IsIfFalse(
606 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
607 IsInt32Constant(0), start(), start()));
608}
609// kExprI64Ctz:
610TEST_F(Int64LoweringTest, I64Ctz) {
611 LowerGraph(graph()->NewNode(machine()->Word64CtzPlaceholder(),
612 Int64Constant(value(0))),
613 MachineRepresentation::kWord64);
614 Capture<Node*> branch_capture;
615 Matcher<Node*> branch_matcher = IsBranch(
616 IsWord32Equal(IsInt32Constant(low_word_value(0)), IsInt32Constant(0)),
617 start());
618 EXPECT_THAT(
619 graph()->end()->InputAt(1),
620 IsReturn2(
621 IsPhi(MachineRepresentation::kWord32,
622 IsInt32Add(IsWord32Ctz(IsInt32Constant(high_word_value(0))),
623 IsInt32Constant(32)),
624 IsWord32Ctz(IsInt32Constant(low_word_value(0))),
625 IsMerge(
626 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
627 IsIfFalse(
628 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
629 IsInt32Constant(0), start(), start()));
630}
631// kExprI64Popcnt:
632
633TEST_F(Int64LoweringTest, Dfs) {
634 Node* common = Int64Constant(value(0));
635 LowerGraph(graph()->NewNode(machine()->Word64And(), common,
636 graph()->NewNode(machine()->Word64And(), common,
637 Int64Constant(value(1)))),
638 MachineRepresentation::kWord64);
639
640 EXPECT_THAT(
641 graph()->end()->InputAt(1),
642 IsReturn2(IsWord32And(IsInt32Constant(low_word_value(0)),
643 IsWord32And(IsInt32Constant(low_word_value(0)),
644 IsInt32Constant(low_word_value(1)))),
645 IsWord32And(IsInt32Constant(high_word_value(0)),
646 IsWord32And(IsInt32Constant(high_word_value(0)),
647 IsInt32Constant(high_word_value(1)))),
648 start(), start()));
649}
650
651TEST_F(Int64LoweringTest, I64Popcnt) {
652 LowerGraph(graph()->NewNode(machine()->Word64PopcntPlaceholder(),
653 Int64Constant(value(0))),
654 MachineRepresentation::kWord64);
655
656 EXPECT_THAT(
657 graph()->end()->InputAt(1),
658 IsReturn2(IsInt32Add(IsWord32Popcnt(IsInt32Constant(low_word_value(0))),
659 IsWord32Popcnt(IsInt32Constant(high_word_value(0)))),
660 IsInt32Constant(0), start(), start()));
661}
662
663TEST_F(Int64LoweringTest, I64Ror) {
664 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
665 Parameter(0)),
666 MachineRepresentation::kWord64, MachineRepresentation::kWord64, 1);
667
668 Matcher<Node*> branch_lt32_matcher =
669 IsBranch(IsInt32LessThan(IsParameter(0), IsInt32Constant(32)), start());
670
671 Matcher<Node*> low_input_matcher = IsPhi(
672 MachineRepresentation::kWord32, IsInt32Constant(low_word_value(0)),
673 IsInt32Constant(high_word_value(0)),
674 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
675
676 Matcher<Node*> high_input_matcher = IsPhi(
677 MachineRepresentation::kWord32, IsInt32Constant(high_word_value(0)),
678 IsInt32Constant(low_word_value(0)),
679 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
680
681 Matcher<Node*> shift_matcher =
682 IsWord32And(IsParameter(0), IsInt32Constant(0x1f));
683
684 Matcher<Node*> bit_mask_matcher = IsWord32Shl(
685 IsWord32Sar(IsInt32Constant(std::numeric_limits<int32_t>::min()),
686 shift_matcher),
687 IsInt32Constant(1));
688
689 Matcher<Node*> inv_mask_matcher =
690 IsWord32Xor(bit_mask_matcher, IsInt32Constant(-1));
691
692 EXPECT_THAT(
693 graph()->end()->InputAt(1),
694 IsReturn2(
695 IsWord32Or(IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
696 inv_mask_matcher),
697 IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
698 bit_mask_matcher)),
699 IsWord32Or(IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
700 inv_mask_matcher),
701 IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
702 bit_mask_matcher)),
703 start(), start()));
704}
705
706TEST_F(Int64LoweringTest, I64Ror_0) {
707 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
708 Int32Constant(0)),
709 MachineRepresentation::kWord64);
710
711 EXPECT_THAT(graph()->end()->InputAt(1),
712 IsReturn2(IsInt32Constant(low_word_value(0)),
713 IsInt32Constant(high_word_value(0)), start(), start()));
714}
715
716TEST_F(Int64LoweringTest, I64Ror_32) {
717 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
718 Int32Constant(32)),
719 MachineRepresentation::kWord64);
720
721 EXPECT_THAT(graph()->end()->InputAt(1),
722 IsReturn2(IsInt32Constant(high_word_value(0)),
723 IsInt32Constant(low_word_value(0)), start(), start()));
724}
725
726TEST_F(Int64LoweringTest, I64Ror_11) {
727 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
728 Int32Constant(11)),
729 MachineRepresentation::kWord64);
730
731 EXPECT_THAT(
732 graph()->end()->InputAt(1),
733 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
734 IsInt32Constant(11)),
735 IsWord32Shl(IsInt32Constant(high_word_value(0)),
736 IsInt32Constant(21))),
737 IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
738 IsInt32Constant(11)),
739 IsWord32Shl(IsInt32Constant(low_word_value(0)),
740 IsInt32Constant(21))),
741 start(), start()));
742}
743
744TEST_F(Int64LoweringTest, I64Ror_43) {
745 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
746 Int32Constant(43)),
747 MachineRepresentation::kWord64);
748
749 EXPECT_THAT(
750 graph()->end()->InputAt(1),
751 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
752 IsInt32Constant(11)),
753 IsWord32Shl(IsInt32Constant(low_word_value(0)),
754 IsInt32Constant(21))),
755 IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
756 IsInt32Constant(11)),
757 IsWord32Shl(IsInt32Constant(high_word_value(0)),
758 IsInt32Constant(21))),
759 start(), start()));
760}
761
762TEST_F(Int64LoweringTest, I64PhiWord64) {
763 LowerGraph(graph()->NewNode(common()->Phi(MachineRepresentation::kWord64, 2),
764 Int64Constant(value(0)), Int64Constant(value(1)),
765 start()),
766 MachineRepresentation::kWord64);
767
768 EXPECT_THAT(graph()->end()->InputAt(1),
769 IsReturn2(IsPhi(MachineRepresentation::kWord32,
770 IsInt32Constant(low_word_value(0)),
771 IsInt32Constant(low_word_value(1)), start()),
772 IsPhi(MachineRepresentation::kWord32,
773 IsInt32Constant(high_word_value(0)),
774 IsInt32Constant(high_word_value(1)), start()),
775 start(), start()));
776}
777
778void TestPhi(Int64LoweringTest* test, MachineRepresentation rep, Node* v1,
779 Node* v2) {
780 test->LowerGraph(test->graph()->NewNode(test->common()->Phi(rep, 2), v1, v2,
781 test->start()),
782 rep);
783
784 EXPECT_THAT(test->graph()->end()->InputAt(1),
785 IsReturn(IsPhi(rep, v1, v2, test->start()), test->start(),
786 test->start()));
787}
788
789TEST_F(Int64LoweringTest, I64PhiFloat32) {
790 TestPhi(this, MachineRepresentation::kFloat32, Float32Constant(1.5),
791 Float32Constant(2.5));
792}
793
794TEST_F(Int64LoweringTest, I64PhiFloat64) {
795 TestPhi(this, MachineRepresentation::kFloat64, Float32Constant(1.5),
796 Float32Constant(2.5));
797}
798
799TEST_F(Int64LoweringTest, I64PhiWord32) {
800 TestPhi(this, MachineRepresentation::kWord32, Float32Constant(1),
801 Float32Constant(2));
802}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100803} // namespace compiler
804} // namespace internal
805} // namespace v8