blob: 804c399b40036f8473da61e41364d5fa7832b476 [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;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100136#if defined(V8_TARGET_LITTLE_ENDIAN)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100137 Matcher<Node*> high_word_load_matcher =
138 IsLoad(MachineType::Int32(), IsInt32Constant(base),
139 IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)), start(),
140 start());
141
142 EXPECT_THAT(
143 graph()->end()->InputAt(1),
144 IsReturn2(IsLoad(MachineType::Int32(), IsInt32Constant(base),
145 IsInt32Constant(index), AllOf(CaptureEq(&high_word_load),
146 high_word_load_matcher),
147 start()),
148 AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
149 start(), start()));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100150#elif defined(V8_TARGET_BIG_ENDIAN)
151 Matcher<Node*> high_word_load_matcher =
152 IsLoad(MachineType::Int32(), IsInt32Constant(base),
153 IsInt32Constant(index), start(), start());
154
155 EXPECT_THAT(
156 graph()->end()->InputAt(1),
157 IsReturn2(
158 IsLoad(MachineType::Int32(), IsInt32Constant(base),
159 IsInt32Add(IsInt32Constant(index), IsInt32Constant(0x4)),
160 AllOf(CaptureEq(&high_word_load), high_word_load_matcher),
161 start()),
162 AllOf(CaptureEq(&high_word_load), high_word_load_matcher), start(),
163 start()));
164#endif
Ben Murdoch097c5b22016-05-18 11:27:45 +0100165}
166
167TEST_F(Int64LoweringTest, Int64Store) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100168 // We have to build the TF graph explicitly here because Store does not return
169 // a value.
170
171 int32_t base = 1111;
172 int32_t index = 2222;
173 int32_t return_value = 0x5555;
174
175 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 0);
176 sig_builder.AddReturn(MachineRepresentation::kWord32);
177
178 Node* store = graph()->NewNode(
179 machine()->Store(StoreRepresentation(MachineRepresentation::kWord64,
180 WriteBarrierKind::kNoWriteBarrier)),
181 Int32Constant(base), Int32Constant(index), Int64Constant(value(0)),
182 start(), start());
183
184 Node* ret = graph()->NewNode(common()->Return(), Int32Constant(return_value),
185 store, start());
186
187 NodeProperties::MergeControlToEnd(graph(), common(), ret);
188
189 Int64Lowering lowering(graph(), machine(), common(), zone(),
190 sig_builder.Build());
191 lowering.LowerGraph();
192
193 const StoreRepresentation rep(MachineRepresentation::kWord32,
194 kNoWriteBarrier);
195
Ben Murdoch61f157c2016-09-16 13:49:30 +0100196#if defined(V8_TARGET_LITTLE_ENDIAN)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100197 EXPECT_THAT(
198 graph()->end()->InputAt(1),
199 IsReturn(
200 IsInt32Constant(return_value),
201 IsStore(
202 rep, IsInt32Constant(base), IsInt32Constant(index),
203 IsInt32Constant(low_word_value(0)),
204 IsStore(rep, IsInt32Constant(base),
205 IsInt32Add(IsInt32Constant(index), IsInt32Constant(4)),
206 IsInt32Constant(high_word_value(0)), start(), start()),
207 start()),
208 start()));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100209#elif defined(V8_TARGET_BIG_ENDIAN)
210 EXPECT_THAT(
211 graph()->end()->InputAt(1),
212 IsReturn(
213 IsInt32Constant(return_value),
214 IsStore(
215 rep, IsInt32Constant(base),
216 IsInt32Add(IsInt32Constant(index), IsInt32Constant(4)),
217 IsInt32Constant(low_word_value(0)),
218 IsStore(rep, IsInt32Constant(base), IsInt32Constant(index),
219 IsInt32Constant(high_word_value(0)), start(), start()),
220 start()),
221 start()));
222#endif
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223}
224
225TEST_F(Int64LoweringTest, Int64And) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100226 LowerGraph(graph()->NewNode(machine()->Word64And(), Int64Constant(value(0)),
227 Int64Constant(value(1))),
228 MachineRepresentation::kWord64);
229 EXPECT_THAT(graph()->end()->InputAt(1),
230 IsReturn2(IsWord32And(IsInt32Constant(low_word_value(0)),
231 IsInt32Constant(low_word_value(1))),
232 IsWord32And(IsInt32Constant(high_word_value(0)),
233 IsInt32Constant(high_word_value(1))),
234 start(), start()));
235}
236
237TEST_F(Int64LoweringTest, TruncateInt64ToInt32) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100238 LowerGraph(graph()->NewNode(machine()->TruncateInt64ToInt32(),
239 Int64Constant(value(0))),
240 MachineRepresentation::kWord32);
241 EXPECT_THAT(graph()->end()->InputAt(1),
242 IsReturn(IsInt32Constant(low_word_value(0)), start(), start()));
243}
244
245TEST_F(Int64LoweringTest, Parameter) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100246 LowerGraph(Parameter(0), MachineRepresentation::kWord64,
247 MachineRepresentation::kWord64, 1);
248
249 EXPECT_THAT(graph()->end()->InputAt(1),
250 IsReturn2(IsParameter(0), IsParameter(1), start(), start()));
251}
252
253TEST_F(Int64LoweringTest, Parameter2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100254 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 5);
255 sig_builder.AddReturn(MachineRepresentation::kWord32);
256
257 sig_builder.AddParam(MachineRepresentation::kWord32);
258 sig_builder.AddParam(MachineRepresentation::kWord64);
259 sig_builder.AddParam(MachineRepresentation::kFloat64);
260 sig_builder.AddParam(MachineRepresentation::kWord64);
261 sig_builder.AddParam(MachineRepresentation::kWord32);
262
263 int start_parameter = start()->op()->ValueOutputCount();
264 LowerGraph(Parameter(4), sig_builder.Build());
265
266 EXPECT_THAT(graph()->end()->InputAt(1),
267 IsReturn(IsParameter(6), start(), start()));
268 // The parameter of the start node should increase by 2, because we lowered
269 // two parameter nodes.
270 EXPECT_THAT(start()->op()->ValueOutputCount(), start_parameter + 2);
271}
272
273TEST_F(Int64LoweringTest, CallI64Return) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100274 int32_t function = 0x9999;
275
276 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 0);
277 sig_builder.AddReturn(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 start(), start()),
284 MachineRepresentation::kWord64);
285
286 Capture<Node*> call;
287 Matcher<Node*> call_matcher =
288 IsCall(testing::_, IsInt32Constant(function), start(), start());
289
290 EXPECT_THAT(graph()->end()->InputAt(1),
291 IsReturn2(IsProjection(0, AllOf(CaptureEq(&call), call_matcher)),
292 IsProjection(1, AllOf(CaptureEq(&call), call_matcher)),
293 start(), start()));
294
295 CompareCallDescriptors(
296 OpParameter<const CallDescriptor*>(
297 graph()->end()->InputAt(1)->InputAt(0)->InputAt(0)),
298 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), desc));
299}
300
301TEST_F(Int64LoweringTest, CallI64Parameter) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100302 int32_t function = 0x9999;
303
304 Signature<MachineRepresentation>::Builder sig_builder(zone(), 1, 3);
305 sig_builder.AddReturn(MachineRepresentation::kWord32);
306 sig_builder.AddParam(MachineRepresentation::kWord64);
307 sig_builder.AddParam(MachineRepresentation::kWord32);
308 sig_builder.AddParam(MachineRepresentation::kWord64);
309
310 compiler::CallDescriptor* desc =
311 wasm::ModuleEnv::GetWasmCallDescriptor(zone(), sig_builder.Build());
312
313 LowerGraph(graph()->NewNode(common()->Call(desc), Int32Constant(function),
314 Int64Constant(value(0)),
315 Int32Constant(low_word_value(1)),
316 Int64Constant(value(2)), start(), start()),
317 MachineRepresentation::kWord32);
318
319 EXPECT_THAT(
320 graph()->end()->InputAt(1),
321 IsReturn(IsCall(testing::_, IsInt32Constant(function),
322 IsInt32Constant(low_word_value(0)),
323 IsInt32Constant(high_word_value(0)),
324 IsInt32Constant(low_word_value(1)),
325 IsInt32Constant(low_word_value(2)),
326 IsInt32Constant(high_word_value(2)), start(), start()),
327 start(), start()));
328
329 CompareCallDescriptors(
330 OpParameter<const CallDescriptor*>(
331 graph()->end()->InputAt(1)->InputAt(0)),
332 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), desc));
333}
334
Ben Murdochda12d292016-06-02 14:46:10 +0100335TEST_F(Int64LoweringTest, Int64Add) {
336 LowerGraph(graph()->NewNode(machine()->Int64Add(), Int64Constant(value(0)),
337 Int64Constant(value(1))),
338 MachineRepresentation::kWord64);
339
340 Capture<Node*> add;
341 Matcher<Node*> add_matcher = IsInt32PairAdd(
342 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
343 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
344
345 EXPECT_THAT(graph()->end()->InputAt(1),
346 IsReturn2(IsProjection(0, AllOf(CaptureEq(&add), add_matcher)),
347 IsProjection(1, AllOf(CaptureEq(&add), add_matcher)),
348 start(), start()));
349}
Ben Murdochc5610432016-08-08 18:44:38 +0100350
Ben Murdochda12d292016-06-02 14:46:10 +0100351TEST_F(Int64LoweringTest, Int64Sub) {
352 LowerGraph(graph()->NewNode(machine()->Int64Sub(), Int64Constant(value(0)),
353 Int64Constant(value(1))),
354 MachineRepresentation::kWord64);
355
356 Capture<Node*> sub;
357 Matcher<Node*> sub_matcher = IsInt32PairSub(
358 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
359 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
360
361 EXPECT_THAT(graph()->end()->InputAt(1),
362 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sub), sub_matcher)),
363 IsProjection(1, AllOf(CaptureEq(&sub), sub_matcher)),
364 start(), start()));
365}
366
Ben Murdochda12d292016-06-02 14:46:10 +0100367TEST_F(Int64LoweringTest, Int64Mul) {
368 LowerGraph(graph()->NewNode(machine()->Int64Mul(), Int64Constant(value(0)),
369 Int64Constant(value(1))),
370 MachineRepresentation::kWord64);
371
372 Capture<Node*> mul_capture;
373 Matcher<Node*> mul_matcher = IsInt32PairMul(
374 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
375 IsInt32Constant(low_word_value(1)), IsInt32Constant(high_word_value(1)));
376
377 EXPECT_THAT(
378 graph()->end()->InputAt(1),
379 IsReturn2(IsProjection(0, AllOf(CaptureEq(&mul_capture), mul_matcher)),
380 IsProjection(1, AllOf(CaptureEq(&mul_capture), mul_matcher)),
381 start(), start()));
382}
383
Ben Murdochda12d292016-06-02 14:46:10 +0100384TEST_F(Int64LoweringTest, Int64Ior) {
385 LowerGraph(graph()->NewNode(machine()->Word64Or(), Int64Constant(value(0)),
386 Int64Constant(value(1))),
387 MachineRepresentation::kWord64);
388 EXPECT_THAT(graph()->end()->InputAt(1),
389 IsReturn2(IsWord32Or(IsInt32Constant(low_word_value(0)),
390 IsInt32Constant(low_word_value(1))),
391 IsWord32Or(IsInt32Constant(high_word_value(0)),
392 IsInt32Constant(high_word_value(1))),
393 start(), start()));
394}
395
Ben Murdochda12d292016-06-02 14:46:10 +0100396TEST_F(Int64LoweringTest, Int64Xor) {
397 LowerGraph(graph()->NewNode(machine()->Word64Xor(), Int64Constant(value(0)),
398 Int64Constant(value(1))),
399 MachineRepresentation::kWord64);
400 EXPECT_THAT(graph()->end()->InputAt(1),
401 IsReturn2(IsWord32Xor(IsInt32Constant(low_word_value(0)),
402 IsInt32Constant(low_word_value(1))),
403 IsWord32Xor(IsInt32Constant(high_word_value(0)),
404 IsInt32Constant(high_word_value(1))),
405 start(), start()));
406}
Ben Murdochc5610432016-08-08 18:44:38 +0100407
Ben Murdochda12d292016-06-02 14:46:10 +0100408TEST_F(Int64LoweringTest, Int64Shl) {
409 LowerGraph(graph()->NewNode(machine()->Word64Shl(), Int64Constant(value(0)),
410 Int64Constant(value(1))),
411 MachineRepresentation::kWord64);
412
413 Capture<Node*> shl;
414 Matcher<Node*> shl_matcher = IsWord32PairShl(
415 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
416 IsInt32Constant(low_word_value(1)));
417
418 EXPECT_THAT(graph()->end()->InputAt(1),
419 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shl), shl_matcher)),
420 IsProjection(1, AllOf(CaptureEq(&shl), shl_matcher)),
421 start(), start()));
422}
Ben Murdochc5610432016-08-08 18:44:38 +0100423
Ben Murdochda12d292016-06-02 14:46:10 +0100424TEST_F(Int64LoweringTest, Int64ShrU) {
425 LowerGraph(graph()->NewNode(machine()->Word64Shr(), Int64Constant(value(0)),
426 Int64Constant(value(1))),
427 MachineRepresentation::kWord64);
428
429 Capture<Node*> shr;
430 Matcher<Node*> shr_matcher = IsWord32PairShr(
431 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
432 IsInt32Constant(low_word_value(1)));
433
434 EXPECT_THAT(graph()->end()->InputAt(1),
435 IsReturn2(IsProjection(0, AllOf(CaptureEq(&shr), shr_matcher)),
436 IsProjection(1, AllOf(CaptureEq(&shr), shr_matcher)),
437 start(), start()));
438}
Ben Murdochc5610432016-08-08 18:44:38 +0100439
Ben Murdochda12d292016-06-02 14:46:10 +0100440TEST_F(Int64LoweringTest, Int64ShrS) {
441 LowerGraph(graph()->NewNode(machine()->Word64Sar(), Int64Constant(value(0)),
442 Int64Constant(value(1))),
443 MachineRepresentation::kWord64);
444
445 Capture<Node*> sar;
446 Matcher<Node*> sar_matcher = IsWord32PairSar(
447 IsInt32Constant(low_word_value(0)), IsInt32Constant(high_word_value(0)),
448 IsInt32Constant(low_word_value(1)));
449
450 EXPECT_THAT(graph()->end()->InputAt(1),
451 IsReturn2(IsProjection(0, AllOf(CaptureEq(&sar), sar_matcher)),
452 IsProjection(1, AllOf(CaptureEq(&sar), sar_matcher)),
453 start(), start()));
454}
Ben Murdochc5610432016-08-08 18:44:38 +0100455
Ben Murdochda12d292016-06-02 14:46:10 +0100456TEST_F(Int64LoweringTest, Int64Eq) {
457 LowerGraph(graph()->NewNode(machine()->Word64Equal(), Int64Constant(value(0)),
458 Int64Constant(value(1))),
459 MachineRepresentation::kWord32);
460 EXPECT_THAT(
461 graph()->end()->InputAt(1),
462 IsReturn(IsWord32Equal(
463 IsWord32Or(IsWord32Xor(IsInt32Constant(low_word_value(0)),
464 IsInt32Constant(low_word_value(1))),
465 IsWord32Xor(IsInt32Constant(high_word_value(0)),
466 IsInt32Constant(high_word_value(1)))),
467 IsInt32Constant(0)),
468 start(), start()));
469}
470
Ben Murdochda12d292016-06-02 14:46:10 +0100471TEST_F(Int64LoweringTest, Int64LtS) {
472 TestComparison(machine()->Int64LessThan(), IsInt32LessThan, IsUint32LessThan);
473}
Ben Murdochc5610432016-08-08 18:44:38 +0100474
Ben Murdochda12d292016-06-02 14:46:10 +0100475TEST_F(Int64LoweringTest, Int64LeS) {
476 TestComparison(machine()->Int64LessThanOrEqual(), IsInt32LessThan,
477 IsUint32LessThanOrEqual);
478}
Ben Murdochc5610432016-08-08 18:44:38 +0100479
Ben Murdochda12d292016-06-02 14:46:10 +0100480TEST_F(Int64LoweringTest, Int64LtU) {
481 TestComparison(machine()->Uint64LessThan(), IsUint32LessThan,
482 IsUint32LessThan);
483}
Ben Murdochc5610432016-08-08 18:44:38 +0100484
Ben Murdochda12d292016-06-02 14:46:10 +0100485TEST_F(Int64LoweringTest, Int64LeU) {
486 TestComparison(machine()->Uint64LessThanOrEqual(), IsUint32LessThan,
487 IsUint32LessThanOrEqual);
488}
489
Ben Murdochda12d292016-06-02 14:46:10 +0100490TEST_F(Int64LoweringTest, I32ConvertI64) {
491 LowerGraph(graph()->NewNode(machine()->TruncateInt64ToInt32(),
492 Int64Constant(value(0))),
493 MachineRepresentation::kWord32);
494 EXPECT_THAT(graph()->end()->InputAt(1),
495 IsReturn(IsInt32Constant(low_word_value(0)), start(), start()));
496}
Ben Murdochc5610432016-08-08 18:44:38 +0100497
Ben Murdochda12d292016-06-02 14:46:10 +0100498TEST_F(Int64LoweringTest, I64SConvertI32) {
499 LowerGraph(graph()->NewNode(machine()->ChangeInt32ToInt64(),
500 Int32Constant(low_word_value(0))),
501 MachineRepresentation::kWord64);
502
503 EXPECT_THAT(graph()->end()->InputAt(1),
504 IsReturn2(IsInt32Constant(low_word_value(0)),
505 IsWord32Sar(IsInt32Constant(low_word_value(0)),
506 IsInt32Constant(31)),
507 start(), start()));
508}
509
510TEST_F(Int64LoweringTest, I64SConvertI32_2) {
511 LowerGraph(
512 graph()->NewNode(machine()->ChangeInt32ToInt64(),
513 graph()->NewNode(machine()->TruncateInt64ToInt32(),
514 Int64Constant(value(0)))),
515 MachineRepresentation::kWord64);
516
517 EXPECT_THAT(graph()->end()->InputAt(1),
518 IsReturn2(IsInt32Constant(low_word_value(0)),
519 IsWord32Sar(IsInt32Constant(low_word_value(0)),
520 IsInt32Constant(31)),
521 start(), start()));
522}
Ben Murdochc5610432016-08-08 18:44:38 +0100523
Ben Murdochda12d292016-06-02 14:46:10 +0100524TEST_F(Int64LoweringTest, I64UConvertI32) {
525 LowerGraph(graph()->NewNode(machine()->ChangeUint32ToUint64(),
526 Int32Constant(low_word_value(0))),
527 MachineRepresentation::kWord64);
528
529 EXPECT_THAT(graph()->end()->InputAt(1),
530 IsReturn2(IsInt32Constant(low_word_value(0)), IsInt32Constant(0),
531 start(), start()));
532}
533
534TEST_F(Int64LoweringTest, I64UConvertI32_2) {
535 LowerGraph(
536 graph()->NewNode(machine()->ChangeUint32ToUint64(),
537 graph()->NewNode(machine()->TruncateInt64ToInt32(),
538 Int64Constant(value(0)))),
539 MachineRepresentation::kWord64);
540
541 EXPECT_THAT(graph()->end()->InputAt(1),
542 IsReturn2(IsInt32Constant(low_word_value(0)), IsInt32Constant(0),
543 start(), start()));
544}
Ben Murdochc5610432016-08-08 18:44:38 +0100545
Ben Murdochda12d292016-06-02 14:46:10 +0100546TEST_F(Int64LoweringTest, F64ReinterpretI64) {
547 LowerGraph(graph()->NewNode(machine()->BitcastInt64ToFloat64(),
548 Int64Constant(value(0))),
549 MachineRepresentation::kFloat64);
550
551 Capture<Node*> stack_slot_capture;
552 Matcher<Node*> stack_slot_matcher =
553 IsStackSlot(MachineRepresentation::kWord64);
554
555 Capture<Node*> store_capture;
556 Matcher<Node*> store_matcher =
557 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
558 WriteBarrierKind::kNoWriteBarrier),
559 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100560 IsInt32Constant(Int64Lowering::kLowerWordOffset),
561 IsInt32Constant(low_word_value(0)),
Ben Murdochda12d292016-06-02 14:46:10 +0100562 IsStore(StoreRepresentation(MachineRepresentation::kWord32,
563 WriteBarrierKind::kNoWriteBarrier),
564 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100565 IsInt32Constant(Int64Lowering::kHigherWordOffset),
566 IsInt32Constant(high_word_value(0)), start(), start()),
Ben Murdochda12d292016-06-02 14:46:10 +0100567 start());
568
569 EXPECT_THAT(
570 graph()->end()->InputAt(1),
571 IsReturn(IsLoad(MachineType::Float64(),
572 AllOf(CaptureEq(&stack_slot_capture), stack_slot_matcher),
573 IsInt32Constant(0),
574 AllOf(CaptureEq(&store_capture), store_matcher), start()),
575 start(), start()));
576}
Ben Murdochc5610432016-08-08 18:44:38 +0100577
Ben Murdochda12d292016-06-02 14:46:10 +0100578TEST_F(Int64LoweringTest, I64ReinterpretF64) {
579 LowerGraph(graph()->NewNode(machine()->BitcastFloat64ToInt64(),
580 Float64Constant(bit_cast<double>(value(0)))),
581 MachineRepresentation::kWord64);
582
583 Capture<Node*> stack_slot;
584 Matcher<Node*> stack_slot_matcher =
585 IsStackSlot(MachineRepresentation::kWord64);
586
587 Capture<Node*> store;
588 Matcher<Node*> store_matcher = IsStore(
589 StoreRepresentation(MachineRepresentation::kFloat64,
590 WriteBarrierKind::kNoWriteBarrier),
591 AllOf(CaptureEq(&stack_slot), stack_slot_matcher), IsInt32Constant(0),
592 IsFloat64Constant(bit_cast<double>(value(0))), start(), start());
593
594 EXPECT_THAT(
595 graph()->end()->InputAt(1),
596 IsReturn2(IsLoad(MachineType::Int32(),
597 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100598 IsInt32Constant(Int64Lowering::kLowerWordOffset),
Ben Murdochda12d292016-06-02 14:46:10 +0100599 AllOf(CaptureEq(&store), store_matcher), start()),
600 IsLoad(MachineType::Int32(),
601 AllOf(CaptureEq(&stack_slot), stack_slot_matcher),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100602 IsInt32Constant(Int64Lowering::kHigherWordOffset),
Ben Murdochda12d292016-06-02 14:46:10 +0100603 AllOf(CaptureEq(&store), store_matcher), start()),
604 start(), start()));
605}
Ben Murdochc5610432016-08-08 18:44:38 +0100606
Ben Murdochda12d292016-06-02 14:46:10 +0100607TEST_F(Int64LoweringTest, I64Clz) {
608 LowerGraph(graph()->NewNode(machine()->Word64Clz(), Int64Constant(value(0))),
609 MachineRepresentation::kWord64);
610
611 Capture<Node*> branch_capture;
612 Matcher<Node*> branch_matcher = IsBranch(
613 IsWord32Equal(IsInt32Constant(high_word_value(0)), IsInt32Constant(0)),
614 start());
615
616 EXPECT_THAT(
617 graph()->end()->InputAt(1),
618 IsReturn2(
619 IsPhi(MachineRepresentation::kWord32,
620 IsInt32Add(IsWord32Clz(IsInt32Constant(low_word_value(0))),
621 IsInt32Constant(32)),
622 IsWord32Clz(IsInt32Constant(high_word_value(0))),
623 IsMerge(
624 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
625 IsIfFalse(
626 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
627 IsInt32Constant(0), start(), start()));
628}
Ben Murdochc5610432016-08-08 18:44:38 +0100629
Ben Murdochda12d292016-06-02 14:46:10 +0100630TEST_F(Int64LoweringTest, I64Ctz) {
631 LowerGraph(graph()->NewNode(machine()->Word64CtzPlaceholder(),
632 Int64Constant(value(0))),
633 MachineRepresentation::kWord64);
634 Capture<Node*> branch_capture;
635 Matcher<Node*> branch_matcher = IsBranch(
636 IsWord32Equal(IsInt32Constant(low_word_value(0)), IsInt32Constant(0)),
637 start());
638 EXPECT_THAT(
639 graph()->end()->InputAt(1),
640 IsReturn2(
641 IsPhi(MachineRepresentation::kWord32,
642 IsInt32Add(IsWord32Ctz(IsInt32Constant(high_word_value(0))),
643 IsInt32Constant(32)),
644 IsWord32Ctz(IsInt32Constant(low_word_value(0))),
645 IsMerge(
646 IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
647 IsIfFalse(
648 AllOf(CaptureEq(&branch_capture), branch_matcher)))),
649 IsInt32Constant(0), start(), start()));
650}
Ben Murdochda12d292016-06-02 14:46:10 +0100651
652TEST_F(Int64LoweringTest, Dfs) {
653 Node* common = Int64Constant(value(0));
654 LowerGraph(graph()->NewNode(machine()->Word64And(), common,
655 graph()->NewNode(machine()->Word64And(), common,
656 Int64Constant(value(1)))),
657 MachineRepresentation::kWord64);
658
659 EXPECT_THAT(
660 graph()->end()->InputAt(1),
661 IsReturn2(IsWord32And(IsInt32Constant(low_word_value(0)),
662 IsWord32And(IsInt32Constant(low_word_value(0)),
663 IsInt32Constant(low_word_value(1)))),
664 IsWord32And(IsInt32Constant(high_word_value(0)),
665 IsWord32And(IsInt32Constant(high_word_value(0)),
666 IsInt32Constant(high_word_value(1)))),
667 start(), start()));
668}
669
670TEST_F(Int64LoweringTest, I64Popcnt) {
671 LowerGraph(graph()->NewNode(machine()->Word64PopcntPlaceholder(),
672 Int64Constant(value(0))),
673 MachineRepresentation::kWord64);
674
675 EXPECT_THAT(
676 graph()->end()->InputAt(1),
677 IsReturn2(IsInt32Add(IsWord32Popcnt(IsInt32Constant(low_word_value(0))),
678 IsWord32Popcnt(IsInt32Constant(high_word_value(0)))),
679 IsInt32Constant(0), start(), start()));
680}
681
682TEST_F(Int64LoweringTest, I64Ror) {
683 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
684 Parameter(0)),
685 MachineRepresentation::kWord64, MachineRepresentation::kWord64, 1);
686
687 Matcher<Node*> branch_lt32_matcher =
688 IsBranch(IsInt32LessThan(IsParameter(0), IsInt32Constant(32)), start());
689
690 Matcher<Node*> low_input_matcher = IsPhi(
691 MachineRepresentation::kWord32, IsInt32Constant(low_word_value(0)),
692 IsInt32Constant(high_word_value(0)),
693 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
694
695 Matcher<Node*> high_input_matcher = IsPhi(
696 MachineRepresentation::kWord32, IsInt32Constant(high_word_value(0)),
697 IsInt32Constant(low_word_value(0)),
698 IsMerge(IsIfTrue(branch_lt32_matcher), IsIfFalse(branch_lt32_matcher)));
699
700 Matcher<Node*> shift_matcher =
701 IsWord32And(IsParameter(0), IsInt32Constant(0x1f));
702
703 Matcher<Node*> bit_mask_matcher = IsWord32Shl(
704 IsWord32Sar(IsInt32Constant(std::numeric_limits<int32_t>::min()),
705 shift_matcher),
706 IsInt32Constant(1));
707
708 Matcher<Node*> inv_mask_matcher =
709 IsWord32Xor(bit_mask_matcher, IsInt32Constant(-1));
710
711 EXPECT_THAT(
712 graph()->end()->InputAt(1),
713 IsReturn2(
714 IsWord32Or(IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
715 inv_mask_matcher),
716 IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
717 bit_mask_matcher)),
718 IsWord32Or(IsWord32And(IsWord32Ror(high_input_matcher, shift_matcher),
719 inv_mask_matcher),
720 IsWord32And(IsWord32Ror(low_input_matcher, shift_matcher),
721 bit_mask_matcher)),
722 start(), start()));
723}
724
725TEST_F(Int64LoweringTest, I64Ror_0) {
726 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
727 Int32Constant(0)),
728 MachineRepresentation::kWord64);
729
730 EXPECT_THAT(graph()->end()->InputAt(1),
731 IsReturn2(IsInt32Constant(low_word_value(0)),
732 IsInt32Constant(high_word_value(0)), start(), start()));
733}
734
735TEST_F(Int64LoweringTest, I64Ror_32) {
736 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
737 Int32Constant(32)),
738 MachineRepresentation::kWord64);
739
740 EXPECT_THAT(graph()->end()->InputAt(1),
741 IsReturn2(IsInt32Constant(high_word_value(0)),
742 IsInt32Constant(low_word_value(0)), start(), start()));
743}
744
745TEST_F(Int64LoweringTest, I64Ror_11) {
746 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
747 Int32Constant(11)),
748 MachineRepresentation::kWord64);
749
750 EXPECT_THAT(
751 graph()->end()->InputAt(1),
752 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
753 IsInt32Constant(11)),
754 IsWord32Shl(IsInt32Constant(high_word_value(0)),
755 IsInt32Constant(21))),
756 IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
757 IsInt32Constant(11)),
758 IsWord32Shl(IsInt32Constant(low_word_value(0)),
759 IsInt32Constant(21))),
760 start(), start()));
761}
762
763TEST_F(Int64LoweringTest, I64Ror_43) {
764 LowerGraph(graph()->NewNode(machine()->Word64Ror(), Int64Constant(value(0)),
765 Int32Constant(43)),
766 MachineRepresentation::kWord64);
767
768 EXPECT_THAT(
769 graph()->end()->InputAt(1),
770 IsReturn2(IsWord32Or(IsWord32Shr(IsInt32Constant(high_word_value(0)),
771 IsInt32Constant(11)),
772 IsWord32Shl(IsInt32Constant(low_word_value(0)),
773 IsInt32Constant(21))),
774 IsWord32Or(IsWord32Shr(IsInt32Constant(low_word_value(0)),
775 IsInt32Constant(11)),
776 IsWord32Shl(IsInt32Constant(high_word_value(0)),
777 IsInt32Constant(21))),
778 start(), start()));
779}
780
781TEST_F(Int64LoweringTest, I64PhiWord64) {
782 LowerGraph(graph()->NewNode(common()->Phi(MachineRepresentation::kWord64, 2),
783 Int64Constant(value(0)), Int64Constant(value(1)),
784 start()),
785 MachineRepresentation::kWord64);
786
787 EXPECT_THAT(graph()->end()->InputAt(1),
788 IsReturn2(IsPhi(MachineRepresentation::kWord32,
789 IsInt32Constant(low_word_value(0)),
790 IsInt32Constant(low_word_value(1)), start()),
791 IsPhi(MachineRepresentation::kWord32,
792 IsInt32Constant(high_word_value(0)),
793 IsInt32Constant(high_word_value(1)), start()),
794 start(), start()));
795}
796
797void TestPhi(Int64LoweringTest* test, MachineRepresentation rep, Node* v1,
798 Node* v2) {
799 test->LowerGraph(test->graph()->NewNode(test->common()->Phi(rep, 2), v1, v2,
800 test->start()),
801 rep);
802
803 EXPECT_THAT(test->graph()->end()->InputAt(1),
804 IsReturn(IsPhi(rep, v1, v2, test->start()), test->start(),
805 test->start()));
806}
807
808TEST_F(Int64LoweringTest, I64PhiFloat32) {
809 TestPhi(this, MachineRepresentation::kFloat32, Float32Constant(1.5),
810 Float32Constant(2.5));
811}
812
813TEST_F(Int64LoweringTest, I64PhiFloat64) {
814 TestPhi(this, MachineRepresentation::kFloat64, Float32Constant(1.5),
815 Float32Constant(2.5));
816}
817
818TEST_F(Int64LoweringTest, I64PhiWord32) {
819 TestPhi(this, MachineRepresentation::kWord32, Float32Constant(1),
820 Float32Constant(2));
821}
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822} // namespace compiler
823} // namespace internal
824} // namespace v8