blob: 1c163706f2183eda9b1f10adfad808c659b3add8 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/common-operator.h"
6#include "src/compiler/common-operator-reducer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/compiler/machine-operator.h"
8#include "src/compiler/operator.h"
9#include "src/compiler/simplified-operator.h"
10#include "src/machine-type.h"
11#include "test/unittests/compiler/graph-reducer-unittest.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "test/unittests/compiler/graph-unittest.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "test/unittests/compiler/node-test-utils.h"
14
15using testing::StrictMock;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016
17namespace v8 {
18namespace internal {
19namespace compiler {
20
21class CommonOperatorReducerTest : public GraphTest {
22 public:
23 explicit CommonOperatorReducerTest(int num_parameters = 1)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024 : GraphTest(num_parameters), machine_(zone()), simplified_(zone()) {}
25 ~CommonOperatorReducerTest() override {}
Emily Bernierd0a1eb72015-03-24 16:35:39 -040026
27 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028 Reduction Reduce(
29 AdvancedReducer::Editor* editor, Node* node,
30 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags) {
31 MachineOperatorBuilder machine(zone(), MachineType::PointerRepresentation(),
32 flags);
33 CommonOperatorReducer reducer(editor, graph(), common(), &machine);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040034 return reducer.Reduce(node);
35 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036
37 Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
38 MachineOperatorBuilder::kNoFlags) {
39 StrictMock<MockAdvancedReducerEditor> editor;
40 return Reduce(&editor, node, flags);
41 }
42
43 MachineOperatorBuilder* machine() { return &machine_; }
44 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
45
46 private:
47 MachineOperatorBuilder machine_;
48 SimplifiedOperatorBuilder simplified_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049};
50
51
52namespace {
53
54const BranchHint kBranchHints[] = {BranchHint::kNone, BranchHint::kFalse,
55 BranchHint::kTrue};
56
57
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058const MachineRepresentation kMachineRepresentations[] = {
59 MachineRepresentation::kBit, MachineRepresentation::kWord8,
60 MachineRepresentation::kWord16, MachineRepresentation::kWord32,
61 MachineRepresentation::kWord64, MachineRepresentation::kFloat32,
62 MachineRepresentation::kFloat64, MachineRepresentation::kTagged};
Emily Bernierd0a1eb72015-03-24 16:35:39 -040063
64
65const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
66
67} // namespace
68
69
70// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071// Branch
72
73
74TEST_F(CommonOperatorReducerTest, BranchWithInt32ZeroConstant) {
75 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
76 Node* const control = graph()->start();
77 Node* const branch =
78 graph()->NewNode(common()->Branch(hint), Int32Constant(0), control);
79 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
80 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
81 StrictMock<MockAdvancedReducerEditor> editor;
82 EXPECT_CALL(editor, Replace(if_true, IsDead()));
83 EXPECT_CALL(editor, Replace(if_false, control));
84 Reduction const r = Reduce(&editor, branch);
85 ASSERT_TRUE(r.Changed());
86 EXPECT_THAT(r.replacement(), IsDead());
87 }
88}
89
90
91TEST_F(CommonOperatorReducerTest, BranchWithInt32OneConstant) {
92 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
93 Node* const control = graph()->start();
94 Node* const branch =
95 graph()->NewNode(common()->Branch(hint), Int32Constant(1), control);
96 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
97 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
98 StrictMock<MockAdvancedReducerEditor> editor;
99 EXPECT_CALL(editor, Replace(if_true, control));
100 EXPECT_CALL(editor, Replace(if_false, IsDead()));
101 Reduction const r = Reduce(&editor, branch);
102 ASSERT_TRUE(r.Changed());
103 EXPECT_THAT(r.replacement(), IsDead());
104 }
105}
106
107
108TEST_F(CommonOperatorReducerTest, BranchWithInt64ZeroConstant) {
109 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
110 Node* const control = graph()->start();
111 Node* const branch =
112 graph()->NewNode(common()->Branch(hint), Int64Constant(0), control);
113 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
114 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
115 StrictMock<MockAdvancedReducerEditor> editor;
116 EXPECT_CALL(editor, Replace(if_true, IsDead()));
117 EXPECT_CALL(editor, Replace(if_false, control));
118 Reduction const r = Reduce(&editor, branch);
119 ASSERT_TRUE(r.Changed());
120 EXPECT_THAT(r.replacement(), IsDead());
121 }
122}
123
124
125TEST_F(CommonOperatorReducerTest, BranchWithInt64OneConstant) {
126 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
127 Node* const control = graph()->start();
128 Node* const branch =
129 graph()->NewNode(common()->Branch(hint), Int64Constant(1), control);
130 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
131 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
132 StrictMock<MockAdvancedReducerEditor> editor;
133 EXPECT_CALL(editor, Replace(if_true, control));
134 EXPECT_CALL(editor, Replace(if_false, IsDead()));
135 Reduction const r = Reduce(&editor, branch);
136 ASSERT_TRUE(r.Changed());
137 EXPECT_THAT(r.replacement(), IsDead());
138 }
139}
140
141
142TEST_F(CommonOperatorReducerTest, BranchWithFalseConstant) {
143 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
144 Node* const control = graph()->start();
145 Node* const branch =
146 graph()->NewNode(common()->Branch(hint), FalseConstant(), control);
147 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
148 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
149 StrictMock<MockAdvancedReducerEditor> editor;
150 EXPECT_CALL(editor, Replace(if_true, IsDead()));
151 EXPECT_CALL(editor, Replace(if_false, control));
152 Reduction const r = Reduce(&editor, branch);
153 ASSERT_TRUE(r.Changed());
154 EXPECT_THAT(r.replacement(), IsDead());
155 }
156}
157
158
159TEST_F(CommonOperatorReducerTest, BranchWithTrueConstant) {
160 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
161 Node* const control = graph()->start();
162 Node* const branch =
163 graph()->NewNode(common()->Branch(hint), TrueConstant(), control);
164 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
165 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
166 StrictMock<MockAdvancedReducerEditor> editor;
167 EXPECT_CALL(editor, Replace(if_true, control));
168 EXPECT_CALL(editor, Replace(if_false, IsDead()));
169 Reduction const r = Reduce(&editor, branch);
170 ASSERT_TRUE(r.Changed());
171 EXPECT_THAT(r.replacement(), IsDead());
172 }
173}
174
175
176TEST_F(CommonOperatorReducerTest, BranchWithBooleanNot) {
177 Node* const value = Parameter(0);
178 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
179 Node* const control = graph()->start();
180 Node* const branch = graph()->NewNode(
181 common()->Branch(hint),
182 graph()->NewNode(simplified()->BooleanNot(), value), control);
183 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
184 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
185 Reduction const r = Reduce(branch);
186 ASSERT_TRUE(r.Changed());
187 EXPECT_EQ(branch, r.replacement());
188 EXPECT_THAT(branch, IsBranch(value, control));
189 EXPECT_THAT(if_false, IsIfTrue(branch));
190 EXPECT_THAT(if_true, IsIfFalse(branch));
191 EXPECT_EQ(NegateBranchHint(hint), BranchHintOf(branch->op()));
192 }
193}
194
195
196// -----------------------------------------------------------------------------
197// Merge
198
199
200TEST_F(CommonOperatorReducerTest, MergeOfUnusedDiamond0) {
201 Node* const value = Parameter(0);
202 Node* const control = graph()->start();
203 Node* const branch = graph()->NewNode(common()->Branch(), value, control);
204 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
205 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
206 Reduction const r =
207 Reduce(graph()->NewNode(common()->Merge(2), if_true, if_false));
208 ASSERT_TRUE(r.Changed());
209 EXPECT_EQ(control, r.replacement());
210 EXPECT_THAT(branch, IsDead());
211}
212
213
214TEST_F(CommonOperatorReducerTest, MergeOfUnusedDiamond1) {
215 Node* const value = Parameter(0);
216 Node* const control = graph()->start();
217 Node* const branch = graph()->NewNode(common()->Branch(), value, control);
218 Node* const if_true = graph()->NewNode(common()->IfTrue(), branch);
219 Node* const if_false = graph()->NewNode(common()->IfFalse(), branch);
220 Reduction const r =
221 Reduce(graph()->NewNode(common()->Merge(2), if_false, if_true));
222 ASSERT_TRUE(r.Changed());
223 EXPECT_EQ(control, r.replacement());
224 EXPECT_THAT(branch, IsDead());
225}
226
227
228// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400229// EffectPhi
230
231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000232TEST_F(CommonOperatorReducerTest, EffectPhiWithMerge) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400233 const int kMaxInputs = 64;
234 Node* inputs[kMaxInputs];
235 Node* const input = graph()->NewNode(&kOp0);
236 TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
237 int const value_input_count = input_count - 1;
238 for (int i = 0; i < value_input_count; ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239 inputs[i] = graph()->start();
240 }
241 Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
242 value_input_count, inputs);
243 for (int i = 0; i < value_input_count; ++i) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400244 inputs[i] = input;
245 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 inputs[value_input_count] = merge;
247 StrictMock<MockAdvancedReducerEditor> editor;
248 EXPECT_CALL(editor, Revisit(merge));
249 Reduction r =
250 Reduce(&editor, graph()->NewNode(common()->EffectPhi(value_input_count),
251 input_count, inputs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252 ASSERT_TRUE(r.Changed());
253 EXPECT_EQ(input, r.replacement());
254 }
255}
256
257
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258TEST_F(CommonOperatorReducerTest, EffectPhiWithLoop) {
259 Node* const e0 = graph()->NewNode(&kOp0);
260 Node* const loop =
261 graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
262 loop->ReplaceInput(1, loop);
263 Node* const ephi = graph()->NewNode(common()->EffectPhi(2), e0, e0, loop);
264 ephi->ReplaceInput(1, ephi);
265 StrictMock<MockAdvancedReducerEditor> editor;
266 EXPECT_CALL(editor, Revisit(loop));
267 Reduction const r = Reduce(&editor, ephi);
268 ASSERT_TRUE(r.Changed());
269 EXPECT_EQ(e0, r.replacement());
270}
271
272
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400273// -----------------------------------------------------------------------------
274// Phi
275
276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277TEST_F(CommonOperatorReducerTest, PhiWithMerge) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400278 const int kMaxInputs = 64;
279 Node* inputs[kMaxInputs];
280 Node* const input = graph()->NewNode(&kOp0);
281 TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
282 int const value_input_count = input_count - 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000283 TRACED_FOREACH(MachineRepresentation, rep, kMachineRepresentations) {
284 for (int i = 0; i < value_input_count; ++i) {
285 inputs[i] = graph()->start();
286 }
287 Node* const merge = graph()->NewNode(common()->Merge(value_input_count),
288 value_input_count, inputs);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400289 for (int i = 0; i < value_input_count; ++i) {
290 inputs[i] = input;
291 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292 inputs[value_input_count] = merge;
293 StrictMock<MockAdvancedReducerEditor> editor;
294 EXPECT_CALL(editor, Revisit(merge));
295 Reduction r = Reduce(
296 &editor, graph()->NewNode(common()->Phi(rep, value_input_count),
297 input_count, inputs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400298 ASSERT_TRUE(r.Changed());
299 EXPECT_EQ(input, r.replacement());
300 }
301 }
302}
303
304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305TEST_F(CommonOperatorReducerTest, PhiWithLoop) {
306 Node* const p0 = Parameter(0);
307 Node* const loop =
308 graph()->NewNode(common()->Loop(2), graph()->start(), graph()->start());
309 loop->ReplaceInput(1, loop);
310 Node* const phi = graph()->NewNode(
311 common()->Phi(MachineRepresentation::kTagged, 2), p0, p0, loop);
312 phi->ReplaceInput(1, phi);
313 StrictMock<MockAdvancedReducerEditor> editor;
314 EXPECT_CALL(editor, Revisit(loop));
315 Reduction const r = Reduce(&editor, phi);
316 ASSERT_TRUE(r.Changed());
317 EXPECT_EQ(p0, r.replacement());
318}
319
320
321TEST_F(CommonOperatorReducerTest, PhiToFloat32Abs) {
322 Node* p0 = Parameter(0);
323 Node* c0 = Float32Constant(0.0);
324 Node* check = graph()->NewNode(machine()->Float32LessThan(), c0, p0);
325 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
326 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
327 Node* vtrue = p0;
328 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
329 Node* vfalse = graph()->NewNode(machine()->Float32Sub(), c0, p0);
330 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
331 Node* phi = graph()->NewNode(
332 common()->Phi(MachineRepresentation::kFloat32, 2), vtrue, vfalse, merge);
333 StrictMock<MockAdvancedReducerEditor> editor;
334 EXPECT_CALL(editor, Revisit(merge));
335 Reduction r = Reduce(&editor, phi);
336 ASSERT_TRUE(r.Changed());
337 EXPECT_THAT(r.replacement(), IsFloat32Abs(p0));
338}
339
340
341TEST_F(CommonOperatorReducerTest, PhiToFloat64Abs) {
342 Node* p0 = Parameter(0);
343 Node* c0 = Float64Constant(0.0);
344 Node* check = graph()->NewNode(machine()->Float64LessThan(), c0, p0);
345 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
346 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
347 Node* vtrue = p0;
348 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
349 Node* vfalse = graph()->NewNode(machine()->Float64Sub(), c0, p0);
350 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
351 Node* phi = graph()->NewNode(
352 common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, vfalse, merge);
353 StrictMock<MockAdvancedReducerEditor> editor;
354 EXPECT_CALL(editor, Revisit(merge));
355 Reduction r = Reduce(&editor, phi);
356 ASSERT_TRUE(r.Changed());
357 EXPECT_THAT(r.replacement(), IsFloat64Abs(p0));
358}
359
360
361TEST_F(CommonOperatorReducerTest, PhiToFloat32Max) {
362 Node* p0 = Parameter(0);
363 Node* p1 = Parameter(1);
364 Node* check = graph()->NewNode(machine()->Float32LessThan(), p0, p1);
365 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
366 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
367 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
368 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
369 Node* phi = graph()->NewNode(
370 common()->Phi(MachineRepresentation::kFloat32, 2), p1, p0, merge);
371 StrictMock<MockAdvancedReducerEditor> editor;
372 EXPECT_CALL(editor, Revisit(merge));
373 Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Max);
374 ASSERT_TRUE(r.Changed());
375 EXPECT_THAT(r.replacement(), IsFloat32Max(p1, p0));
376}
377
378
379TEST_F(CommonOperatorReducerTest, PhiToFloat64Max) {
380 Node* p0 = Parameter(0);
381 Node* p1 = Parameter(1);
382 Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
383 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
384 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
385 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
386 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
387 Node* phi = graph()->NewNode(
388 common()->Phi(MachineRepresentation::kFloat64, 2), p1, p0, merge);
389 StrictMock<MockAdvancedReducerEditor> editor;
390 EXPECT_CALL(editor, Revisit(merge));
391 Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Max);
392 ASSERT_TRUE(r.Changed());
393 EXPECT_THAT(r.replacement(), IsFloat64Max(p1, p0));
394}
395
396
397TEST_F(CommonOperatorReducerTest, PhiToFloat32Min) {
398 Node* p0 = Parameter(0);
399 Node* p1 = Parameter(1);
400 Node* check = graph()->NewNode(machine()->Float32LessThan(), p0, p1);
401 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
402 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
403 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
404 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
405 Node* phi = graph()->NewNode(
406 common()->Phi(MachineRepresentation::kFloat32, 2), p0, p1, merge);
407 StrictMock<MockAdvancedReducerEditor> editor;
408 EXPECT_CALL(editor, Revisit(merge));
409 Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat32Min);
410 ASSERT_TRUE(r.Changed());
411 EXPECT_THAT(r.replacement(), IsFloat32Min(p0, p1));
412}
413
414
415TEST_F(CommonOperatorReducerTest, PhiToFloat64Min) {
416 Node* p0 = Parameter(0);
417 Node* p1 = Parameter(1);
418 Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
419 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
420 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
421 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
422 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
423 Node* phi = graph()->NewNode(
424 common()->Phi(MachineRepresentation::kFloat64, 2), p0, p1, merge);
425 StrictMock<MockAdvancedReducerEditor> editor;
426 EXPECT_CALL(editor, Revisit(merge));
427 Reduction r = Reduce(&editor, phi, MachineOperatorBuilder::kFloat64Min);
428 ASSERT_TRUE(r.Changed());
429 EXPECT_THAT(r.replacement(), IsFloat64Min(p0, p1));
430}
431
432
433// -----------------------------------------------------------------------------
434// Return
435
436
437TEST_F(CommonOperatorReducerTest, ReturnWithPhiAndEffectPhiAndMerge) {
438 Node* cond = Parameter(2);
439 Node* branch = graph()->NewNode(common()->Branch(), cond, graph()->start());
440 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
441 Node* etrue = graph()->start();
442 Node* vtrue = Parameter(0);
443 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
444 Node* efalse = graph()->start();
445 Node* vfalse = Parameter(1);
446 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
447 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
448 Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
449 vtrue, vfalse, merge);
450 Node* ret = graph()->NewNode(common()->Return(), phi, ephi, merge);
451 graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
452 StrictMock<MockAdvancedReducerEditor> editor;
453 EXPECT_CALL(editor, Replace(merge, IsDead()));
454 Reduction const r = Reduce(&editor, ret);
455 ASSERT_TRUE(r.Changed());
456 EXPECT_THAT(r.replacement(), IsDead());
457 EXPECT_THAT(graph()->end(), IsEnd(ret, IsReturn(vtrue, etrue, if_true),
458 IsReturn(vfalse, efalse, if_false)));
459}
460
461
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400462// -----------------------------------------------------------------------------
463// Select
464
465
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000466TEST_F(CommonOperatorReducerTest, SelectWithSameThenAndElse) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400467 Node* const input = graph()->NewNode(&kOp0);
468 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000469 TRACED_FOREACH(MachineRepresentation, rep, kMachineRepresentations) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400470 Reduction r = Reduce(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471 graph()->NewNode(common()->Select(rep, hint), input, input, input));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400472 ASSERT_TRUE(r.Changed());
473 EXPECT_EQ(input, r.replacement());
474 }
475 }
476}
477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000478
479TEST_F(CommonOperatorReducerTest, SelectWithInt32ZeroConstant) {
480 Node* p0 = Parameter(0);
481 Node* p1 = Parameter(1);
482 Node* select =
483 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
484 Int32Constant(0), p0, p1);
485 Reduction r = Reduce(select);
486 ASSERT_TRUE(r.Changed());
487 EXPECT_EQ(p1, r.replacement());
488}
489
490
491TEST_F(CommonOperatorReducerTest, SelectWithInt32OneConstant) {
492 Node* p0 = Parameter(0);
493 Node* p1 = Parameter(1);
494 Node* select =
495 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
496 Int32Constant(1), p0, p1);
497 Reduction r = Reduce(select);
498 ASSERT_TRUE(r.Changed());
499 EXPECT_EQ(p0, r.replacement());
500}
501
502
503TEST_F(CommonOperatorReducerTest, SelectWithInt64ZeroConstant) {
504 Node* p0 = Parameter(0);
505 Node* p1 = Parameter(1);
506 Node* select =
507 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
508 Int64Constant(0), p0, p1);
509 Reduction r = Reduce(select);
510 ASSERT_TRUE(r.Changed());
511 EXPECT_EQ(p1, r.replacement());
512}
513
514
515TEST_F(CommonOperatorReducerTest, SelectWithInt64OneConstant) {
516 Node* p0 = Parameter(0);
517 Node* p1 = Parameter(1);
518 Node* select =
519 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
520 Int64Constant(1), p0, p1);
521 Reduction r = Reduce(select);
522 ASSERT_TRUE(r.Changed());
523 EXPECT_EQ(p0, r.replacement());
524}
525
526
527TEST_F(CommonOperatorReducerTest, SelectWithFalseConstant) {
528 Node* p0 = Parameter(0);
529 Node* p1 = Parameter(1);
530 Node* select =
531 graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
532 FalseConstant(), p0, p1);
533 Reduction r = Reduce(select);
534 ASSERT_TRUE(r.Changed());
535 EXPECT_EQ(p1, r.replacement());
536}
537
538
539TEST_F(CommonOperatorReducerTest, SelectWithTrueConstant) {
540 Node* p0 = Parameter(0);
541 Node* p1 = Parameter(1);
542 Node* select = graph()->NewNode(
543 common()->Select(MachineRepresentation::kTagged), TrueConstant(), p0, p1);
544 Reduction r = Reduce(select);
545 ASSERT_TRUE(r.Changed());
546 EXPECT_EQ(p0, r.replacement());
547}
548
549
550TEST_F(CommonOperatorReducerTest, SelectToFloat32Abs) {
551 Node* p0 = Parameter(0);
552 Node* c0 = Float32Constant(0.0);
553 Node* check = graph()->NewNode(machine()->Float32LessThan(), c0, p0);
554 Node* select =
555 graph()->NewNode(common()->Select(MachineRepresentation::kFloat32), check,
556 p0, graph()->NewNode(machine()->Float32Sub(), c0, p0));
557 Reduction r = Reduce(select);
558 ASSERT_TRUE(r.Changed());
559 EXPECT_THAT(r.replacement(), IsFloat32Abs(p0));
560}
561
562
563TEST_F(CommonOperatorReducerTest, SelectToFloat64Abs) {
564 Node* p0 = Parameter(0);
565 Node* c0 = Float64Constant(0.0);
566 Node* check = graph()->NewNode(machine()->Float64LessThan(), c0, p0);
567 Node* select =
568 graph()->NewNode(common()->Select(MachineRepresentation::kFloat64), check,
569 p0, graph()->NewNode(machine()->Float64Sub(), c0, p0));
570 Reduction r = Reduce(select);
571 ASSERT_TRUE(r.Changed());
572 EXPECT_THAT(r.replacement(), IsFloat64Abs(p0));
573}
574
575
576TEST_F(CommonOperatorReducerTest, SelectToFloat32Max) {
577 Node* p0 = Parameter(0);
578 Node* p1 = Parameter(1);
579 Node* check = graph()->NewNode(machine()->Float32LessThan(), p0, p1);
580 Node* select = graph()->NewNode(
581 common()->Select(MachineRepresentation::kFloat32), check, p1, p0);
582 Reduction r = Reduce(select, MachineOperatorBuilder::kFloat32Max);
583 ASSERT_TRUE(r.Changed());
584 EXPECT_THAT(r.replacement(), IsFloat32Max(p1, p0));
585}
586
587
588TEST_F(CommonOperatorReducerTest, SelectToFloat64Max) {
589 Node* p0 = Parameter(0);
590 Node* p1 = Parameter(1);
591 Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
592 Node* select = graph()->NewNode(
593 common()->Select(MachineRepresentation::kFloat64), check, p1, p0);
594 Reduction r = Reduce(select, MachineOperatorBuilder::kFloat64Max);
595 ASSERT_TRUE(r.Changed());
596 EXPECT_THAT(r.replacement(), IsFloat64Max(p1, p0));
597}
598
599
600TEST_F(CommonOperatorReducerTest, SelectToFloat32Min) {
601 Node* p0 = Parameter(0);
602 Node* p1 = Parameter(1);
603 Node* check = graph()->NewNode(machine()->Float32LessThan(), p0, p1);
604 Node* select = graph()->NewNode(
605 common()->Select(MachineRepresentation::kFloat32), check, p0, p1);
606 Reduction r = Reduce(select, MachineOperatorBuilder::kFloat32Min);
607 ASSERT_TRUE(r.Changed());
608 EXPECT_THAT(r.replacement(), IsFloat32Min(p0, p1));
609}
610
611
612TEST_F(CommonOperatorReducerTest, SelectToFloat64Min) {
613 Node* p0 = Parameter(0);
614 Node* p1 = Parameter(1);
615 Node* check = graph()->NewNode(machine()->Float64LessThan(), p0, p1);
616 Node* select = graph()->NewNode(
617 common()->Select(MachineRepresentation::kFloat64), check, p0, p1);
618 Reduction r = Reduce(select, MachineOperatorBuilder::kFloat64Min);
619 ASSERT_TRUE(r.Changed());
620 EXPECT_THAT(r.replacement(), IsFloat64Min(p0, p1));
621}
622
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400623} // namespace compiler
624} // namespace internal
625} // namespace v8