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