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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 15188 : 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 = graph()->NewNode(
672 : simplified()->CheckedUint32Bounds(
673 : feedback1, CheckBoundsParameters::kDeoptOnOutOfBounds),
674 18 : index, length, effect, control);
675 : Reduction r1 = Reduce(check1);
676 9 : ASSERT_TRUE(r1.Changed());
677 18 : EXPECT_EQ(r1.replacement(), check1);
678 :
679 : Node* check2 = effect = graph()->NewNode(
680 : simplified()->CheckedUint32Bounds(
681 : feedback2, CheckBoundsParameters::kDeoptOnOutOfBounds),
682 9 : index, length, effect, control);
683 : Reduction r2 = Reduce(check2);
684 9 : ASSERT_TRUE(r2.Changed());
685 18 : EXPECT_EQ(r2.replacement(), check1);
686 9 : }
687 3 : }
688 : }
689 :
690 : // -----------------------------------------------------------------------------
691 : // CheckedUint32ToInt32
692 :
693 15188 : TEST_F(RedundancyEliminationTest, CheckedUint32ToInt32) {
694 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
695 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
696 9 : Node* value = Parameter(0);
697 9 : Node* effect = graph()->start();
698 : Node* control = graph()->start();
699 :
700 : Node* check1 = effect =
701 : graph()->NewNode(simplified()->CheckedUint32ToInt32(feedback1), value,
702 18 : effect, control);
703 : Reduction r1 = Reduce(check1);
704 9 : ASSERT_TRUE(r1.Changed());
705 18 : EXPECT_EQ(r1.replacement(), check1);
706 :
707 : Node* check2 = effect =
708 : graph()->NewNode(simplified()->CheckedUint32ToInt32(feedback2), value,
709 9 : effect, control);
710 : Reduction r2 = Reduce(check2);
711 9 : ASSERT_TRUE(r2.Changed());
712 18 : EXPECT_EQ(r2.replacement(), check1);
713 9 : }
714 3 : }
715 : }
716 :
717 : // -----------------------------------------------------------------------------
718 : // CheckedUint32ToTaggedSigned
719 :
720 15188 : TEST_F(RedundancyEliminationTest, CheckedUint32ToTaggedSigned) {
721 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
722 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
723 9 : Node* value = Parameter(0);
724 9 : Node* effect = graph()->start();
725 : Node* control = graph()->start();
726 :
727 : Node* check1 = effect =
728 : graph()->NewNode(simplified()->CheckedUint32ToTaggedSigned(feedback1),
729 18 : value, effect, control);
730 : Reduction r1 = Reduce(check1);
731 9 : ASSERT_TRUE(r1.Changed());
732 18 : EXPECT_EQ(r1.replacement(), check1);
733 :
734 : Node* check2 = effect =
735 : graph()->NewNode(simplified()->CheckedUint32ToTaggedSigned(feedback2),
736 9 : value, effect, control);
737 : Reduction r2 = Reduce(check2);
738 9 : ASSERT_TRUE(r2.Changed());
739 18 : EXPECT_EQ(r2.replacement(), check1);
740 9 : }
741 3 : }
742 : }
743 :
744 : // -----------------------------------------------------------------------------
745 : // CheckedUint64Bounds
746 :
747 15188 : TEST_F(RedundancyEliminationTest, CheckedUint64Bounds) {
748 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
749 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
750 9 : Node* index = Parameter(0);
751 9 : Node* length = Parameter(1);
752 9 : Node* effect = graph()->start();
753 : Node* control = graph()->start();
754 :
755 : Node* check1 = effect =
756 : graph()->NewNode(simplified()->CheckedUint64Bounds(feedback1), index,
757 18 : length, effect, control);
758 : Reduction r1 = Reduce(check1);
759 9 : ASSERT_TRUE(r1.Changed());
760 18 : EXPECT_EQ(r1.replacement(), check1);
761 :
762 : Node* check2 = effect =
763 : graph()->NewNode(simplified()->CheckedUint64Bounds(feedback2), index,
764 9 : length, effect, control);
765 : Reduction r2 = Reduce(check2);
766 9 : ASSERT_TRUE(r2.Changed());
767 18 : EXPECT_EQ(r2.replacement(), check1);
768 9 : }
769 3 : }
770 : }
771 :
772 : // -----------------------------------------------------------------------------
773 : // CheckedUint64ToInt32
774 :
775 15188 : TEST_F(RedundancyEliminationTest, CheckedUint64ToInt32) {
776 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
777 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
778 9 : Node* value = Parameter(0);
779 9 : Node* effect = graph()->start();
780 : Node* control = graph()->start();
781 :
782 : Node* check1 = effect =
783 : graph()->NewNode(simplified()->CheckedUint64ToInt32(feedback1), value,
784 18 : effect, control);
785 : Reduction r1 = Reduce(check1);
786 9 : ASSERT_TRUE(r1.Changed());
787 18 : EXPECT_EQ(r1.replacement(), check1);
788 :
789 : Node* check2 = effect =
790 : graph()->NewNode(simplified()->CheckedUint64ToInt32(feedback2), value,
791 9 : effect, control);
792 : Reduction r2 = Reduce(check2);
793 9 : ASSERT_TRUE(r2.Changed());
794 18 : EXPECT_EQ(r2.replacement(), check1);
795 9 : }
796 3 : }
797 : }
798 :
799 : // -----------------------------------------------------------------------------
800 : // CheckedUint64ToTaggedSigned
801 :
802 15188 : TEST_F(RedundancyEliminationTest, CheckedUint64ToTaggedSigned) {
803 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
804 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
805 9 : Node* value = Parameter(0);
806 9 : Node* effect = graph()->start();
807 : Node* control = graph()->start();
808 :
809 : Node* check1 = effect =
810 : graph()->NewNode(simplified()->CheckedUint64ToTaggedSigned(feedback1),
811 18 : value, effect, control);
812 : Reduction r1 = Reduce(check1);
813 9 : ASSERT_TRUE(r1.Changed());
814 18 : EXPECT_EQ(r1.replacement(), check1);
815 :
816 : Node* check2 = effect =
817 : graph()->NewNode(simplified()->CheckedUint64ToTaggedSigned(feedback2),
818 9 : value, effect, control);
819 : Reduction r2 = Reduce(check2);
820 9 : ASSERT_TRUE(r2.Changed());
821 18 : EXPECT_EQ(r2.replacement(), check1);
822 9 : }
823 3 : }
824 : }
825 :
826 : // -----------------------------------------------------------------------------
827 : // SpeculativeNumberEqual
828 :
829 15188 : TEST_F(RedundancyEliminationTest,
830 : SpeculativeNumberEqualWithCheckBoundsBetterType) {
831 2 : Typer typer(broker(), Typer::kNoFlags, graph());
832 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
833 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
834 9 : Node* lhs = Parameter(Type::Any(), 0);
835 9 : Node* rhs = Parameter(Type::Any(), 1);
836 9 : Node* length = Parameter(Type::Unsigned31(), 2);
837 9 : Node* effect = graph()->start();
838 : Node* control = graph()->start();
839 :
840 : Node* check1 = effect = graph()->NewNode(
841 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
842 : Reduction r1 = Reduce(check1);
843 9 : ASSERT_TRUE(r1.Changed());
844 18 : EXPECT_EQ(r1.replacement(), check1);
845 :
846 : Node* check2 = effect = graph()->NewNode(
847 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
848 : Reduction r2 = Reduce(check2);
849 9 : ASSERT_TRUE(r2.Changed());
850 18 : EXPECT_EQ(r2.replacement(), check2);
851 :
852 : Node* cmp3 = effect =
853 : graph()->NewNode(simplified()->SpeculativeNumberEqual(
854 : NumberOperationHint::kSignedSmall),
855 9 : lhs, rhs, effect, control);
856 : Reduction r3 = Reduce(cmp3);
857 9 : ASSERT_TRUE(r3.Changed());
858 90 : EXPECT_THAT(r3.replacement(),
859 : IsSpeculativeNumberEqual(NumberOperationHint::kSignedSmall,
860 0 : check1, check2, _, _));
861 9 : }
862 4 : }
863 : }
864 :
865 15188 : TEST_F(RedundancyEliminationTest,
866 : SpeculativeNumberEqualWithCheckBoundsSameType) {
867 2 : Typer typer(broker(), Typer::kNoFlags, graph());
868 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
869 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
870 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
871 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
872 9 : Node* length = Parameter(Type::Unsigned31(), 2);
873 9 : Node* effect = graph()->start();
874 : Node* control = graph()->start();
875 :
876 : Node* check1 = effect = graph()->NewNode(
877 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
878 : Reduction r1 = Reduce(check1);
879 9 : ASSERT_TRUE(r1.Changed());
880 18 : EXPECT_EQ(r1.replacement(), check1);
881 :
882 : Node* check2 = effect = graph()->NewNode(
883 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
884 : Reduction r2 = Reduce(check2);
885 9 : ASSERT_TRUE(r2.Changed());
886 18 : EXPECT_EQ(r2.replacement(), check2);
887 :
888 : Node* cmp3 = effect =
889 : graph()->NewNode(simplified()->SpeculativeNumberEqual(
890 : NumberOperationHint::kSignedSmall),
891 9 : lhs, rhs, effect, control);
892 : Reduction r3 = Reduce(cmp3);
893 9 : ASSERT_TRUE(r3.Changed());
894 90 : EXPECT_THAT(r3.replacement(),
895 : IsSpeculativeNumberEqual(NumberOperationHint::kSignedSmall,
896 0 : lhs, rhs, _, _));
897 9 : }
898 4 : }
899 : }
900 :
901 : // -----------------------------------------------------------------------------
902 : // SpeculativeNumberLessThan
903 :
904 15188 : TEST_F(RedundancyEliminationTest,
905 : SpeculativeNumberLessThanWithCheckBoundsBetterType) {
906 2 : Typer typer(broker(), Typer::kNoFlags, graph());
907 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
908 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
909 9 : Node* lhs = Parameter(Type::Any(), 0);
910 9 : Node* rhs = Parameter(Type::Any(), 1);
911 9 : Node* length = Parameter(Type::Unsigned31(), 2);
912 9 : Node* effect = graph()->start();
913 : Node* control = graph()->start();
914 :
915 : Node* check1 = effect = graph()->NewNode(
916 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
917 : Reduction r1 = Reduce(check1);
918 9 : ASSERT_TRUE(r1.Changed());
919 18 : EXPECT_EQ(r1.replacement(), check1);
920 :
921 : Node* check2 = effect = graph()->NewNode(
922 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
923 : Reduction r2 = Reduce(check2);
924 9 : ASSERT_TRUE(r2.Changed());
925 18 : EXPECT_EQ(r2.replacement(), check2);
926 :
927 : Node* cmp3 = effect =
928 : graph()->NewNode(simplified()->SpeculativeNumberLessThan(
929 : NumberOperationHint::kSignedSmall),
930 9 : lhs, rhs, effect, control);
931 : Reduction r3 = Reduce(cmp3);
932 9 : ASSERT_TRUE(r3.Changed());
933 90 : EXPECT_THAT(r3.replacement(),
934 : IsSpeculativeNumberLessThan(NumberOperationHint::kSignedSmall,
935 0 : check1, check2, _, _));
936 9 : }
937 4 : }
938 : }
939 :
940 15188 : TEST_F(RedundancyEliminationTest,
941 : SpeculativeNumberLessThanWithCheckBoundsSameType) {
942 2 : Typer typer(broker(), Typer::kNoFlags, graph());
943 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
944 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
945 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
946 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
947 9 : Node* length = Parameter(Type::Unsigned31(), 2);
948 9 : Node* effect = graph()->start();
949 : Node* control = graph()->start();
950 :
951 : Node* check1 = effect = graph()->NewNode(
952 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
953 : Reduction r1 = Reduce(check1);
954 9 : ASSERT_TRUE(r1.Changed());
955 18 : EXPECT_EQ(r1.replacement(), check1);
956 :
957 : Node* check2 = effect = graph()->NewNode(
958 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
959 : Reduction r2 = Reduce(check2);
960 9 : ASSERT_TRUE(r2.Changed());
961 18 : EXPECT_EQ(r2.replacement(), check2);
962 :
963 : Node* cmp3 = effect =
964 : graph()->NewNode(simplified()->SpeculativeNumberLessThan(
965 : NumberOperationHint::kSignedSmall),
966 9 : lhs, rhs, effect, control);
967 : Reduction r3 = Reduce(cmp3);
968 9 : ASSERT_TRUE(r3.Changed());
969 90 : EXPECT_THAT(r3.replacement(),
970 : IsSpeculativeNumberLessThan(NumberOperationHint::kSignedSmall,
971 0 : lhs, rhs, _, _));
972 9 : }
973 4 : }
974 : }
975 :
976 : // -----------------------------------------------------------------------------
977 : // SpeculativeNumberLessThanOrEqual
978 :
979 15188 : TEST_F(RedundancyEliminationTest,
980 : SpeculativeNumberLessThanOrEqualWithCheckBoundsBetterType) {
981 2 : Typer typer(broker(), Typer::kNoFlags, graph());
982 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
983 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
984 9 : Node* lhs = Parameter(Type::Any(), 0);
985 9 : Node* rhs = Parameter(Type::Any(), 1);
986 9 : Node* length = Parameter(Type::Unsigned31(), 2);
987 9 : Node* effect = graph()->start();
988 : Node* control = graph()->start();
989 :
990 : Node* check1 = effect = graph()->NewNode(
991 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
992 : Reduction r1 = Reduce(check1);
993 9 : ASSERT_TRUE(r1.Changed());
994 18 : EXPECT_EQ(r1.replacement(), check1);
995 :
996 : Node* check2 = effect = graph()->NewNode(
997 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
998 : Reduction r2 = Reduce(check2);
999 9 : ASSERT_TRUE(r2.Changed());
1000 18 : EXPECT_EQ(r2.replacement(), check2);
1001 :
1002 : Node* cmp3 = effect =
1003 : graph()->NewNode(simplified()->SpeculativeNumberLessThanOrEqual(
1004 : NumberOperationHint::kSignedSmall),
1005 9 : lhs, rhs, effect, control);
1006 : Reduction r3 = Reduce(cmp3);
1007 9 : ASSERT_TRUE(r3.Changed());
1008 90 : EXPECT_THAT(r3.replacement(),
1009 : IsSpeculativeNumberLessThanOrEqual(
1010 0 : NumberOperationHint::kSignedSmall, check1, check2, _, _));
1011 9 : }
1012 4 : }
1013 : }
1014 :
1015 15188 : TEST_F(RedundancyEliminationTest,
1016 : SpeculativeNumberLessThanOrEqualWithCheckBoundsSameType) {
1017 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1018 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1019 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1020 9 : Node* lhs = Parameter(Type::UnsignedSmall(), 0);
1021 9 : Node* rhs = Parameter(Type::UnsignedSmall(), 1);
1022 9 : Node* length = Parameter(Type::Unsigned31(), 2);
1023 9 : Node* effect = graph()->start();
1024 : Node* control = graph()->start();
1025 :
1026 : Node* check1 = effect = graph()->NewNode(
1027 18 : simplified()->CheckBounds(feedback1), lhs, length, effect, control);
1028 : Reduction r1 = Reduce(check1);
1029 9 : ASSERT_TRUE(r1.Changed());
1030 18 : EXPECT_EQ(r1.replacement(), check1);
1031 :
1032 : Node* check2 = effect = graph()->NewNode(
1033 18 : simplified()->CheckBounds(feedback2), rhs, length, effect, control);
1034 : Reduction r2 = Reduce(check2);
1035 9 : ASSERT_TRUE(r2.Changed());
1036 18 : EXPECT_EQ(r2.replacement(), check2);
1037 :
1038 : Node* cmp3 = effect =
1039 : graph()->NewNode(simplified()->SpeculativeNumberLessThanOrEqual(
1040 : NumberOperationHint::kSignedSmall),
1041 9 : lhs, rhs, effect, control);
1042 : Reduction r3 = Reduce(cmp3);
1043 9 : ASSERT_TRUE(r3.Changed());
1044 90 : EXPECT_THAT(r3.replacement(),
1045 : IsSpeculativeNumberLessThanOrEqual(
1046 0 : NumberOperationHint::kSignedSmall, lhs, rhs, _, _));
1047 9 : }
1048 4 : }
1049 : }
1050 :
1051 : // -----------------------------------------------------------------------------
1052 : // SpeculativeNumberAdd
1053 :
1054 15188 : TEST_F(RedundancyEliminationTest,
1055 : SpeculativeNumberAddWithCheckBoundsBetterType) {
1056 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1057 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1058 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1059 15 : Node* lhs = Parameter(Type::Any(), 0);
1060 15 : Node* rhs = Parameter(Type::Any(), 1);
1061 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1062 15 : Node* effect = graph()->start();
1063 : Node* control = graph()->start();
1064 :
1065 : Node* check1 = effect = graph()->NewNode(
1066 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1067 : Reduction r1 = Reduce(check1);
1068 15 : ASSERT_TRUE(r1.Changed());
1069 30 : EXPECT_EQ(r1.replacement(), check1);
1070 :
1071 : Node* add2 = effect = graph()->NewNode(
1072 15 : simplified()->SpeculativeNumberAdd(hint), lhs, rhs, effect, control);
1073 : Reduction r2 = Reduce(add2);
1074 15 : ASSERT_TRUE(r2.Changed());
1075 150 : EXPECT_THAT(r2.replacement(),
1076 0 : IsSpeculativeNumberAdd(hint, check1, rhs, _, _));
1077 15 : }
1078 4 : }
1079 : }
1080 :
1081 15188 : TEST_F(RedundancyEliminationTest, SpeculativeNumberAddWithCheckBoundsSameType) {
1082 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1083 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1084 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1085 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1086 15 : Node* rhs = Parameter(Type::Any(), 0);
1087 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1088 15 : Node* effect = graph()->start();
1089 : Node* control = graph()->start();
1090 :
1091 : Node* check1 = effect = graph()->NewNode(
1092 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1093 : Reduction r1 = Reduce(check1);
1094 15 : ASSERT_TRUE(r1.Changed());
1095 30 : EXPECT_EQ(r1.replacement(), check1);
1096 :
1097 : Node* add2 = effect = graph()->NewNode(
1098 15 : simplified()->SpeculativeNumberAdd(hint), lhs, rhs, effect, control);
1099 : Reduction r2 = Reduce(add2);
1100 15 : ASSERT_TRUE(r2.Changed());
1101 150 : EXPECT_THAT(r2.replacement(),
1102 0 : IsSpeculativeNumberAdd(hint, lhs, rhs, _, _));
1103 15 : }
1104 4 : }
1105 : }
1106 :
1107 : // -----------------------------------------------------------------------------
1108 : // SpeculativeNumberSubtract
1109 :
1110 15188 : TEST_F(RedundancyEliminationTest,
1111 : SpeculativeNumberSubtractWithCheckBoundsBetterType) {
1112 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1113 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1114 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1115 15 : Node* lhs = Parameter(Type::Any(), 0);
1116 15 : Node* rhs = Parameter(Type::Any(), 1);
1117 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1118 15 : Node* effect = graph()->start();
1119 : Node* control = graph()->start();
1120 :
1121 : Node* check1 = effect = graph()->NewNode(
1122 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1123 : Reduction r1 = Reduce(check1);
1124 15 : ASSERT_TRUE(r1.Changed());
1125 30 : EXPECT_EQ(r1.replacement(), check1);
1126 :
1127 : Node* subtract2 = effect =
1128 : graph()->NewNode(simplified()->SpeculativeNumberSubtract(hint), lhs,
1129 15 : rhs, effect, control);
1130 : Reduction r2 = Reduce(subtract2);
1131 15 : ASSERT_TRUE(r2.Changed());
1132 150 : EXPECT_THAT(r2.replacement(),
1133 0 : IsSpeculativeNumberSubtract(hint, check1, rhs, _, _));
1134 15 : }
1135 4 : }
1136 : }
1137 :
1138 15188 : TEST_F(RedundancyEliminationTest,
1139 : SpeculativeNumberSubtractWithCheckBoundsSameType) {
1140 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1141 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1142 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1143 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1144 15 : Node* rhs = Parameter(Type::Any(), 0);
1145 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1146 15 : Node* effect = graph()->start();
1147 : Node* control = graph()->start();
1148 :
1149 : Node* check1 = effect = graph()->NewNode(
1150 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1151 : Reduction r1 = Reduce(check1);
1152 15 : ASSERT_TRUE(r1.Changed());
1153 30 : EXPECT_EQ(r1.replacement(), check1);
1154 :
1155 : Node* subtract2 = effect =
1156 : graph()->NewNode(simplified()->SpeculativeNumberSubtract(hint), lhs,
1157 15 : rhs, effect, control);
1158 : Reduction r2 = Reduce(subtract2);
1159 15 : ASSERT_TRUE(r2.Changed());
1160 150 : EXPECT_THAT(r2.replacement(),
1161 0 : IsSpeculativeNumberSubtract(hint, lhs, rhs, _, _));
1162 15 : }
1163 4 : }
1164 : }
1165 :
1166 : // -----------------------------------------------------------------------------
1167 : // SpeculativeSafeIntegerAdd
1168 :
1169 15188 : TEST_F(RedundancyEliminationTest,
1170 : SpeculativeSafeIntegerAddWithCheckBoundsBetterType) {
1171 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1172 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1173 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1174 15 : Node* lhs = Parameter(Type::Any(), 0);
1175 15 : Node* rhs = Parameter(Type::Any(), 1);
1176 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1177 15 : Node* effect = graph()->start();
1178 : Node* control = graph()->start();
1179 :
1180 : Node* check1 = effect = graph()->NewNode(
1181 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1182 : Reduction r1 = Reduce(check1);
1183 15 : ASSERT_TRUE(r1.Changed());
1184 30 : EXPECT_EQ(r1.replacement(), check1);
1185 :
1186 : Node* add2 = effect =
1187 : graph()->NewNode(simplified()->SpeculativeSafeIntegerAdd(hint), lhs,
1188 15 : rhs, effect, control);
1189 : Reduction r2 = Reduce(add2);
1190 15 : ASSERT_TRUE(r2.Changed());
1191 150 : EXPECT_THAT(r2.replacement(),
1192 0 : IsSpeculativeSafeIntegerAdd(hint, check1, rhs, _, _));
1193 15 : }
1194 4 : }
1195 : }
1196 :
1197 15188 : TEST_F(RedundancyEliminationTest,
1198 : SpeculativeSafeIntegerAddWithCheckBoundsSameType) {
1199 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1200 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1201 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1202 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1203 15 : Node* rhs = Parameter(Type::Any(), 0);
1204 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1205 15 : Node* effect = graph()->start();
1206 : Node* control = graph()->start();
1207 :
1208 : Node* check1 = effect = graph()->NewNode(
1209 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1210 : Reduction r1 = Reduce(check1);
1211 15 : ASSERT_TRUE(r1.Changed());
1212 30 : EXPECT_EQ(r1.replacement(), check1);
1213 :
1214 : Node* add2 = effect =
1215 : graph()->NewNode(simplified()->SpeculativeSafeIntegerAdd(hint), lhs,
1216 15 : rhs, effect, control);
1217 : Reduction r2 = Reduce(add2);
1218 15 : ASSERT_TRUE(r2.Changed());
1219 150 : EXPECT_THAT(r2.replacement(),
1220 0 : IsSpeculativeSafeIntegerAdd(hint, lhs, rhs, _, _));
1221 15 : }
1222 4 : }
1223 : }
1224 :
1225 : // -----------------------------------------------------------------------------
1226 : // SpeculativeSafeIntegerSubtract
1227 :
1228 15188 : TEST_F(RedundancyEliminationTest,
1229 : SpeculativeSafeIntegerSubtractWithCheckBoundsBetterType) {
1230 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1231 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1232 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1233 15 : Node* lhs = Parameter(Type::Any(), 0);
1234 15 : Node* rhs = Parameter(Type::Any(), 1);
1235 15 : Node* length = Parameter(Type::Unsigned31(), 2);
1236 15 : Node* effect = graph()->start();
1237 : Node* control = graph()->start();
1238 :
1239 : Node* check1 = effect = graph()->NewNode(
1240 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1241 : Reduction r1 = Reduce(check1);
1242 15 : ASSERT_TRUE(r1.Changed());
1243 30 : EXPECT_EQ(r1.replacement(), check1);
1244 :
1245 : Node* subtract2 = effect =
1246 : graph()->NewNode(simplified()->SpeculativeSafeIntegerSubtract(hint),
1247 15 : lhs, rhs, effect, control);
1248 : Reduction r2 = Reduce(subtract2);
1249 15 : ASSERT_TRUE(r2.Changed());
1250 150 : EXPECT_THAT(r2.replacement(),
1251 0 : IsSpeculativeSafeIntegerSubtract(hint, check1, rhs, _, _));
1252 15 : }
1253 4 : }
1254 : }
1255 :
1256 15188 : TEST_F(RedundancyEliminationTest,
1257 : SpeculativeSafeIntegerSubtractWithCheckBoundsSameType) {
1258 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1259 23 : TRACED_FOREACH(VectorSlotPair, feedback, vector_slot_pairs()) {
1260 105 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1261 15 : Node* lhs = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1262 15 : Node* rhs = Parameter(Type::Any(), 0);
1263 15 : Node* length = Parameter(Type::Unsigned31(), 1);
1264 15 : Node* effect = graph()->start();
1265 : Node* control = graph()->start();
1266 :
1267 : Node* check1 = effect = graph()->NewNode(
1268 30 : simplified()->CheckBounds(feedback), lhs, length, effect, control);
1269 : Reduction r1 = Reduce(check1);
1270 15 : ASSERT_TRUE(r1.Changed());
1271 30 : EXPECT_EQ(r1.replacement(), check1);
1272 :
1273 : Node* subtract2 = effect =
1274 : graph()->NewNode(simplified()->SpeculativeSafeIntegerSubtract(hint),
1275 15 : lhs, rhs, effect, control);
1276 : Reduction r2 = Reduce(subtract2);
1277 15 : ASSERT_TRUE(r2.Changed());
1278 150 : EXPECT_THAT(r2.replacement(),
1279 0 : IsSpeculativeSafeIntegerSubtract(hint, lhs, rhs, _, _));
1280 15 : }
1281 4 : }
1282 : }
1283 :
1284 : // -----------------------------------------------------------------------------
1285 : // SpeculativeToNumber
1286 :
1287 15188 : TEST_F(RedundancyEliminationTest,
1288 : SpeculativeToNumberWithCheckBoundsBetterType) {
1289 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1290 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1291 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1292 315 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1293 45 : Node* index = Parameter(Type::Any(), 0);
1294 45 : Node* length = Parameter(Type::Unsigned31(), 1);
1295 45 : Node* effect = graph()->start();
1296 : Node* control = graph()->start();
1297 :
1298 : Node* check1 = effect =
1299 : graph()->NewNode(simplified()->CheckBounds(feedback1), index,
1300 90 : length, effect, control);
1301 : Reduction r1 = Reduce(check1);
1302 45 : ASSERT_TRUE(r1.Changed());
1303 90 : EXPECT_EQ(r1.replacement(), check1);
1304 :
1305 : Node* to_number2 = effect =
1306 : graph()->NewNode(simplified()->SpeculativeToNumber(hint, feedback2),
1307 45 : index, effect, control);
1308 : Reduction r2 = Reduce(to_number2);
1309 45 : ASSERT_TRUE(r2.Changed());
1310 225 : EXPECT_THAT(r2.replacement(), IsSpeculativeToNumber(check1));
1311 45 : }
1312 9 : }
1313 4 : }
1314 : }
1315 :
1316 15188 : TEST_F(RedundancyEliminationTest, SpeculativeToNumberWithCheckBoundsSameType) {
1317 2 : Typer typer(broker(), Typer::kNoFlags, graph());
1318 23 : TRACED_FOREACH(VectorSlotPair, feedback1, vector_slot_pairs()) {
1319 69 : TRACED_FOREACH(VectorSlotPair, feedback2, vector_slot_pairs()) {
1320 315 : TRACED_FOREACH(NumberOperationHint, hint, kNumberOperationHints) {
1321 45 : Node* index = Parameter(Type::Range(42.0, 42.0, zone()), 0);
1322 45 : Node* length = Parameter(Type::Unsigned31(), 1);
1323 45 : Node* effect = graph()->start();
1324 : Node* control = graph()->start();
1325 :
1326 : Node* check1 = effect =
1327 : graph()->NewNode(simplified()->CheckBounds(feedback1), index,
1328 90 : length, effect, control);
1329 : Reduction r1 = Reduce(check1);
1330 45 : ASSERT_TRUE(r1.Changed());
1331 90 : EXPECT_EQ(r1.replacement(), check1);
1332 :
1333 : Node* to_number2 = effect =
1334 : graph()->NewNode(simplified()->SpeculativeToNumber(hint, feedback2),
1335 45 : index, effect, control);
1336 : Reduction r2 = Reduce(to_number2);
1337 45 : ASSERT_TRUE(r2.Changed());
1338 225 : EXPECT_THAT(r2.replacement(), IsSpeculativeToNumber(index));
1339 45 : }
1340 9 : }
1341 4 : }
1342 : }
1343 :
1344 : } // namespace redundancy_elimination_unittest
1345 : } // namespace compiler
1346 : } // namespace internal
1347 9111 : } // namespace v8
|