blob: 8bc02c542a988b12368a6961e0925f3d747ad78a [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 +0100304TEST_F(Int64LoweringTest, Int64Add) {
305 LowerGraph(graph()->NewNode(machine()->Int64Add(), Int64Constant(value(0)),
306 Int64Constant(value(1))),
307 MachineRepresentation::kWord64);
308
309 Capture<Node*> add;
310 Matcher<Node*> add_matcher = IsInt32PairAdd(
311 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
312 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
313
314 EXPECT_THAT(graph()->end()->InputAt(1),
315 IsReturn2(IsProjection(0, AllOf(CaptureEq(&add), add_matcher)),
316 IsProjection(1, AllOf(CaptureEq(&add), add_matcher)),
317 start(), start()));
318}
Ben Murdochc5610432016-08-08 18:44:38 +0100319
Ben Murdochda12d292016-06-02 14:46:10 +0100320TEST_F(Int64LoweringTest, Int64Sub) {
321 LowerGraph(graph()->NewNode(machine()->Int64Sub(), Int64Constant(value(0)),
322 Int64Constant(value(1))),
323 MachineRepresentation::kWord64);
324
325 Capture<Node*> sub;
326 Matcher<Node*> sub_matcher = IsInt32PairSub(
327 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
328 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
329
330 EXPECT_THAT(graph()->end()->InputAt(1),
331 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sub), sub_matcher)),
332 IsProjection(1, AllOf(CaptureEq(&sub), sub_matcher)),
333 start(), start()));
334}
335
Ben Murdochda12d292016-06-02 14:46:10 +0100336TEST_F(Int64LoweringTest, Int64Mul) {
337 LowerGraph(graph()->NewNode(machine()->Int64Mul(), Int64Constant(value(0)),
338 Int64Constant(value(1))),
339 MachineRepresentation::kWord64);
340
341 Capture<Node*> mul_capture;
342 Matcher<Node*> mul_matcher = IsInt32PairMul(
343 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
344 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
345
346 EXPECT_THAT(
347 graph()->end()->InputAt(1),
348 IsReturn2(IsProjection(0, AllOf(CaptureEq(&mul_capture), mul_matcher)),
349 IsProjection(1, AllOf(CaptureEq(&mul_capture), mul_matcher)),
350 start(), start()));
351}
352
Ben Murdochda12d292016-06-02 14:46:10 +0100353TEST_F(Int64LoweringTest, Int64Ior) {
354 LowerGraph(graph()->NewNode(machine()->Word64Or(), Int64Constant(value(0)),
355 Int64Constant(value(1))),
356 MachineRepresentation::kWord64);
357 EXPECT_THAT(graph()->end()->InputAt(1),
358 IsReturn2(IsWord32Or(IsInt32Constant(low_word_value(0)),
359 IsInt32Constant(low_word_value(1))),
360 IsWord32Or(IsInt32Constant(high_word_value(0)),
361 IsInt32Constant(high_word_value(1))),
362 start(), start()));
363}
364
Ben Murdochda12d292016-06-02 14:46:10 +0100365TEST_F(Int64LoweringTest, Int64Xor) {
366 LowerGraph(graph()->NewNode(machine()->Word64Xor(), Int64Constant(value(0)),
367 Int64Constant(value(1))),
368 MachineRepresentation::kWord64);
369 EXPECT_THAT(graph()->end()->InputAt(1),
370 IsReturn2(IsWord32Xor(IsInt32Constant(low_word_value(0)),
371 IsInt32Constant(low_word_value(1))),
372 IsWord32Xor(IsInt32Constant(high_word_value(0)),
373 IsInt32Constant(high_word_value(1))),
374 start(), start()));
375}
Ben Murdochc5610432016-08-08 18:44:38 +0100376
Ben Murdochda12d292016-06-02 14:46:10 +0100377TEST_F(Int64LoweringTest, Int64Shl) {
378 LowerGraph(graph()->NewNode(machine()->Word64Shl(), Int64Constant(value(0)),
379 Int64Constant(value(1))),
380 MachineRepresentation::kWord64);
381
382 Capture<Node*> shl;
383 Matcher<Node*> shl_matcher = IsWord32PairShl(
384 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
385 IsInt32Constant(low_word_value(1)));
386
387 EXPECT_THAT(graph()->end()->InputAt(1),
388 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shl), shl_matcher)),
389 IsProjection(1, AllOf(CaptureEq(&shl), shl_matcher)),
390 start(), start()));
391}
Ben Murdochc5610432016-08-08 18:44:38 +0100392
Ben Murdochda12d292016-06-02 14:46:10 +0100393TEST_F(Int64LoweringTest, Int64ShrU) {
394 LowerGraph(graph()->NewNode(machine()->Word64Shr(), Int64Constant(value(0)),
395 Int64Constant(value(1))),
396 MachineRepresentation::kWord64);
397
398 Capture<Node*> shr;
399 Matcher<Node*> shr_matcher = IsWord32PairShr(
400 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
401 IsInt32Constant(low_word_value(1)));
402
403 EXPECT_THAT(graph()->end()->InputAt(1),
404 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shr), shr_matcher)),
405 IsProjection(1, AllOf(CaptureEq(&shr), shr_matcher)),
406 start(), start()));
407}
Ben Murdochc5610432016-08-08 18:44:38 +0100408
Ben Murdochda12d292016-06-02 14:46:10 +0100409TEST_F(Int64LoweringTest, Int64ShrS) {
410 LowerGraph(graph()->NewNode(machine()->Word64Sar(), Int64Constant(value(0)),
411 Int64Constant(value(1))),
412 MachineRepresentation::kWord64);
413
414 Capture<Node*> sar;
415 Matcher<Node*> sar_matcher = IsWord32PairSar(
416 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
417 IsInt32Constant(low_word_value(1)));
418
419 EXPECT_THAT(graph()->end()->InputAt(1),
420 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sar), sar_matcher)),
421 IsProjection(1, AllOf(CaptureEq(&sar), sar_matcher)),
422 start(), start()));
423}
Ben Murdochc5610432016-08-08 18:44:38 +0100424
Ben Murdochda12d292016-06-02 14:46:10 +0100425TEST_F(Int64LoweringTest, Int64Eq) {
426 LowerGraph(graph()->NewNode(machine()->Word64Equal(), Int64Constant(value(0)),
427 Int64Constant(value(1))),
428 MachineRepresentation::kWord32);
429 EXPECT_THAT(
430 graph()->end()->InputAt(1),
431 IsReturn(IsWord32Equal(
432 IsWord32Or(IsWord32Xor(IsInt32Constant(low_word_value(0)),
433 IsInt32Constant(low_word_value(1))),
434 IsWord32Xor(IsInt32Constant(high_word_value(0)),
435 IsInt32Constant(high_word_value(1)))),
436 IsInt32Constant(0)),
437 start(), start()));
438}
439
Ben Murdochda12d292016-06-02 14:46:10 +0100440TEST_F(Int64LoweringTest, Int64LtS) {
441 TestComparison(machine()->Int64LessThan(), IsInt32LessThan, IsUint32LessThan);
442}
Ben Murdochc5610432016-08-08 18:44:38 +0100443
Ben Murdochda12d292016-06-02 14:46:10 +0100444TEST_F(Int64LoweringTest, Int64LeS) {
445 TestComparison(machine()->Int64LessThanOrEqual(), IsInt32LessThan,
446 IsUint32LessThanOrEqual);
447}
Ben Murdochc5610432016-08-08 18:44:38 +0100448
Ben Murdochda12d292016-06-02 14:46:10 +0100449TEST_F(Int64LoweringTest, Int64LtU) {
450 TestComparison(machine()->Uint64LessThan(), IsUint32LessThan,
451 IsUint32LessThan);
452}
Ben Murdochc5610432016-08-08 18:44:38 +0100453
Ben Murdochda12d292016-06-02 14:46:10 +0100454TEST_F(Int64LoweringTest, Int64LeU) {
455 TestComparison(machine()->Uint64LessThanOrEqual(), IsUint32LessThan,
456 IsUint32LessThanOrEqual);
457}
458
Ben Murdochda12d292016-06-02 14:46:10 +0100459TEST_F(Int64LoweringTest, I32ConvertI64) {
460 LowerGraph(graph()->NewNode(machine()->TruncateInt64ToInt32(),
461 Int64Constant(value(0))),
462 MachineRepresentation::kWord32);
463 EXPECT_THAT(graph()->end()->InputAt(1),
464 IsReturn(IsInt32Constant(low_word_value(0)), start(), start()));
465}
Ben Murdochc5610432016-08-08 18:44:38 +0100466
Ben Murdochda12d292016-06-02 14:46:10 +0100467TEST_F(Int64LoweringTest, I64SConvertI32) {
468 LowerGraph(graph()->NewNode(machine()->ChangeInt32ToInt64(),
469 Int32Constant(low_word_value(0))),
470 MachineRepresentation::kWord64);
471
472 EXPECT_THAT(graph()->end()->InputAt(1),
473 IsReturn2(IsInt32Constant(low_word_value(0)),
474 IsWord32Sar(IsInt32Constant(low_word_value(0)),
475 IsInt32Constant(31)),
476 start(), start()));
477}
478
479TEST_F(Int64LoweringTest, I64SConvertI32_2) {
480 LowerGraph(
481 graph()->NewNode(machine()->ChangeInt32ToInt64(),
482 graph()->NewNode(machine()->TruncateInt64ToInt32(),
483 Int64Constant(value(0)))),
484 MachineRepresentation::kWord64);
485
486 EXPECT_THAT(graph()->end()->InputAt(1),
487 IsReturn2(IsInt32Constant(low_word_value(0)),
488 IsWord32Sar(IsInt32Constant(low_word_value(0)),
489 IsInt32Constant(31)),
490 start(), start()));
491}
Ben Murdochc5610432016-08-08 18:44:38 +0100492
Ben Murdochda12d292016-06-02 14:46:10 +0100493TEST_F(Int64LoweringTest, I64UConvertI32) {
494 LowerGraph(graph()->NewNode(machine()->ChangeUint32ToUint64(),
495 Int32Constant(low_word_value(0))),
496 MachineRepresentation::kWord64);
497
498 EXPECT_THAT(graph()->end()->InputAt(1),
499 IsReturn2(IsInt32Constant(low_word_value(0)), IsInt32Constant(0),
500 start(), start()));
501}
502
503TEST_F(Int64LoweringTest, I64UConvertI32_2) {
504 LowerGraph(
505 graph()->NewNode(machine()->ChangeUint32ToUint64(),
506 graph()->NewNode(machine()->TruncateInt64ToInt32(),
507 Int64Constant(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}
Ben Murdochc5610432016-08-08 18:44:38 +0100514
Ben Murdochda12d292016-06-02 14:46:10 +0100515TEST_F(Int64LoweringTest, F64ReinterpretI64) {
516 LowerGraph(graph()->NewNode(machine()->BitcastInt64ToFloat64(),
517 Int64Constant(value(0))),
518 MachineRepresentation::kFloat64);
519
520 Capture<Node*> stack_slot_capture;
521 Matcher<Node*> stack_slot_matcher =
522 IsStackSlot(MachineRepresentation::kWord64);
523
524 Capture<Node*> store_capture;
525 Matcher<Node*> store_matcher =
526 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
527 WriteBarrierKind::kNoWriteBarrier),
528 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
529 IsInt32Constant(0), IsInt32Constant(low_word_value(0)),
530 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
531 WriteBarrierKind::kNoWriteBarrier),
532 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
533 IsInt32Constant(4), IsInt32Constant(high_word_value(0)),
534 start(), start()),
535 start());
536
537 EXPECT_THAT(
538 graph()->end()->InputAt(1),
539 IsReturn(IsLoad(MachineType::Float64(),
540 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
541 IsInt32Constant(0),
542 AllOf(CaptureEq(&store_capture), store_matcher), start()),
543 start(), start()));
544}
Ben Murdochc5610432016-08-08 18:44:38 +0100545
Ben Murdochda12d292016-06-02 14:46:10 +0100546TEST_F(Int64LoweringTest, I64ReinterpretF64) {
547 LowerGraph(graph()->NewNode(machine()->BitcastFloat64ToInt64(),
548 Float64Constant(bit_cast<double>(value(0)))),
549 MachineRepresentation::kWord64);
550
551 Capture<Node*> stack_slot;
552 Matcher<Node*> stack_slot_matcher =
553 IsStackSlot(MachineRepresentation::kWord64);
554
555 Capture<Node*> store;
556 Matcher<Node*> store_matcher = IsStore(
557 StoreRepresentation(MachineRepresentation::kFloat64,
558 WriteBarrierKind::kNoWriteBarrier),
559 AllOf(CaptureEq(&stack_slot), stack_slot_matcher), IsInt32Constant(0),
560 IsFloat64Constant(bit_cast<double>(value(0))), start(), start());
561
562 EXPECT_THAT(
563 graph()->end()->InputAt(1),
564 IsReturn2(IsLoad(MachineType::Int32(),
565 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
566 IsInt32Constant(0),
567 AllOf(CaptureEq(&store), store_matcher), start()),
568 IsLoad(MachineType::Int32(),
569 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
570 IsInt32Constant(0x4),
571 AllOf(CaptureEq(&store), store_matcher), start()),
572 start(), start()));
573}
Ben Murdochc5610432016-08-08 18:44:38 +0100574
Ben Murdochda12d292016-06-02 14:46:10 +0100575TEST_F(Int64LoweringTest, I64Clz) {
576 LowerGraph(graph()->NewNode(machine()->Word64Clz(), Int64Constant(value(0))),
577 MachineRepresentation::kWord64);
578
579 Capture<Node*> branch_capture;
580 Matcher<Node*> branch_matcher = IsBranch(
581 IsWord32Equal(IsInt32Constant(high_word_value(0)), IsInt32Constant(0)),
582 start());
583
584 EXPECT_THAT(
585 graph()->end()->InputAt(1),
586 IsReturn2(
587 IsPhi(MachineRepresentation::kWord32,
588 IsInt32Add(IsWord32Clz(IsInt32Constant(low_word_value(0))),
589 IsInt32Constant(32)),
590 IsWord32Clz(IsInt32Constant(high_word_value(0))),
591 IsMerge(
592 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
593 IsIfFalse(
594 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
595 IsInt32Constant(0), start(), start()));
596}
Ben Murdochc5610432016-08-08 18:44:38 +0100597
Ben Murdochda12d292016-06-02 14:46:10 +0100598TEST_F(Int64LoweringTest, I64Ctz) {
599 LowerGraph(graph()->NewNode(machine()->Word64CtzPlaceholder(),
600 Int64Constant(value(0))),
601 MachineRepresentation::kWord64);
602 Capture<Node*> branch_capture;
603 Matcher<Node*> branch_matcher = IsBranch(
604 IsWord32Equal(IsInt32Constant(low_word_value(0)), IsInt32Constant(0)),
605 start());
606 EXPECT_THAT(
607 graph()->end()->InputAt(1),
608 IsReturn2(
609 IsPhi(MachineRepresentation::kWord32,
610 IsInt32Add(IsWord32Ctz(IsInt32Constant(high_word_value(0))),
611 IsInt32Constant(32)),
612 IsWord32Ctz(IsInt32Constant(low_word_value(0))),
613 IsMerge(
614 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
615 IsIfFalse(
616 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
617 IsInt32Constant(0), start(), start()));
618}
Ben Murdochda12d292016-06-02 14:46:10 +0100619
620TEST_F(Int64LoweringTest, Dfs) {
621 Node* common = Int64Constant(value(0));
622 LowerGraph(graph()->NewNode(machine()->Word64And(), common,
623 graph()->NewNode(machine()->Word64And(), common,
624 Int64Constant(value(1)))),
625 MachineRepresentation::kWord64);
626
627 EXPECT_THAT(
628 graph()->end()->InputAt(1),
629 IsReturn2(IsWord32And(IsInt32Constant(low_word_value(0)),
630 IsWord32And(IsInt32Constant(low_word_value(0)),
631 IsInt32Constant(low_word_value(1)))),
632 IsWord32And(IsInt32Constant(high_word_value(0)),
633 IsWord32And(IsInt32Constant(high_word_value(0)),
634 IsInt32Constant(high_word_value(1)))),
635 start(), start()));
636}
637
638TEST_F(Int64LoweringTest, I64Popcnt) {
639 LowerGraph(graph()->NewNode(machine()->Word64PopcntPlaceholder(),
640 Int64Constant(value(0))),
641 MachineRepresentation::kWord64);
642
643 EXPECT_THAT(
644 graph()->end()->InputAt(1),
645 IsReturn2(IsInt32Add(IsWord32Popcnt(IsInt32Constant(low_word_value(0))),
646 IsWord32Popcnt(IsInt32Constant(high_word_value(0)))),
647 IsInt32Constant(0), start(), start()));
648}
649
650TEST_F(Int64LoweringTest, I64Ror) {
651 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
652 Parameter(0)),
653 MachineRepresentation::kWord64, MachineRepresentation::kWord64, 1);
654
655 Matcher<Node*> branch_lt32_matcher =
656 IsBranch(IsInt32LessThan(IsParameter(0), IsInt32Constant(32)), start());
657
658 Matcher<Node*> low_input_matcher = IsPhi(
659 MachineRepresentation::kWord32, IsInt32Constant(low_word_value(0)),
660 IsInt32Constant(high_word_value(0)),
661 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
662
663 Matcher<Node*> high_input_matcher = IsPhi(
664 MachineRepresentation::kWord32, IsInt32Constant(high_word_value(0)),
665 IsInt32Constant(low_word_value(0)),
666 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
667
668 Matcher<Node*> shift_matcher =
669 IsWord32And(IsParameter(0), IsInt32Constant(0x1f));
670
671 Matcher<Node*> bit_mask_matcher = IsWord32Shl(
672 IsWord32Sar(IsInt32Constant(std::numeric_limits<int32_t>::min()),
673 shift_matcher),
674 IsInt32Constant(1));
675
676 Matcher<Node*> inv_mask_matcher =
677 IsWord32Xor(bit_mask_matcher, IsInt32Constant(-1));
678
679 EXPECT_THAT(
680 graph()->end()->InputAt(1),
681 IsReturn2(
682 IsWord32Or(IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
683 inv_mask_matcher),
684 IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
685 bit_mask_matcher)),
686 IsWord32Or(IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
687 inv_mask_matcher),
688 IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
689 bit_mask_matcher)),
690 start(), start()));
691}
692
693TEST_F(Int64LoweringTest, I64Ror_0) {
694 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
695 Int32Constant(0)),
696 MachineRepresentation::kWord64);
697
698 EXPECT_THAT(graph()->end()->InputAt(1),
699 IsReturn2(IsInt32Constant(low_word_value(0)),
700 IsInt32Constant(high_word_value(0)), start(), start()));
701}
702
703TEST_F(Int64LoweringTest, I64Ror_32) {
704 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
705 Int32Constant(32)),
706 MachineRepresentation::kWord64);
707
708 EXPECT_THAT(graph()->end()->InputAt(1),
709 IsReturn2(IsInt32Constant(high_word_value(0)),
710 IsInt32Constant(low_word_value(0)), start(), start()));
711}
712
713TEST_F(Int64LoweringTest, I64Ror_11) {
714 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
715 Int32Constant(11)),
716 MachineRepresentation::kWord64);
717
718 EXPECT_THAT(
719 graph()->end()->InputAt(1),
720 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
721 IsInt32Constant(11)),
722 IsWord32Shl(IsInt32Constant(high_word_value(0)),
723 IsInt32Constant(21))),
724 IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
725 IsInt32Constant(11)),
726 IsWord32Shl(IsInt32Constant(low_word_value(0)),
727 IsInt32Constant(21))),
728 start(), start()));
729}
730
731TEST_F(Int64LoweringTest, I64Ror_43) {
732 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
733 Int32Constant(43)),
734 MachineRepresentation::kWord64);
735
736 EXPECT_THAT(
737 graph()->end()->InputAt(1),
738 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
739 IsInt32Constant(11)),
740 IsWord32Shl(IsInt32Constant(low_word_value(0)),
741 IsInt32Constant(21))),
742 IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
743 IsInt32Constant(11)),
744 IsWord32Shl(IsInt32Constant(high_word_value(0)),
745 IsInt32Constant(21))),
746 start(), start()));
747}
748
749TEST_F(Int64LoweringTest, I64PhiWord64) {
750 LowerGraph(graph()->NewNode(common()->Phi(MachineRepresentation::kWord64, 2),
751 Int64Constant(value(0)), Int64Constant(value(1)),
752 start()),
753 MachineRepresentation::kWord64);
754
755 EXPECT_THAT(graph()->end()->InputAt(1),
756 IsReturn2(IsPhi(MachineRepresentation::kWord32,
757 IsInt32Constant(low_word_value(0)),
758 IsInt32Constant(low_word_value(1)), start()),
759 IsPhi(MachineRepresentation::kWord32,
760 IsInt32Constant(high_word_value(0)),
761 IsInt32Constant(high_word_value(1)), start()),
762 start(), start()));
763}
764
765void TestPhi(Int64LoweringTest* test, MachineRepresentation rep, Node* v1,
766 Node* v2) {
767 test->LowerGraph(test->graph()->NewNode(test->common()->Phi(rep, 2), v1, v2,
768 test->start()),
769 rep);
770
771 EXPECT_THAT(test->graph()->end()->InputAt(1),
772 IsReturn(IsPhi(rep, v1, v2, test->start()), test->start(),
773 test->start()));
774}
775
776TEST_F(Int64LoweringTest, I64PhiFloat32) {
777 TestPhi(this, MachineRepresentation::kFloat32, Float32Constant(1.5),
778 Float32Constant(2.5));
779}
780
781TEST_F(Int64LoweringTest, I64PhiFloat64) {
782 TestPhi(this, MachineRepresentation::kFloat64, Float32Constant(1.5),
783 Float32Constant(2.5));
784}
785
786TEST_F(Int64LoweringTest, I64PhiWord32) {
787 TestPhi(this, MachineRepresentation::kWord32, Float32Constant(1),
788 Float32Constant(2));
789}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100790} // namespace compiler
791} // namespace internal
792} // namespace v8