Line data Source code
1 : // Copyright 2018 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/redundancy-elimination.h"
6 : #include "src/compiler/common-operator.h"
7 : #include "test/unittests/compiler/graph-reducer-unittest.h"
8 : #include "test/unittests/compiler/graph-unittest.h"
9 : #include "test/unittests/compiler/node-test-utils.h"
10 : #include "testing/gmock-support.h"
11 :
12 : using testing::_;
13 : using testing::NiceMock;
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 : namespace redundancy_elimination_unittest {
19 :
20 : class RedundancyEliminationTest : public GraphTest {
21 : public:
22 49 : explicit RedundancyEliminationTest(int num_parameters = 4)
23 : : GraphTest(num_parameters),
24 : reducer_(&editor_, zone()),
25 147 : simplified_(zone()) {
26 : // Initialize the {reducer_} state for the Start node.
27 49 : reducer_.Reduce(graph()->start());
28 :
29 : // Create a feedback vector with two CALL_IC slots.
30 : FeedbackVectorSpec spec(zone());
31 : FeedbackSlot slot1 = spec.AddCallICSlot();
32 : FeedbackSlot slot2 = spec.AddCallICSlot();
33 49 : Handle<FeedbackMetadata> metadata = FeedbackMetadata::New(isolate(), &spec);
34 : Handle<SharedFunctionInfo> shared =
35 : isolate()->factory()->NewSharedFunctionInfoForBuiltin(
36 49 : isolate()->factory()->empty_string(), Builtins::kIllegal);
37 98 : shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
38 : Handle<FixedArray> closure_feedback_cell_array =
39 49 : FeedbackVector::NewClosureFeedbackCellArray(isolate(), shared);
40 : Handle<FeedbackVector> feedback_vector =
41 49 : FeedbackVector::New(isolate(), shared, closure_feedback_cell_array);
42 98 : vector_slot_pairs_.push_back(VectorSlotPair());
43 49 : vector_slot_pairs_.push_back(
44 : VectorSlotPair(feedback_vector, slot1, UNINITIALIZED));
45 49 : vector_slot_pairs_.push_back(
46 : VectorSlotPair(feedback_vector, slot2, UNINITIALIZED));
47 49 : }
48 98 : ~RedundancyEliminationTest() override = default;
49 :
50 : protected:
51 1158 : Reduction Reduce(Node* node) { return reducer_.Reduce(node); }
52 :
53 : std::vector<VectorSlotPair> const& vector_slot_pairs() const {
54 : return vector_slot_pairs_;
55 : }
56 552 : SimplifiedOperatorBuilder* simplified() { return &simplified_; }
57 :
58 : private:
59 : NiceMock<MockAdvancedReducerEditor> editor_;
60 : std::vector<VectorSlotPair> vector_slot_pairs_;
61 : VectorSlotPair feedback2_;
62 : RedundancyElimination reducer_;
63 : SimplifiedOperatorBuilder simplified_;
64 : };
65 :
66 : namespace {
67 :
68 : const CheckForMinusZeroMode kCheckForMinusZeroModes[] = {
69 : CheckForMinusZeroMode::kCheckForMinusZero,
70 : CheckForMinusZeroMode::kDontCheckForMinusZero,
71 : };
72 :
73 : const CheckTaggedInputMode kCheckTaggedInputModes[] = {
74 : CheckTaggedInputMode::kNumber, CheckTaggedInputMode::kNumberOrOddball};
75 :
76 : const NumberOperationHint kNumberOperationHints[] = {
77 : NumberOperationHint::kSignedSmall,
78 : NumberOperationHint::kSignedSmallInputs,
79 : NumberOperationHint::kSigned32,
80 : NumberOperationHint::kNumber,
81 : NumberOperationHint::kNumberOrOddball,
82 : };
83 :
84 : } // namespace
85 :
86 : // -----------------------------------------------------------------------------
87 : // CheckBounds
88 :
89 15373 : TEST_F(RedundancyEliminationTest, CheckBounds) {
90 10 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
91 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
92 9 : Node* index = Parameter(0);
93 9 : Node* length = Parameter(1);
94 : Node* effect = graph()->start();
95 : Node* control = graph()->start();
96 :
97 9 : Node* check1 = effect = graph()->NewNode(
98 9 : simplified()->CheckBounds(feedback1), index, length, effect, control);
99 : Reduction r1 = Reduce(check1);
100 9 : ASSERT_TRUE(r1.Changed());
101 18 : EXPECT_EQ(r1.replacement(), check1);
102 :
103 9 : Node* check2 = effect = graph()->NewNode(
104 : simplified()->CheckBounds(feedback2), index, length, effect, control);
105 : Reduction r2 = Reduce(check2);
106 9 : ASSERT_TRUE(r2.Changed());
107 18 : EXPECT_EQ(r2.replacement(), check1);
108 : }
109 : }
110 : }
111 :
112 : // -----------------------------------------------------------------------------
113 : // CheckNumber
114 :
115 15373 : TEST_F(RedundancyEliminationTest, CheckNumberSubsumedByCheckSmi) {
116 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
117 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
118 9 : Node* value = Parameter(0);
119 : Node* effect = graph()->start();
120 : Node* control = graph()->start();
121 :
122 9 : Node* check1 = effect = graph()->NewNode(
123 9 : simplified()->CheckSmi(feedback1), value, effect, control);
124 : Reduction r1 = Reduce(check1);
125 9 : ASSERT_TRUE(r1.Changed());
126 18 : EXPECT_EQ(r1.replacement(), check1);
127 :
128 9 : Node* check2 = effect = graph()->NewNode(
129 : simplified()->CheckNumber(feedback2), value, effect, control);
130 : Reduction r2 = Reduce(check2);
131 9 : ASSERT_TRUE(r2.Changed());
132 18 : EXPECT_EQ(r2.replacement(), check1);
133 : }
134 : }
135 : }
136 :
137 : // -----------------------------------------------------------------------------
138 : // CheckReceiver
139 :
140 15373 : TEST_F(RedundancyEliminationTest, CheckReceiver) {
141 1 : Node* value = Parameter(0);
142 : Node* effect = graph()->start();
143 : Node* control = graph()->start();
144 :
145 : Node* check1 = effect =
146 2 : graph()->NewNode(simplified()->CheckReceiver(), value, effect, control);
147 : Reduction r1 = Reduce(check1);
148 1 : ASSERT_TRUE(r1.Changed());
149 2 : EXPECT_EQ(r1.replacement(), check1);
150 :
151 : Node* check2 = effect =
152 1 : graph()->NewNode(simplified()->CheckReceiver(), value, effect, control);
153 : Reduction r2 = Reduce(check2);
154 1 : ASSERT_TRUE(r2.Changed());
155 2 : EXPECT_EQ(r2.replacement(), check1);
156 : }
157 :
158 : // -----------------------------------------------------------------------------
159 : // CheckReceiverOrNullOrUndefined
160 :
161 15373 : TEST_F(RedundancyEliminationTest, CheckReceiverOrNullOrUndefined) {
162 1 : Node* value = Parameter(0);
163 : Node* effect = graph()->start();
164 : Node* control = graph()->start();
165 :
166 1 : Node* check1 = effect = graph()->NewNode(
167 1 : simplified()->CheckReceiverOrNullOrUndefined(), value, effect, control);
168 : Reduction r1 = Reduce(check1);
169 1 : ASSERT_TRUE(r1.Changed());
170 2 : EXPECT_EQ(r1.replacement(), check1);
171 :
172 1 : Node* check2 = effect = graph()->NewNode(
173 : simplified()->CheckReceiverOrNullOrUndefined(), value, effect, control);
174 : Reduction r2 = Reduce(check2);
175 1 : ASSERT_TRUE(r2.Changed());
176 2 : EXPECT_EQ(r2.replacement(), check1);
177 : }
178 :
179 15373 : TEST_F(RedundancyEliminationTest,
180 : CheckReceiverOrNullOrUndefinedSubsumedByCheckReceiver) {
181 1 : Node* value = Parameter(0);
182 : Node* effect = graph()->start();
183 : Node* control = graph()->start();
184 :
185 : Node* check1 = effect =
186 2 : graph()->NewNode(simplified()->CheckReceiver(), value, effect, control);
187 : Reduction r1 = Reduce(check1);
188 1 : ASSERT_TRUE(r1.Changed());
189 2 : EXPECT_EQ(r1.replacement(), check1);
190 :
191 1 : Node* check2 = effect = graph()->NewNode(
192 : simplified()->CheckReceiverOrNullOrUndefined(), value, effect, control);
193 : Reduction r2 = Reduce(check2);
194 1 : ASSERT_TRUE(r2.Changed());
195 2 : EXPECT_EQ(r2.replacement(), check1);
196 : }
197 :
198 : // -----------------------------------------------------------------------------
199 : // CheckNonEmptyString
200 :
201 15373 : TEST_F(RedundancyEliminationTest,
202 : CheckNonEmptyStringSubsumedByCheckNonEmptyOneByteString) {
203 1 : Node* value = Parameter(0);
204 : Node* effect = graph()->start();
205 : Node* control = graph()->start();
206 :
207 1 : Node* check1 = effect = graph()->NewNode(
208 1 : simplified()->CheckNonEmptyOneByteString(), value, effect, control);
209 : Reduction r1 = Reduce(check1);
210 1 : ASSERT_TRUE(r1.Changed());
211 2 : EXPECT_EQ(r1.replacement(), check1);
212 :
213 1 : Node* check2 = effect = graph()->NewNode(simplified()->CheckNonEmptyString(),
214 : value, effect, control);
215 : Reduction r2 = Reduce(check2);
216 1 : ASSERT_TRUE(r2.Changed());
217 2 : EXPECT_EQ(r2.replacement(), check1);
218 : }
219 :
220 15373 : TEST_F(RedundancyEliminationTest,
221 : CheckNonEmptyStringSubsumedByCheckNonEmptyTwoByteString) {
222 1 : Node* value = Parameter(0);
223 : Node* effect = graph()->start();
224 : Node* control = graph()->start();
225 :
226 1 : Node* check1 = effect = graph()->NewNode(
227 1 : simplified()->CheckNonEmptyTwoByteString(), value, effect, control);
228 : Reduction r1 = Reduce(check1);
229 1 : ASSERT_TRUE(r1.Changed());
230 2 : EXPECT_EQ(r1.replacement(), check1);
231 :
232 1 : Node* check2 = effect = graph()->NewNode(simplified()->CheckNonEmptyString(),
233 : value, effect, control);
234 : Reduction r2 = Reduce(check2);
235 1 : ASSERT_TRUE(r2.Changed());
236 2 : EXPECT_EQ(r2.replacement(), check1);
237 : }
238 :
239 : // -----------------------------------------------------------------------------
240 : // CheckString
241 :
242 15373 : TEST_F(RedundancyEliminationTest,
243 : CheckStringSubsumedByCheckInternalizedString) {
244 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
245 3 : Node* value = Parameter(0);
246 : Node* effect = graph()->start();
247 : Node* control = graph()->start();
248 :
249 3 : Node* check1 = effect = graph()->NewNode(
250 3 : simplified()->CheckInternalizedString(), value, effect, control);
251 : Reduction r1 = Reduce(check1);
252 3 : ASSERT_TRUE(r1.Changed());
253 6 : EXPECT_EQ(r1.replacement(), check1);
254 :
255 3 : Node* check2 = effect = graph()->NewNode(
256 : simplified()->CheckString(feedback), value, effect, control);
257 : Reduction r2 = Reduce(check2);
258 3 : ASSERT_TRUE(r2.Changed());
259 6 : EXPECT_EQ(r2.replacement(), check1);
260 : }
261 : }
262 :
263 15373 : TEST_F(RedundancyEliminationTest, CheckStringSubsumedByCheckNonEmptyString) {
264 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
265 3 : Node* value = Parameter(0);
266 : Node* effect = graph()->start();
267 : Node* control = graph()->start();
268 :
269 3 : Node* check1 = effect = graph()->NewNode(
270 3 : simplified()->CheckNonEmptyString(), value, effect, control);
271 : Reduction r1 = Reduce(check1);
272 3 : ASSERT_TRUE(r1.Changed());
273 6 : EXPECT_EQ(r1.replacement(), check1);
274 :
275 3 : Node* check2 = effect = graph()->NewNode(
276 : simplified()->CheckString(feedback), value, effect, control);
277 : Reduction r2 = Reduce(check2);
278 3 : ASSERT_TRUE(r2.Changed());
279 6 : EXPECT_EQ(r2.replacement(), check1);
280 : }
281 : }
282 :
283 15373 : TEST_F(RedundancyEliminationTest,
284 : CheckStringSubsumedByCheckNonEmptyOneByteString) {
285 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
286 3 : Node* value = Parameter(0);
287 : Node* effect = graph()->start();
288 : Node* control = graph()->start();
289 :
290 3 : Node* check1 = effect = graph()->NewNode(
291 3 : simplified()->CheckNonEmptyOneByteString(), value, effect, control);
292 : Reduction r1 = Reduce(check1);
293 3 : ASSERT_TRUE(r1.Changed());
294 6 : EXPECT_EQ(r1.replacement(), check1);
295 :
296 3 : Node* check2 = effect = graph()->NewNode(
297 : simplified()->CheckString(feedback), value, effect, control);
298 : Reduction r2 = Reduce(check2);
299 3 : ASSERT_TRUE(r2.Changed());
300 6 : EXPECT_EQ(r2.replacement(), check1);
301 : }
302 : }
303 :
304 15373 : TEST_F(RedundancyEliminationTest,
305 : CheckStringSubsumedByCheckNonEmptyTwoByteString) {
306 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
307 3 : Node* value = Parameter(0);
308 : Node* effect = graph()->start();
309 : Node* control = graph()->start();
310 :
311 3 : Node* check1 = effect = graph()->NewNode(
312 3 : simplified()->CheckNonEmptyTwoByteString(), value, effect, control);
313 : Reduction r1 = Reduce(check1);
314 3 : ASSERT_TRUE(r1.Changed());
315 6 : EXPECT_EQ(r1.replacement(), check1);
316 :
317 3 : Node* check2 = effect = graph()->NewNode(
318 : simplified()->CheckString(feedback), value, effect, control);
319 : Reduction r2 = Reduce(check2);
320 3 : ASSERT_TRUE(r2.Changed());
321 6 : EXPECT_EQ(r2.replacement(), check1);
322 : }
323 : }
324 :
325 : // -----------------------------------------------------------------------------
326 : // CheckSymbol
327 :
328 15373 : TEST_F(RedundancyEliminationTest, CheckSymbol) {
329 1 : Node* value = Parameter(0);
330 : Node* effect = graph()->start();
331 : Node* control = graph()->start();
332 :
333 : Node* check1 = effect =
334 2 : graph()->NewNode(simplified()->CheckSymbol(), value, effect, control);
335 : Reduction r1 = Reduce(check1);
336 1 : ASSERT_TRUE(r1.Changed());
337 2 : EXPECT_EQ(r1.replacement(), check1);
338 :
339 : Node* check2 = effect =
340 1 : graph()->NewNode(simplified()->CheckSymbol(), value, effect, control);
341 : Reduction r2 = Reduce(check2);
342 1 : ASSERT_TRUE(r2.Changed());
343 2 : EXPECT_EQ(r2.replacement(), check1);
344 : }
345 :
346 : // -----------------------------------------------------------------------------
347 : // CheckedFloat64ToInt32
348 :
349 15373 : TEST_F(RedundancyEliminationTest, CheckedFloat64ToInt32) {
350 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
351 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
352 81 : TRACED_FOREACH(CheckForMinusZeroMode, mode, kCheckForMinusZeroModes) {
353 18 : Node* value = Parameter(0);
354 : Node* effect = graph()->start();
355 : Node* control = graph()->start();
356 :
357 18 : Node* check1 = effect = graph()->NewNode(
358 : simplified()->CheckedFloat64ToInt32(mode, feedback1), value, effect,
359 18 : control);
360 : Reduction r1 = Reduce(check1);
361 18 : ASSERT_TRUE(r1.Changed());
362 36 : EXPECT_EQ(r1.replacement(), check1);
363 :
364 18 : Node* check2 = effect = graph()->NewNode(
365 : simplified()->CheckedFloat64ToInt32(mode, feedback2), value, effect,
366 : control);
367 : Reduction r2 = Reduce(check2);
368 18 : ASSERT_TRUE(r2.Changed());
369 36 : EXPECT_EQ(r2.replacement(), check1);
370 : }
371 : }
372 : }
373 : }
374 :
375 : // -----------------------------------------------------------------------------
376 : // CheckedFloat64ToInt64
377 :
378 15373 : TEST_F(RedundancyEliminationTest, CheckedFloat64ToInt64) {
379 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
380 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
381 81 : TRACED_FOREACH(CheckForMinusZeroMode, mode, kCheckForMinusZeroModes) {
382 18 : Node* value = Parameter(0);
383 : Node* effect = graph()->start();
384 : Node* control = graph()->start();
385 :
386 18 : Node* check1 = effect = graph()->NewNode(
387 : simplified()->CheckedFloat64ToInt64(mode, feedback1), value, effect,
388 18 : control);
389 : Reduction r1 = Reduce(check1);
390 18 : ASSERT_TRUE(r1.Changed());
391 36 : EXPECT_EQ(r1.replacement(), check1);
392 :
393 18 : Node* check2 = effect = graph()->NewNode(
394 : simplified()->CheckedFloat64ToInt64(mode, feedback2), value, effect,
395 : control);
396 : Reduction r2 = Reduce(check2);
397 18 : ASSERT_TRUE(r2.Changed());
398 36 : EXPECT_EQ(r2.replacement(), check1);
399 : }
400 : }
401 : }
402 : }
403 :
404 : // -----------------------------------------------------------------------------
405 : // CheckedInt32ToTaggedSigned
406 :
407 15373 : TEST_F(RedundancyEliminationTest, CheckedInt32ToTaggedSigned) {
408 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
409 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
410 9 : Node* value = Parameter(0);
411 : Node* effect = graph()->start();
412 : Node* control = graph()->start();
413 :
414 : Node* check1 = effect =
415 9 : graph()->NewNode(simplified()->CheckedInt32ToTaggedSigned(feedback1),
416 9 : value, effect, control);
417 : Reduction r1 = Reduce(check1);
418 9 : ASSERT_TRUE(r1.Changed());
419 18 : EXPECT_EQ(r1.replacement(), check1);
420 :
421 : Node* check2 = effect =
422 9 : graph()->NewNode(simplified()->CheckedInt32ToTaggedSigned(feedback2),
423 : value, effect, control);
424 : Reduction r2 = Reduce(check2);
425 9 : ASSERT_TRUE(r2.Changed());
426 18 : EXPECT_EQ(r2.replacement(), check1);
427 : }
428 : }
429 : }
430 :
431 : // -----------------------------------------------------------------------------
432 : // CheckedInt64ToInt32
433 :
434 15373 : TEST_F(RedundancyEliminationTest, CheckedInt64ToInt32) {
435 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
436 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
437 9 : Node* value = Parameter(0);
438 : Node* effect = graph()->start();
439 : Node* control = graph()->start();
440 :
441 9 : Node* check1 = effect = graph()->NewNode(
442 9 : simplified()->CheckedInt64ToInt32(feedback1), value, effect, control);
443 : Reduction r1 = Reduce(check1);
444 9 : ASSERT_TRUE(r1.Changed());
445 18 : EXPECT_EQ(r1.replacement(), check1);
446 :
447 9 : Node* check2 = effect = graph()->NewNode(
448 : simplified()->CheckedInt64ToInt32(feedback2), value, effect, control);
449 : Reduction r2 = Reduce(check2);
450 9 : ASSERT_TRUE(r2.Changed());
451 18 : EXPECT_EQ(r2.replacement(), check1);
452 : }
453 : }
454 : }
455 :
456 : // -----------------------------------------------------------------------------
457 : // CheckedInt64ToTaggedSigned
458 :
459 12299 : TEST_F(RedundancyEliminationTest, CheckedInt64ToTaggedSigned) {
460 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
461 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
462 9 : Node* value = Parameter(0);
463 : Node* effect = graph()->start();
464 : Node* control = graph()->start();
465 :
466 : Node* check1 = effect =
467 9 : graph()->NewNode(simplified()->CheckedInt64ToTaggedSigned(feedback1),
468 9 : value, effect, control);
469 : Reduction r1 = Reduce(check1);
470 9 : ASSERT_TRUE(r1.Changed());
471 18 : EXPECT_EQ(r1.replacement(), check1);
472 :
473 : Node* check2 = effect =
474 9 : graph()->NewNode(simplified()->CheckedInt64ToTaggedSigned(feedback2),
475 : value, effect, control);
476 : Reduction r2 = Reduce(check2);
477 9 : ASSERT_TRUE(r2.Changed());
478 18 : EXPECT_EQ(r2.replacement(), check1);
479 : }
480 : }
481 : }
482 :
483 : // -----------------------------------------------------------------------------
484 : // CheckedTaggedSignedToInt32
485 :
486 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedSignedToInt32) {
487 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
488 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
489 9 : Node* value = Parameter(0);
490 : Node* effect = graph()->start();
491 : Node* control = graph()->start();
492 :
493 : Node* check1 = effect =
494 9 : graph()->NewNode(simplified()->CheckedTaggedSignedToInt32(feedback1),
495 9 : value, effect, control);
496 : Reduction r1 = Reduce(check1);
497 9 : ASSERT_TRUE(r1.Changed());
498 18 : EXPECT_EQ(r1.replacement(), check1);
499 :
500 : Node* check2 = effect =
501 9 : graph()->NewNode(simplified()->CheckedTaggedSignedToInt32(feedback2),
502 : value, effect, control);
503 : Reduction r2 = Reduce(check2);
504 9 : ASSERT_TRUE(r2.Changed());
505 18 : EXPECT_EQ(r2.replacement(), check1);
506 : }
507 : }
508 : }
509 :
510 : // -----------------------------------------------------------------------------
511 : // CheckedTaggedToFloat64
512 :
513 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedToFloat64) {
514 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
515 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
516 81 : TRACED_FOREACH(CheckTaggedInputMode, mode, kCheckTaggedInputModes) {
517 18 : Node* value = Parameter(0);
518 : Node* effect = graph()->start();
519 : Node* control = graph()->start();
520 :
521 18 : Node* check1 = effect = graph()->NewNode(
522 : simplified()->CheckedTaggedToFloat64(mode, feedback1), value,
523 18 : effect, control);
524 : Reduction r1 = Reduce(check1);
525 18 : ASSERT_TRUE(r1.Changed());
526 36 : EXPECT_EQ(r1.replacement(), check1);
527 :
528 18 : Node* check2 = effect = graph()->NewNode(
529 : simplified()->CheckedTaggedToFloat64(mode, feedback2), value,
530 : effect, control);
531 : Reduction r2 = Reduce(check2);
532 18 : ASSERT_TRUE(r2.Changed());
533 36 : EXPECT_EQ(r2.replacement(), check1);
534 : }
535 : }
536 : }
537 : }
538 :
539 15373 : TEST_F(RedundancyEliminationTest,
540 : CheckedTaggedToFloat64SubsubmedByCheckedTaggedToFloat64) {
541 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
542 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
543 9 : Node* value = Parameter(0);
544 : Node* effect = graph()->start();
545 : Node* control = graph()->start();
546 :
547 : // If the check passed for CheckTaggedInputMode::kNumber, it'll
548 : // also pass later for CheckTaggedInputMode::kNumberOrOddball.
549 : Node* check1 = effect =
550 9 : graph()->NewNode(simplified()->CheckedTaggedToFloat64(
551 : CheckTaggedInputMode::kNumber, feedback1),
552 9 : value, effect, control);
553 : Reduction r1 = Reduce(check1);
554 9 : ASSERT_TRUE(r1.Changed());
555 18 : EXPECT_EQ(r1.replacement(), check1);
556 :
557 9 : Node* check2 = effect = graph()->NewNode(
558 : simplified()->CheckedTaggedToFloat64(
559 : CheckTaggedInputMode::kNumberOrOddball, feedback2),
560 : value, effect, control);
561 : Reduction r2 = Reduce(check2);
562 9 : ASSERT_TRUE(r2.Changed());
563 18 : EXPECT_EQ(r2.replacement(), check1);
564 : }
565 : }
566 : }
567 :
568 : // -----------------------------------------------------------------------------
569 : // CheckedTaggedToInt32
570 :
571 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedToInt32) {
572 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
573 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
574 81 : TRACED_FOREACH(CheckForMinusZeroMode, mode, kCheckForMinusZeroModes) {
575 18 : Node* value = Parameter(0);
576 : Node* effect = graph()->start();
577 : Node* control = graph()->start();
578 :
579 18 : Node* check1 = effect = graph()->NewNode(
580 : simplified()->CheckedTaggedToInt32(mode, feedback1), value, effect,
581 18 : control);
582 : Reduction r1 = Reduce(check1);
583 18 : ASSERT_TRUE(r1.Changed());
584 36 : EXPECT_EQ(r1.replacement(), check1);
585 :
586 18 : Node* check2 = effect = graph()->NewNode(
587 : simplified()->CheckedTaggedToInt32(mode, feedback2), value, effect,
588 : control);
589 : Reduction r2 = Reduce(check2);
590 18 : ASSERT_TRUE(r2.Changed());
591 36 : EXPECT_EQ(r2.replacement(), check1);
592 : }
593 : }
594 : }
595 : }
596 :
597 15373 : TEST_F(RedundancyEliminationTest,
598 : CheckedTaggedToInt32SubsumedByCheckedTaggedSignedToInt32) {
599 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
600 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
601 81 : TRACED_FOREACH(CheckForMinusZeroMode, mode, kCheckForMinusZeroModes) {
602 18 : Node* value = Parameter(0);
603 : Node* effect = graph()->start();
604 : Node* control = graph()->start();
605 :
606 18 : Node* check1 = effect = graph()->NewNode(
607 : simplified()->CheckedTaggedSignedToInt32(feedback1), value, effect,
608 18 : control);
609 : Reduction r1 = Reduce(check1);
610 18 : ASSERT_TRUE(r1.Changed());
611 36 : EXPECT_EQ(r1.replacement(), check1);
612 :
613 18 : Node* check2 = effect = graph()->NewNode(
614 : simplified()->CheckedTaggedToInt32(mode, feedback2), value, effect,
615 : control);
616 : Reduction r2 = Reduce(check2);
617 18 : ASSERT_TRUE(r2.Changed());
618 36 : EXPECT_EQ(r2.replacement(), check1);
619 : }
620 : }
621 : }
622 : }
623 :
624 : // -----------------------------------------------------------------------------
625 : // CheckedTaggedToInt64
626 :
627 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedToInt64) {
628 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
629 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
630 81 : TRACED_FOREACH(CheckForMinusZeroMode, mode, kCheckForMinusZeroModes) {
631 18 : Node* value = Parameter(0);
632 : Node* effect = graph()->start();
633 : Node* control = graph()->start();
634 :
635 18 : Node* check1 = effect = graph()->NewNode(
636 : simplified()->CheckedTaggedToInt64(mode, feedback1), value, effect,
637 18 : control);
638 : Reduction r1 = Reduce(check1);
639 18 : ASSERT_TRUE(r1.Changed());
640 36 : EXPECT_EQ(r1.replacement(), check1);
641 :
642 18 : Node* check2 = effect = graph()->NewNode(
643 : simplified()->CheckedTaggedToInt64(mode, feedback2), value, effect,
644 : control);
645 : Reduction r2 = Reduce(check2);
646 18 : ASSERT_TRUE(r2.Changed());
647 36 : EXPECT_EQ(r2.replacement(), check1);
648 : }
649 : }
650 : }
651 : }
652 :
653 : // -----------------------------------------------------------------------------
654 : // CheckedTaggedToTaggedPointer
655 :
656 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedToTaggedPointer) {
657 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
658 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
659 9 : Node* value = Parameter(0);
660 : Node* effect = graph()->start();
661 : Node* control = graph()->start();
662 :
663 9 : Node* check1 = effect = graph()->NewNode(
664 : simplified()->CheckedTaggedToTaggedPointer(feedback1), value, effect,
665 9 : control);
666 : Reduction r1 = Reduce(check1);
667 9 : ASSERT_TRUE(r1.Changed());
668 18 : EXPECT_EQ(r1.replacement(), check1);
669 :
670 9 : Node* check2 = effect = graph()->NewNode(
671 : simplified()->CheckedTaggedToTaggedPointer(feedback2), value, effect,
672 : control);
673 : Reduction r2 = Reduce(check2);
674 9 : ASSERT_TRUE(r2.Changed());
675 18 : EXPECT_EQ(r2.replacement(), check1);
676 : }
677 : }
678 : }
679 :
680 : // -----------------------------------------------------------------------------
681 : // CheckedTaggedToTaggedSigned
682 :
683 15373 : TEST_F(RedundancyEliminationTest, CheckedTaggedToTaggedSigned) {
684 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
685 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
686 9 : Node* value = Parameter(0);
687 : Node* effect = graph()->start();
688 : Node* control = graph()->start();
689 :
690 : Node* check1 = effect =
691 9 : graph()->NewNode(simplified()->CheckedTaggedToTaggedSigned(feedback1),
692 9 : value, effect, control);
693 : Reduction r1 = Reduce(check1);
694 9 : ASSERT_TRUE(r1.Changed());
695 18 : EXPECT_EQ(r1.replacement(), check1);
696 :
697 : Node* check2 = effect =
698 9 : graph()->NewNode(simplified()->CheckedTaggedToTaggedSigned(feedback2),
699 : value, effect, control);
700 : Reduction r2 = Reduce(check2);
701 9 : ASSERT_TRUE(r2.Changed());
702 18 : EXPECT_EQ(r2.replacement(), check1);
703 : }
704 : }
705 : }
706 :
707 : // -----------------------------------------------------------------------------
708 : // CheckedTruncateTaggedToWord32
709 :
710 15373 : TEST_F(RedundancyEliminationTest, CheckedTruncateTaggedToWord32) {
711 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
712 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
713 81 : TRACED_FOREACH(CheckTaggedInputMode, mode, kCheckTaggedInputModes) {
714 18 : Node* value = Parameter(0);
715 : Node* effect = graph()->start();
716 : Node* control = graph()->start();
717 :
718 18 : Node* check1 = effect = graph()->NewNode(
719 : simplified()->CheckedTruncateTaggedToWord32(mode, feedback1), value,
720 18 : effect, control);
721 : Reduction r1 = Reduce(check1);
722 18 : ASSERT_TRUE(r1.Changed());
723 36 : EXPECT_EQ(r1.replacement(), check1);
724 :
725 18 : Node* check2 = effect = graph()->NewNode(
726 : simplified()->CheckedTruncateTaggedToWord32(mode, feedback2), value,
727 : effect, control);
728 : Reduction r2 = Reduce(check2);
729 18 : ASSERT_TRUE(r2.Changed());
730 36 : EXPECT_EQ(r2.replacement(), check1);
731 : }
732 : }
733 : }
734 : }
735 :
736 15373 : TEST_F(RedundancyEliminationTest,
737 : CheckedTruncateTaggedToWord32SubsumedByCheckedTruncateTaggedToWord32) {
738 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
739 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
740 9 : Node* value = Parameter(0);
741 : Node* effect = graph()->start();
742 : Node* control = graph()->start();
743 :
744 : // If the check passed for CheckTaggedInputMode::kNumber, it'll
745 : // also pass later for CheckTaggedInputMode::kNumberOrOddball.
746 : Node* check1 = effect =
747 9 : graph()->NewNode(simplified()->CheckedTruncateTaggedToWord32(
748 : CheckTaggedInputMode::kNumber, feedback1),
749 9 : value, effect, control);
750 : Reduction r1 = Reduce(check1);
751 9 : ASSERT_TRUE(r1.Changed());
752 18 : EXPECT_EQ(r1.replacement(), check1);
753 :
754 9 : Node* check2 = effect = graph()->NewNode(
755 : simplified()->CheckedTruncateTaggedToWord32(
756 : CheckTaggedInputMode::kNumberOrOddball, feedback2),
757 : value, effect, control);
758 : Reduction r2 = Reduce(check2);
759 9 : ASSERT_TRUE(r2.Changed());
760 18 : EXPECT_EQ(r2.replacement(), check1);
761 : }
762 : }
763 : }
764 :
765 : // -----------------------------------------------------------------------------
766 : // CheckedUint32Bounds
767 :
768 15373 : TEST_F(RedundancyEliminationTest, CheckedUint32Bounds) {
769 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
770 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
771 9 : Node* index = Parameter(0);
772 9 : Node* length = Parameter(1);
773 : Node* effect = graph()->start();
774 : Node* control = graph()->start();
775 :
776 9 : Node* check1 = effect = graph()->NewNode(
777 : simplified()->CheckedUint32Bounds(
778 : feedback1, CheckBoundsParameters::kDeoptOnOutOfBounds),
779 9 : index, length, effect, control);
780 : Reduction r1 = Reduce(check1);
781 9 : ASSERT_TRUE(r1.Changed());
782 18 : EXPECT_EQ(r1.replacement(), check1);
783 :
784 9 : Node* check2 = effect = graph()->NewNode(
785 : simplified()->CheckedUint32Bounds(
786 : feedback2, CheckBoundsParameters::kDeoptOnOutOfBounds),
787 : index, length, effect, control);
788 : Reduction r2 = Reduce(check2);
789 9 : ASSERT_TRUE(r2.Changed());
790 18 : EXPECT_EQ(r2.replacement(), check1);
791 : }
792 : }
793 : }
794 :
795 : // -----------------------------------------------------------------------------
796 : // CheckedUint32ToInt32
797 :
798 15373 : TEST_F(RedundancyEliminationTest, CheckedUint32ToInt32) {
799 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
800 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
801 9 : Node* value = Parameter(0);
802 : Node* effect = graph()->start();
803 : Node* control = graph()->start();
804 :
805 : Node* check1 = effect =
806 9 : graph()->NewNode(simplified()->CheckedUint32ToInt32(feedback1), value,
807 9 : effect, control);
808 : Reduction r1 = Reduce(check1);
809 9 : ASSERT_TRUE(r1.Changed());
810 18 : EXPECT_EQ(r1.replacement(), check1);
811 :
812 : Node* check2 = effect =
813 9 : graph()->NewNode(simplified()->CheckedUint32ToInt32(feedback2), value,
814 : effect, control);
815 : Reduction r2 = Reduce(check2);
816 9 : ASSERT_TRUE(r2.Changed());
817 18 : EXPECT_EQ(r2.replacement(), check1);
818 : }
819 : }
820 : }
821 :
822 : // -----------------------------------------------------------------------------
823 : // CheckedUint32ToTaggedSigned
824 :
825 15373 : TEST_F(RedundancyEliminationTest, CheckedUint32ToTaggedSigned) {
826 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
827 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
828 9 : Node* value = Parameter(0);
829 : Node* effect = graph()->start();
830 : Node* control = graph()->start();
831 :
832 : Node* check1 = effect =
833 9 : graph()->NewNode(simplified()->CheckedUint32ToTaggedSigned(feedback1),
834 9 : value, effect, control);
835 : Reduction r1 = Reduce(check1);
836 9 : ASSERT_TRUE(r1.Changed());
837 18 : EXPECT_EQ(r1.replacement(), check1);
838 :
839 : Node* check2 = effect =
840 9 : graph()->NewNode(simplified()->CheckedUint32ToTaggedSigned(feedback2),
841 : value, effect, control);
842 : Reduction r2 = Reduce(check2);
843 9 : ASSERT_TRUE(r2.Changed());
844 18 : EXPECT_EQ(r2.replacement(), check1);
845 : }
846 : }
847 : }
848 :
849 : // -----------------------------------------------------------------------------
850 : // CheckedUint64Bounds
851 :
852 15373 : TEST_F(RedundancyEliminationTest, CheckedUint64Bounds) {
853 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
854 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
855 9 : Node* index = Parameter(0);
856 9 : Node* length = Parameter(1);
857 : Node* effect = graph()->start();
858 : Node* control = graph()->start();
859 :
860 : Node* check1 = effect =
861 9 : graph()->NewNode(simplified()->CheckedUint64Bounds(feedback1), index,
862 9 : length, effect, control);
863 : Reduction r1 = Reduce(check1);
864 9 : ASSERT_TRUE(r1.Changed());
865 18 : EXPECT_EQ(r1.replacement(), check1);
866 :
867 : Node* check2 = effect =
868 9 : graph()->NewNode(simplified()->CheckedUint64Bounds(feedback2), index,
869 : length, effect, control);
870 : Reduction r2 = Reduce(check2);
871 9 : ASSERT_TRUE(r2.Changed());
872 18 : EXPECT_EQ(r2.replacement(), check1);
873 : }
874 : }
875 : }
876 :
877 : // -----------------------------------------------------------------------------
878 : // CheckedUint64ToInt32
879 :
880 15373 : TEST_F(RedundancyEliminationTest, CheckedUint64ToInt32) {
881 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
882 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
883 9 : Node* value = Parameter(0);
884 : Node* effect = graph()->start();
885 : Node* control = graph()->start();
886 :
887 : Node* check1 = effect =
888 9 : graph()->NewNode(simplified()->CheckedUint64ToInt32(feedback1), value,
889 9 : effect, control);
890 : Reduction r1 = Reduce(check1);
891 9 : ASSERT_TRUE(r1.Changed());
892 18 : EXPECT_EQ(r1.replacement(), check1);
893 :
894 : Node* check2 = effect =
895 9 : graph()->NewNode(simplified()->CheckedUint64ToInt32(feedback2), value,
896 : effect, control);
897 : Reduction r2 = Reduce(check2);
898 9 : ASSERT_TRUE(r2.Changed());
899 18 : EXPECT_EQ(r2.replacement(), check1);
900 : }
901 : }
902 : }
903 :
904 : // -----------------------------------------------------------------------------
905 : // CheckedUint64ToTaggedSigned
906 :
907 15373 : TEST_F(RedundancyEliminationTest, CheckedUint64ToTaggedSigned) {
908 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
909 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
910 9 : Node* value = Parameter(0);
911 : Node* effect = graph()->start();
912 : Node* control = graph()->start();
913 :
914 : Node* check1 = effect =
915 9 : graph()->NewNode(simplified()->CheckedUint64ToTaggedSigned(feedback1),
916 9 : value, effect, control);
917 : Reduction r1 = Reduce(check1);
918 9 : ASSERT_TRUE(r1.Changed());
919 18 : EXPECT_EQ(r1.replacement(), check1);
920 :
921 : Node* check2 = effect =
922 9 : graph()->NewNode(simplified()->CheckedUint64ToTaggedSigned(feedback2),
923 : value, effect, control);
924 : Reduction r2 = Reduce(check2);
925 9 : ASSERT_TRUE(r2.Changed());
926 18 : EXPECT_EQ(r2.replacement(), check1);
927 : }
928 : }
929 : }
930 :
931 : // -----------------------------------------------------------------------------
932 : // SpeculativeNumberEqual
933 :
934 15373 : TEST_F(RedundancyEliminationTest,
935 : SpeculativeNumberEqualWithCheckBoundsBetterType) {
936 2 : Typer typer(broker(), Typer::kNoFlags, graph());
937 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
938 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
939 9 : Node* lhs = Parameter(Type::Any(), 0);
940 9 : Node* rhs = Parameter(Type::Any(), 1);
941 9 : Node* length = Parameter(Type::Unsigned31(), 2);
942 : Node* effect = graph()->start();
943 : Node* control = graph()->start();
944 :
945 9 : Node* check1 = effect = graph()->NewNode(
946 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
947 : Reduction r1 = Reduce(check1);
948 9 : ASSERT_TRUE(r1.Changed());
949 18 : EXPECT_EQ(r1.replacement(), check1);
950 :
951 9 : Node* check2 = effect = graph()->NewNode(
952 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
953 : Reduction r2 = Reduce(check2);
954 9 : ASSERT_TRUE(r2.Changed());
955 18 : EXPECT_EQ(r2.replacement(), check2);
956 :
957 : Node* cmp3 = effect =
958 9 : graph()->NewNode(simplified()->SpeculativeNumberEqual(
959 : NumberOperationHint::kSignedSmall),
960 : lhs, rhs, effect, control);
961 : Reduction r3 = Reduce(cmp3);
962 9 : ASSERT_TRUE(r3.Changed());
963 90 : EXPECT_THAT(r3.replacement(),
964 : IsSpeculativeNumberEqual(NumberOperationHint::kSignedSmall,
965 0 : check1, check2, _, _));
966 : }
967 : }
968 : }
969 :
970 15373 : TEST_F(RedundancyEliminationTest,
971 : SpeculativeNumberEqualWithCheckBoundsSameType) {
972 2 : Typer typer(broker(), Typer::kNoFlags, graph());
973 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
974 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
975 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
976 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
977 9 : Node* length = Parameter(Type::Unsigned31(), 2);
978 : Node* effect = graph()->start();
979 : Node* control = graph()->start();
980 :
981 9 : Node* check1 = effect = graph()->NewNode(
982 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
983 : Reduction r1 = Reduce(check1);
984 9 : ASSERT_TRUE(r1.Changed());
985 18 : EXPECT_EQ(r1.replacement(), check1);
986 :
987 9 : Node* check2 = effect = graph()->NewNode(
988 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
989 : Reduction r2 = Reduce(check2);
990 9 : ASSERT_TRUE(r2.Changed());
991 18 : EXPECT_EQ(r2.replacement(), check2);
992 :
993 : Node* cmp3 = effect =
994 9 : graph()->NewNode(simplified()->SpeculativeNumberEqual(
995 : NumberOperationHint::kSignedSmall),
996 : lhs, rhs, effect, control);
997 : Reduction r3 = Reduce(cmp3);
998 9 : ASSERT_TRUE(r3.Changed());
999 90 : EXPECT_THAT(r3.replacement(),
1000 : IsSpeculativeNumberEqual(NumberOperationHint::kSignedSmall,
1001 0 : lhs, rhs, _, _));
1002 : }
1003 : }
1004 : }
1005 :
1006 : // -----------------------------------------------------------------------------
1007 : // SpeculativeNumberLessThan
1008 :
1009 15373 : TEST_F(RedundancyEliminationTest,
1010 : SpeculativeNumberLessThanWithCheckBoundsBetterType) {
1011 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1012 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1013 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1014 9 : Node* lhs = Parameter(Type::Any(), 0);
1015 9 : Node* rhs = Parameter(Type::Any(), 1);
1016 9 : Node* length = Parameter(Type::Unsigned31(), 2);
1017 : Node* effect = graph()->start();
1018 : Node* control = graph()->start();
1019 :
1020 9 : Node* check1 = effect = graph()->NewNode(
1021 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
1022 : Reduction r1 = Reduce(check1);
1023 9 : ASSERT_TRUE(r1.Changed());
1024 18 : EXPECT_EQ(r1.replacement(), check1);
1025 :
1026 9 : Node* check2 = effect = graph()->NewNode(
1027 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
1028 : Reduction r2 = Reduce(check2);
1029 9 : ASSERT_TRUE(r2.Changed());
1030 18 : EXPECT_EQ(r2.replacement(), check2);
1031 :
1032 : Node* cmp3 = effect =
1033 9 : graph()->NewNode(simplified()->SpeculativeNumberLessThan(
1034 : NumberOperationHint::kSignedSmall),
1035 : lhs, rhs, effect, control);
1036 : Reduction r3 = Reduce(cmp3);
1037 9 : ASSERT_TRUE(r3.Changed());
1038 90 : EXPECT_THAT(r3.replacement(),
1039 : IsSpeculativeNumberLessThan(NumberOperationHint::kSignedSmall,
1040 0 : check1, check2, _, _));
1041 : }
1042 : }
1043 : }
1044 :
1045 15373 : TEST_F(RedundancyEliminationTest,
1046 : SpeculativeNumberLessThanWithCheckBoundsSameType) {
1047 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1048 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1049 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1050 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
1051 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
1052 9 : Node* length = Parameter(Type::Unsigned31(), 2);
1053 : Node* effect = graph()->start();
1054 : Node* control = graph()->start();
1055 :
1056 9 : Node* check1 = effect = graph()->NewNode(
1057 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
1058 : Reduction r1 = Reduce(check1);
1059 9 : ASSERT_TRUE(r1.Changed());
1060 18 : EXPECT_EQ(r1.replacement(), check1);
1061 :
1062 9 : Node* check2 = effect = graph()->NewNode(
1063 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
1064 : Reduction r2 = Reduce(check2);
1065 9 : ASSERT_TRUE(r2.Changed());
1066 18 : EXPECT_EQ(r2.replacement(), check2);
1067 :
1068 : Node* cmp3 = effect =
1069 9 : graph()->NewNode(simplified()->SpeculativeNumberLessThan(
1070 : NumberOperationHint::kSignedSmall),
1071 : lhs, rhs, effect, control);
1072 : Reduction r3 = Reduce(cmp3);
1073 9 : ASSERT_TRUE(r3.Changed());
1074 90 : EXPECT_THAT(r3.replacement(),
1075 : IsSpeculativeNumberLessThan(NumberOperationHint::kSignedSmall,
1076 0 : lhs, rhs, _, _));
1077 : }
1078 : }
1079 : }
1080 :
1081 : // -----------------------------------------------------------------------------
1082 : // SpeculativeNumberLessThanOrEqual
1083 :
1084 15373 : TEST_F(RedundancyEliminationTest,
1085 : SpeculativeNumberLessThanOrEqualWithCheckBoundsBetterType) {
1086 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1087 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1088 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1089 9 : Node* lhs = Parameter(Type::Any(), 0);
1090 9 : Node* rhs = Parameter(Type::Any(), 1);
1091 9 : Node* length = Parameter(Type::Unsigned31(), 2);
1092 : Node* effect = graph()->start();
1093 : Node* control = graph()->start();
1094 :
1095 9 : Node* check1 = effect = graph()->NewNode(
1096 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
1097 : Reduction r1 = Reduce(check1);
1098 9 : ASSERT_TRUE(r1.Changed());
1099 18 : EXPECT_EQ(r1.replacement(), check1);
1100 :
1101 9 : Node* check2 = effect = graph()->NewNode(
1102 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
1103 : Reduction r2 = Reduce(check2);
1104 9 : ASSERT_TRUE(r2.Changed());
1105 18 : EXPECT_EQ(r2.replacement(), check2);
1106 :
1107 : Node* cmp3 = effect =
1108 9 : graph()->NewNode(simplified()->SpeculativeNumberLessThanOrEqual(
1109 : NumberOperationHint::kSignedSmall),
1110 : lhs, rhs, effect, control);
1111 : Reduction r3 = Reduce(cmp3);
1112 9 : ASSERT_TRUE(r3.Changed());
1113 90 : EXPECT_THAT(r3.replacement(),
1114 : IsSpeculativeNumberLessThanOrEqual(
1115 0 : NumberOperationHint::kSignedSmall, check1, check2, _, _));
1116 : }
1117 : }
1118 : }
1119 :
1120 15373 : TEST_F(RedundancyEliminationTest,
1121 : SpeculativeNumberLessThanOrEqualWithCheckBoundsSameType) {
1122 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1123 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1124 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1125 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
1126 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
1127 9 : Node* length = Parameter(Type::Unsigned31(), 2);
1128 : Node* effect = graph()->start();
1129 : Node* control = graph()->start();
1130 :
1131 9 : Node* check1 = effect = graph()->NewNode(
1132 9 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
1133 : Reduction r1 = Reduce(check1);
1134 9 : ASSERT_TRUE(r1.Changed());
1135 18 : EXPECT_EQ(r1.replacement(), check1);
1136 :
1137 9 : Node* check2 = effect = graph()->NewNode(
1138 9 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
1139 : Reduction r2 = Reduce(check2);
1140 9 : ASSERT_TRUE(r2.Changed());
1141 18 : EXPECT_EQ(r2.replacement(), check2);
1142 :
1143 : Node* cmp3 = effect =
1144 9 : graph()->NewNode(simplified()->SpeculativeNumberLessThanOrEqual(
1145 : NumberOperationHint::kSignedSmall),
1146 : lhs, rhs, effect, control);
1147 : Reduction r3 = Reduce(cmp3);
1148 9 : ASSERT_TRUE(r3.Changed());
1149 90 : EXPECT_THAT(r3.replacement(),
1150 : IsSpeculativeNumberLessThanOrEqual(
1151 0 : NumberOperationHint::kSignedSmall, lhs, rhs, _, _));
1152 : }
1153 : }
1154 : }
1155 :
1156 : // -----------------------------------------------------------------------------
1157 : // SpeculativeNumberAdd
1158 :
1159 15373 : TEST_F(RedundancyEliminationTest,
1160 : SpeculativeNumberAddWithCheckBoundsBetterType) {
1161 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1162 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1163 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1164 15 : Node* lhs = Parameter(Type::Any(), 0);
1165 15 : Node* rhs = Parameter(Type::Any(), 1);
1166 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1167 : Node* effect = graph()->start();
1168 : Node* control = graph()->start();
1169 :
1170 15 : Node* check1 = effect = graph()->NewNode(
1171 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1172 : Reduction r1 = Reduce(check1);
1173 15 : ASSERT_TRUE(r1.Changed());
1174 30 : EXPECT_EQ(r1.replacement(), check1);
1175 :
1176 15 : Node* add2 = effect = graph()->NewNode(
1177 : simplified()->SpeculativeNumberAdd(hint), lhs, rhs, effect, control);
1178 : Reduction r2 = Reduce(add2);
1179 15 : ASSERT_TRUE(r2.Changed());
1180 150 : EXPECT_THAT(r2.replacement(),
1181 0 : IsSpeculativeNumberAdd(hint, check1, rhs, _, _));
1182 : }
1183 : }
1184 : }
1185 :
1186 15373 : TEST_F(RedundancyEliminationTest, SpeculativeNumberAddWithCheckBoundsSameType) {
1187 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1188 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1189 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1190 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1191 15 : Node* rhs = Parameter(Type::Any(), 0);
1192 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1193 : Node* effect = graph()->start();
1194 : Node* control = graph()->start();
1195 :
1196 15 : Node* check1 = effect = graph()->NewNode(
1197 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1198 : Reduction r1 = Reduce(check1);
1199 15 : ASSERT_TRUE(r1.Changed());
1200 30 : EXPECT_EQ(r1.replacement(), check1);
1201 :
1202 15 : Node* add2 = effect = graph()->NewNode(
1203 : simplified()->SpeculativeNumberAdd(hint), lhs, rhs, effect, control);
1204 : Reduction r2 = Reduce(add2);
1205 15 : ASSERT_TRUE(r2.Changed());
1206 150 : EXPECT_THAT(r2.replacement(),
1207 0 : IsSpeculativeNumberAdd(hint, lhs, rhs, _, _));
1208 : }
1209 : }
1210 : }
1211 :
1212 : // -----------------------------------------------------------------------------
1213 : // SpeculativeNumberSubtract
1214 :
1215 15373 : TEST_F(RedundancyEliminationTest,
1216 : SpeculativeNumberSubtractWithCheckBoundsBetterType) {
1217 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1218 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1219 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1220 15 : Node* lhs = Parameter(Type::Any(), 0);
1221 15 : Node* rhs = Parameter(Type::Any(), 1);
1222 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1223 : Node* effect = graph()->start();
1224 : Node* control = graph()->start();
1225 :
1226 15 : Node* check1 = effect = graph()->NewNode(
1227 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1228 : Reduction r1 = Reduce(check1);
1229 15 : ASSERT_TRUE(r1.Changed());
1230 30 : EXPECT_EQ(r1.replacement(), check1);
1231 :
1232 : Node* subtract2 = effect =
1233 15 : graph()->NewNode(simplified()->SpeculativeNumberSubtract(hint), lhs,
1234 : rhs, effect, control);
1235 : Reduction r2 = Reduce(subtract2);
1236 15 : ASSERT_TRUE(r2.Changed());
1237 150 : EXPECT_THAT(r2.replacement(),
1238 0 : IsSpeculativeNumberSubtract(hint, check1, rhs, _, _));
1239 : }
1240 : }
1241 : }
1242 :
1243 15373 : TEST_F(RedundancyEliminationTest,
1244 : SpeculativeNumberSubtractWithCheckBoundsSameType) {
1245 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1246 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1247 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1248 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1249 15 : Node* rhs = Parameter(Type::Any(), 0);
1250 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1251 : Node* effect = graph()->start();
1252 : Node* control = graph()->start();
1253 :
1254 15 : Node* check1 = effect = graph()->NewNode(
1255 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1256 : Reduction r1 = Reduce(check1);
1257 15 : ASSERT_TRUE(r1.Changed());
1258 30 : EXPECT_EQ(r1.replacement(), check1);
1259 :
1260 : Node* subtract2 = effect =
1261 15 : graph()->NewNode(simplified()->SpeculativeNumberSubtract(hint), lhs,
1262 : rhs, effect, control);
1263 : Reduction r2 = Reduce(subtract2);
1264 15 : ASSERT_TRUE(r2.Changed());
1265 150 : EXPECT_THAT(r2.replacement(),
1266 0 : IsSpeculativeNumberSubtract(hint, lhs, rhs, _, _));
1267 : }
1268 : }
1269 : }
1270 :
1271 : // -----------------------------------------------------------------------------
1272 : // SpeculativeSafeIntegerAdd
1273 :
1274 15373 : TEST_F(RedundancyEliminationTest,
1275 : SpeculativeSafeIntegerAddWithCheckBoundsBetterType) {
1276 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1277 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1278 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1279 15 : Node* lhs = Parameter(Type::Any(), 0);
1280 15 : Node* rhs = Parameter(Type::Any(), 1);
1281 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1282 : Node* effect = graph()->start();
1283 : Node* control = graph()->start();
1284 :
1285 15 : Node* check1 = effect = graph()->NewNode(
1286 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1287 : Reduction r1 = Reduce(check1);
1288 15 : ASSERT_TRUE(r1.Changed());
1289 30 : EXPECT_EQ(r1.replacement(), check1);
1290 :
1291 : Node* add2 = effect =
1292 15 : graph()->NewNode(simplified()->SpeculativeSafeIntegerAdd(hint), lhs,
1293 : rhs, effect, control);
1294 : Reduction r2 = Reduce(add2);
1295 15 : ASSERT_TRUE(r2.Changed());
1296 150 : EXPECT_THAT(r2.replacement(),
1297 0 : IsSpeculativeSafeIntegerAdd(hint, check1, rhs, _, _));
1298 : }
1299 : }
1300 : }
1301 :
1302 15373 : TEST_F(RedundancyEliminationTest,
1303 : SpeculativeSafeIntegerAddWithCheckBoundsSameType) {
1304 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1305 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1306 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1307 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1308 15 : Node* rhs = Parameter(Type::Any(), 0);
1309 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1310 : Node* effect = graph()->start();
1311 : Node* control = graph()->start();
1312 :
1313 15 : Node* check1 = effect = graph()->NewNode(
1314 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1315 : Reduction r1 = Reduce(check1);
1316 15 : ASSERT_TRUE(r1.Changed());
1317 30 : EXPECT_EQ(r1.replacement(), check1);
1318 :
1319 : Node* add2 = effect =
1320 15 : graph()->NewNode(simplified()->SpeculativeSafeIntegerAdd(hint), lhs,
1321 : rhs, effect, control);
1322 : Reduction r2 = Reduce(add2);
1323 15 : ASSERT_TRUE(r2.Changed());
1324 150 : EXPECT_THAT(r2.replacement(),
1325 0 : IsSpeculativeSafeIntegerAdd(hint, lhs, rhs, _, _));
1326 : }
1327 : }
1328 : }
1329 :
1330 : // -----------------------------------------------------------------------------
1331 : // SpeculativeSafeIntegerSubtract
1332 :
1333 15373 : TEST_F(RedundancyEliminationTest,
1334 : SpeculativeSafeIntegerSubtractWithCheckBoundsBetterType) {
1335 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1336 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1337 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1338 15 : Node* lhs = Parameter(Type::Any(), 0);
1339 15 : Node* rhs = Parameter(Type::Any(), 1);
1340 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1341 : Node* effect = graph()->start();
1342 : Node* control = graph()->start();
1343 :
1344 15 : Node* check1 = effect = graph()->NewNode(
1345 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1346 : Reduction r1 = Reduce(check1);
1347 15 : ASSERT_TRUE(r1.Changed());
1348 30 : EXPECT_EQ(r1.replacement(), check1);
1349 :
1350 : Node* subtract2 = effect =
1351 15 : graph()->NewNode(simplified()->SpeculativeSafeIntegerSubtract(hint),
1352 : lhs, rhs, effect, control);
1353 : Reduction r2 = Reduce(subtract2);
1354 15 : ASSERT_TRUE(r2.Changed());
1355 150 : EXPECT_THAT(r2.replacement(),
1356 0 : IsSpeculativeSafeIntegerSubtract(hint, check1, rhs, _, _));
1357 : }
1358 : }
1359 : }
1360 :
1361 15373 : TEST_F(RedundancyEliminationTest,
1362 : SpeculativeSafeIntegerSubtractWithCheckBoundsSameType) {
1363 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1364 13 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1365 63 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1366 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1367 15 : Node* rhs = Parameter(Type::Any(), 0);
1368 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1369 : Node* effect = graph()->start();
1370 : Node* control = graph()->start();
1371 :
1372 15 : Node* check1 = effect = graph()->NewNode(
1373 15 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1374 : Reduction r1 = Reduce(check1);
1375 15 : ASSERT_TRUE(r1.Changed());
1376 30 : EXPECT_EQ(r1.replacement(), check1);
1377 :
1378 : Node* subtract2 = effect =
1379 15 : graph()->NewNode(simplified()->SpeculativeSafeIntegerSubtract(hint),
1380 : lhs, rhs, effect, control);
1381 : Reduction r2 = Reduce(subtract2);
1382 15 : ASSERT_TRUE(r2.Changed());
1383 150 : EXPECT_THAT(r2.replacement(),
1384 0 : IsSpeculativeSafeIntegerSubtract(hint, lhs, rhs, _, _));
1385 : }
1386 : }
1387 : }
1388 :
1389 : // -----------------------------------------------------------------------------
1390 : // SpeculativeToNumber
1391 :
1392 15373 : TEST_F(RedundancyEliminationTest,
1393 : SpeculativeToNumberWithCheckBoundsBetterType) {
1394 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1395 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1396 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1397 189 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1398 45 : Node* index = Parameter(Type::Any(), 0);
1399 45 : Node* length = Parameter(Type::Unsigned31(), 1);
1400 : Node* effect = graph()->start();
1401 : Node* control = graph()->start();
1402 :
1403 : Node* check1 = effect =
1404 45 : graph()->NewNode(simplified()->CheckBounds(feedback1), index,
1405 45 : length, effect, control);
1406 : Reduction r1 = Reduce(check1);
1407 45 : ASSERT_TRUE(r1.Changed());
1408 90 : EXPECT_EQ(r1.replacement(), check1);
1409 :
1410 : Node* to_number2 = effect =
1411 45 : graph()->NewNode(simplified()->SpeculativeToNumber(hint, feedback2),
1412 : index, effect, control);
1413 : Reduction r2 = Reduce(to_number2);
1414 45 : ASSERT_TRUE(r2.Changed());
1415 225 : EXPECT_THAT(r2.replacement(), IsSpeculativeToNumber(check1));
1416 : }
1417 : }
1418 : }
1419 : }
1420 :
1421 15373 : TEST_F(RedundancyEliminationTest, SpeculativeToNumberWithCheckBoundsSameType) {
1422 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1423 13 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1424 39 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1425 189 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1426 45 : Node* index = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1427 45 : Node* length = Parameter(Type::Unsigned31(), 1);
1428 : Node* effect = graph()->start();
1429 : Node* control = graph()->start();
1430 :
1431 : Node* check1 = effect =
1432 45 : graph()->NewNode(simplified()->CheckBounds(feedback1), index,
1433 45 : length, effect, control);
1434 : Reduction r1 = Reduce(check1);
1435 45 : ASSERT_TRUE(r1.Changed());
1436 90 : EXPECT_EQ(r1.replacement(), check1);
1437 :
1438 : Node* to_number2 = effect =
1439 45 : graph()->NewNode(simplified()->SpeculativeToNumber(hint, feedback2),
1440 : index, effect, control);
1441 : Reduction r2 = Reduce(to_number2);
1442 45 : ASSERT_TRUE(r2.Changed());
1443 225 : EXPECT_THAT(r2.replacement(), IsSpeculativeToNumber(index));
1444 : }
1445 : }
1446 : }
1447 : }
1448 :
1449 : } // namespace redundancy_elimination_unittest
1450 : } // namespace compiler
1451 : } // namespace internal
1452 9222 : } // namespace v8
|