1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/common-operator.h"
6 #include "src/compiler/common-operator-reducer.h"
7 #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"
12 #include "test/unittests/compiler/graph-unittest.h"
13 #include "test/unittests/compiler/node-test-utils.h"
14
15 using testing::StrictMock;
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
21 class CommonOperatorReducerTest : public GraphTest {
22 public:
CommonOperatorReducerTest(int num_parameters=1)23 explicit CommonOperatorReducerTest(int num_parameters = 1)
24 : GraphTest(num_parameters), machine_(zone()), simplified_(zone()) {}
~CommonOperatorReducerTest()25 ~CommonOperatorReducerTest() override {}
26
27 protected:
Reduce(AdvancedReducer::Editor * editor,Node * node,MachineOperatorBuilder::Flags flags=MachineOperatorBuilder::kNoFlags)28 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);
34 return reducer.Reduce(node);
35 }
36
Reduce(Node * node,MachineOperatorBuilder::Flags flags=MachineOperatorBuilder::kNoFlags)37 Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
38 MachineOperatorBuilder::kNoFlags) {
39 StrictMock<MockAdvancedReducerEditor> editor;
40 return Reduce(&editor, node, flags);
41 }
42
machine()43 MachineOperatorBuilder* machine() { return &machine_; }
simplified()44 SimplifiedOperatorBuilder* simplified() { return &simplified_; }
45
46 private:
47 MachineOperatorBuilder machine_;
48 SimplifiedOperatorBuilder simplified_;
49 };
50
51
52 namespace {
53
54 const BranchHint kBranchHints[] = {BranchHint::kNone, BranchHint::kFalse,
55 BranchHint::kTrue};
56
57
58 const MachineRepresentation kMachineRepresentations[] = {
59 MachineRepresentation::kBit, MachineRepresentation::kWord8,
60 MachineRepresentation::kWord16, MachineRepresentation::kWord32,
61 MachineRepresentation::kWord64, MachineRepresentation::kFloat32,
62 MachineRepresentation::kFloat64, MachineRepresentation::kTagged};
63
64
65 const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
66
67 } // namespace
68
69
70 // -----------------------------------------------------------------------------
71 // Branch
72
73
TEST_F(CommonOperatorReducerTest,BranchWithInt32ZeroConstant)74 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithInt32OneConstant)91 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithInt64ZeroConstant)108 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithInt64OneConstant)125 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithFalseConstant)142 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithTrueConstant)159 TEST_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
TEST_F(CommonOperatorReducerTest,BranchWithBooleanNot)176 TEST_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
TEST_F(CommonOperatorReducerTest,MergeOfUnusedDiamond0)200 TEST_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
TEST_F(CommonOperatorReducerTest,MergeOfUnusedDiamond1)214 TEST_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 // -----------------------------------------------------------------------------
229 // EffectPhi
230
231
TEST_F(CommonOperatorReducerTest,EffectPhiWithMerge)232 TEST_F(CommonOperatorReducerTest, EffectPhiWithMerge) {
233 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) {
239 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) {
244 inputs[i] = input;
245 }
246 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));
252 ASSERT_TRUE(r.Changed());
253 EXPECT_EQ(input, r.replacement());
254 }
255 }
256
257
TEST_F(CommonOperatorReducerTest,EffectPhiWithLoop)258 TEST_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
273 // -----------------------------------------------------------------------------
274 // Phi
275
276
TEST_F(CommonOperatorReducerTest,PhiWithMerge)277 TEST_F(CommonOperatorReducerTest, PhiWithMerge) {
278 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;
283 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);
289 for (int i = 0; i < value_input_count; ++i) {
290 inputs[i] = input;
291 }
292 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));
298 ASSERT_TRUE(r.Changed());
299 EXPECT_EQ(input, r.replacement());
300 }
301 }
302 }
303
304
TEST_F(CommonOperatorReducerTest,PhiWithLoop)305 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat32Abs)321 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat64Abs)341 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat32Max)361 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat64Max)379 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat32Min)397 TEST_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
TEST_F(CommonOperatorReducerTest,PhiToFloat64Min)415 TEST_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
TEST_F(CommonOperatorReducerTest,ReturnWithPhiAndEffectPhiAndMerge)437 TEST_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
462 // -----------------------------------------------------------------------------
463 // Select
464
465
TEST_F(CommonOperatorReducerTest,SelectWithSameThenAndElse)466 TEST_F(CommonOperatorReducerTest, SelectWithSameThenAndElse) {
467 Node* const input = graph()->NewNode(&kOp0);
468 TRACED_FOREACH(BranchHint, hint, kBranchHints) {
469 TRACED_FOREACH(MachineRepresentation, rep, kMachineRepresentations) {
470 Reduction r = Reduce(
471 graph()->NewNode(common()->Select(rep, hint), input, input, input));
472 ASSERT_TRUE(r.Changed());
473 EXPECT_EQ(input, r.replacement());
474 }
475 }
476 }
477
478
TEST_F(CommonOperatorReducerTest,SelectWithInt32ZeroConstant)479 TEST_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
TEST_F(CommonOperatorReducerTest,SelectWithInt32OneConstant)491 TEST_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
TEST_F(CommonOperatorReducerTest,SelectWithInt64ZeroConstant)503 TEST_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
TEST_F(CommonOperatorReducerTest,SelectWithInt64OneConstant)515 TEST_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
TEST_F(CommonOperatorReducerTest,SelectWithFalseConstant)527 TEST_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
TEST_F(CommonOperatorReducerTest,SelectWithTrueConstant)539 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat32Abs)550 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat64Abs)563 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat32Max)576 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat64Max)588 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat32Min)600 TEST_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
TEST_F(CommonOperatorReducerTest,SelectToFloat64Min)612 TEST_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
623 } // namespace compiler
624 } // namespace internal
625 } // namespace v8
626