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