OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compilation-dependencies.h" | 5 #include "src/compilation-dependencies.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-typed-lowering.h" | 7 #include "src/compiler/js-typed-lowering.h" |
8 #include "src/compiler/machine-operator.h" | 8 #include "src/compiler/machine-operator.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
11 #include "src/compiler/operator-properties.h" | 11 #include "src/compiler/operator-properties.h" |
12 #include "src/compiler/simplified-operator.h" | 12 #include "src/compiler/simplified-operator.h" |
13 #include "src/compiler/typer.h" | 13 #include "src/compiler/typer.h" |
14 #include "test/cctest/cctest.h" | 14 #include "test/cctest/cctest.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 #ifndef TEST_WITH_STRONG | |
21 #define TEST_WITH_STRONG(Name) \ | |
22 static void Test##Name(); \ | |
23 static void TestWithStrong##Name(LanguageMode language_mode); \ | |
24 CcTest register_test_##Name(Test##Name, __FILE__, #Name, NULL, true, true); \ | |
25 static void Test##Name() { \ | |
26 TestWithStrong##Name(LanguageMode::SLOPPY); \ | |
27 TestWithStrong##Name(LanguageMode::STRONG); \ | |
28 } \ | |
29 static void TestWithStrong##Name(LanguageMode language_mode) | |
30 #endif | |
31 | |
32 | |
33 class JSTypedLoweringTester : public HandleAndZoneScope { | 20 class JSTypedLoweringTester : public HandleAndZoneScope { |
34 public: | 21 public: |
35 explicit JSTypedLoweringTester(int num_parameters = 0) | 22 explicit JSTypedLoweringTester(int num_parameters = 0) |
36 : isolate(main_isolate()), | 23 : isolate(main_isolate()), |
37 binop(NULL), | 24 binop(NULL), |
38 unop(NULL), | 25 unop(NULL), |
39 javascript(main_zone()), | 26 javascript(main_zone()), |
40 machine(main_zone()), | 27 machine(main_zone()), |
41 simplified(main_zone()), | 28 simplified(main_zone()), |
42 common(main_zone()), | 29 common(main_zone()), |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 211 } |
225 | 212 |
226 | 213 |
227 static IrOpcode::Value NumberToI32(bool is_signed) { | 214 static IrOpcode::Value NumberToI32(bool is_signed) { |
228 return is_signed ? IrOpcode::kNumberToInt32 : IrOpcode::kNumberToUint32; | 215 return is_signed ? IrOpcode::kNumberToInt32 : IrOpcode::kNumberToUint32; |
229 } | 216 } |
230 | 217 |
231 | 218 |
232 // TODO(turbofan): Lowering of StringAdd is disabled for now. | 219 // TODO(turbofan): Lowering of StringAdd is disabled for now. |
233 #if 0 | 220 #if 0 |
234 TEST_WITH_STRONG(StringBinops) { | 221 TEST(StringBinops) { |
235 JSTypedLoweringTester R; | 222 JSTypedLoweringTester R; |
236 | 223 |
237 for (size_t i = 0; i < arraysize(kStringTypes); ++i) { | 224 for (size_t i = 0; i < arraysize(kStringTypes); ++i) { |
238 Node* p0 = R.Parameter(kStringTypes[i], 0); | 225 Node* p0 = R.Parameter(kStringTypes[i], 0); |
239 | 226 |
240 for (size_t j = 0; j < arraysize(kStringTypes); ++j) { | 227 for (size_t j = 0; j < arraysize(kStringTypes); ++j) { |
241 Node* p1 = R.Parameter(kStringTypes[j], 1); | 228 Node* p1 = R.Parameter(kStringTypes[j], 1); |
242 | 229 |
243 Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1); | 230 Node* add = R.Binop(R.javascript.Add(), p0, p1); |
244 Node* r = R.reduce(add); | 231 Node* r = R.reduce(add); |
245 | 232 |
246 R.CheckBinop(IrOpcode::kStringAdd, r); | 233 R.CheckBinop(IrOpcode::kStringAdd, r); |
247 CHECK_EQ(p0, r->InputAt(0)); | 234 CHECK_EQ(p0, r->InputAt(0)); |
248 CHECK_EQ(p1, r->InputAt(1)); | 235 CHECK_EQ(p1, r->InputAt(1)); |
249 } | 236 } |
250 } | 237 } |
251 } | 238 } |
252 #endif | 239 #endif |
253 | 240 |
254 | 241 TEST(AddNumber1) { |
255 TEST_WITH_STRONG(AddNumber1) { | |
256 JSTypedLoweringTester R; | 242 JSTypedLoweringTester R; |
257 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { | 243 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
258 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 244 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
259 Node* p1 = R.Parameter(kNumberTypes[i], 1); | 245 Node* p1 = R.Parameter(kNumberTypes[i], 1); |
260 Node* add = R.Binop( | 246 Node* add = R.Binop(R.javascript.Add(BinaryOperationHints::Any()), p0, p1); |
261 R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1); | |
262 Node* r = R.reduce(add); | 247 Node* r = R.reduce(add); |
263 | 248 |
264 R.CheckBinop(IrOpcode::kNumberAdd, r); | 249 R.CheckBinop(IrOpcode::kNumberAdd, r); |
265 CHECK_EQ(p0, r->InputAt(0)); | 250 CHECK_EQ(p0, r->InputAt(0)); |
266 CHECK_EQ(p1, r->InputAt(1)); | 251 CHECK_EQ(p1, r->InputAt(1)); |
267 } | 252 } |
268 } | 253 } |
269 | 254 |
270 | 255 TEST(NumberBinops) { |
271 TEST_WITH_STRONG(NumberBinops) { | |
272 JSTypedLoweringTester R; | 256 JSTypedLoweringTester R; |
273 const Operator* ops[] = { | 257 const Operator* ops[] = { |
274 R.javascript.Add(language_mode, R.hints), | 258 R.javascript.Add(R.hints), R.simplified.NumberAdd(), |
275 R.simplified.NumberAdd(), | 259 R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(), |
276 R.javascript.Subtract(language_mode, R.hints), | 260 R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(), |
277 R.simplified.NumberSubtract(), | 261 R.javascript.Divide(R.hints), R.simplified.NumberDivide(), |
278 R.javascript.Multiply(language_mode, R.hints), | 262 R.javascript.Modulus(R.hints), R.simplified.NumberModulus(), |
279 R.simplified.NumberMultiply(), | |
280 R.javascript.Divide(language_mode, R.hints), | |
281 R.simplified.NumberDivide(), | |
282 R.javascript.Modulus(language_mode, R.hints), | |
283 R.simplified.NumberModulus(), | |
284 }; | 263 }; |
285 | 264 |
286 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { | 265 for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { |
287 Node* p0 = R.Parameter(kNumberTypes[i], 0); | 266 Node* p0 = R.Parameter(kNumberTypes[i], 0); |
288 | 267 |
289 for (size_t j = 0; j < arraysize(kNumberTypes); ++j) { | 268 for (size_t j = 0; j < arraysize(kNumberTypes); ++j) { |
290 Node* p1 = R.Parameter(kNumberTypes[j], 1); | 269 Node* p1 = R.Parameter(kNumberTypes[j], 1); |
291 | 270 |
292 for (size_t k = 0; k < arraysize(ops); k += 2) { | 271 for (size_t k = 0; k < arraysize(ops); k += 2) { |
293 Node* add = R.Binop(ops[k], p0, p1); | 272 Node* add = R.Binop(ops[k], p0, p1); |
(...skipping 19 matching lines...) Expand all Loading... |
313 double v = OpParameter<double>(new_input); | 292 double v = OpParameter<double>(new_input); |
314 double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v)); | 293 double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v)); |
315 CHECK_EQ(e, v); | 294 CHECK_EQ(e, v); |
316 } | 295 } |
317 } | 296 } |
318 | 297 |
319 | 298 |
320 // A helper class for testing lowering of bitwise shift operators. | 299 // A helper class for testing lowering of bitwise shift operators. |
321 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { | 300 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { |
322 public: | 301 public: |
323 explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode) | 302 JSBitwiseShiftTypedLoweringTester() : JSTypedLoweringTester() { |
324 : JSTypedLoweringTester(), language_mode_(language_mode) { | |
325 int i = 0; | 303 int i = 0; |
326 set(i++, javascript.ShiftLeft(language_mode_, hints), true); | 304 set(i++, javascript.ShiftLeft(hints), true); |
327 set(i++, simplified.NumberShiftLeft(), false); | 305 set(i++, simplified.NumberShiftLeft(), false); |
328 set(i++, javascript.ShiftRight(language_mode_, hints), true); | 306 set(i++, javascript.ShiftRight(hints), true); |
329 set(i++, simplified.NumberShiftRight(), false); | 307 set(i++, simplified.NumberShiftRight(), false); |
330 set(i++, javascript.ShiftRightLogical(language_mode_, hints), false); | 308 set(i++, javascript.ShiftRightLogical(hints), false); |
331 set(i++, simplified.NumberShiftRightLogical(), false); | 309 set(i++, simplified.NumberShiftRightLogical(), false); |
332 } | 310 } |
333 static const int kNumberOps = 6; | 311 static const int kNumberOps = 6; |
334 const Operator* ops[kNumberOps]; | 312 const Operator* ops[kNumberOps]; |
335 bool signedness[kNumberOps]; | 313 bool signedness[kNumberOps]; |
336 | 314 |
337 private: | 315 private: |
338 LanguageMode language_mode_; | |
339 void set(int idx, const Operator* op, bool s) { | 316 void set(int idx, const Operator* op, bool s) { |
340 ops[idx] = op; | 317 ops[idx] = op; |
341 signedness[idx] = s; | 318 signedness[idx] = s; |
342 } | 319 } |
343 }; | 320 }; |
344 | 321 |
345 | 322 |
346 TEST(Int32BitwiseShifts) { | 323 TEST(Int32BitwiseShifts) { |
347 JSBitwiseShiftTypedLoweringTester R(LanguageMode::SLOPPY); | 324 JSBitwiseShiftTypedLoweringTester R; |
348 | 325 |
349 Type* types[] = { | 326 Type* types[] = { |
350 Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(), | 327 Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(), |
351 Type::Unsigned31(), Type::Unsigned32(), Type::Signed32(), | 328 Type::Unsigned31(), Type::Unsigned32(), Type::Signed32(), |
352 Type::MinusZero(), Type::NaN(), Type::Undefined(), | 329 Type::MinusZero(), Type::NaN(), Type::Undefined(), |
353 Type::Null(), Type::Boolean(), Type::Number(), | 330 Type::Null(), Type::Boolean(), Type::Number(), |
354 Type::PlainNumber(), Type::String()}; | 331 Type::PlainNumber(), Type::String()}; |
355 | 332 |
356 for (size_t i = 0; i < arraysize(types); ++i) { | 333 for (size_t i = 0; i < arraysize(types); ++i) { |
357 Node* p0 = R.Parameter(types[i], 0); | 334 Node* p0 = R.Parameter(types[i], 0); |
(...skipping 13 matching lines...) Expand all Loading... |
371 CheckToI32(p1, r1, false); | 348 CheckToI32(p1, r1, false); |
372 } | 349 } |
373 } | 350 } |
374 } | 351 } |
375 } | 352 } |
376 | 353 |
377 | 354 |
378 // A helper class for testing lowering of bitwise operators. | 355 // A helper class for testing lowering of bitwise operators. |
379 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester { | 356 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester { |
380 public: | 357 public: |
381 explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode) | 358 JSBitwiseTypedLoweringTester() : JSTypedLoweringTester() { |
382 : JSTypedLoweringTester(), language_mode_(language_mode) { | |
383 int i = 0; | 359 int i = 0; |
384 set(i++, javascript.BitwiseOr(language_mode_, hints), true); | 360 set(i++, javascript.BitwiseOr(hints), true); |
385 set(i++, simplified.NumberBitwiseOr(), true); | 361 set(i++, simplified.NumberBitwiseOr(), true); |
386 set(i++, javascript.BitwiseXor(language_mode_, hints), true); | 362 set(i++, javascript.BitwiseXor(hints), true); |
387 set(i++, simplified.NumberBitwiseXor(), true); | 363 set(i++, simplified.NumberBitwiseXor(), true); |
388 set(i++, javascript.BitwiseAnd(language_mode_, hints), true); | 364 set(i++, javascript.BitwiseAnd(hints), true); |
389 set(i++, simplified.NumberBitwiseAnd(), true); | 365 set(i++, simplified.NumberBitwiseAnd(), true); |
390 } | 366 } |
391 static const int kNumberOps = 6; | 367 static const int kNumberOps = 6; |
392 const Operator* ops[kNumberOps]; | 368 const Operator* ops[kNumberOps]; |
393 bool signedness[kNumberOps]; | 369 bool signedness[kNumberOps]; |
394 | 370 |
395 private: | 371 private: |
396 LanguageMode language_mode_; | |
397 void set(int idx, const Operator* op, bool s) { | 372 void set(int idx, const Operator* op, bool s) { |
398 ops[idx] = op; | 373 ops[idx] = op; |
399 signedness[idx] = s; | 374 signedness[idx] = s; |
400 } | 375 } |
401 }; | 376 }; |
402 | 377 |
403 | 378 |
404 TEST(Int32BitwiseBinops) { | 379 TEST(Int32BitwiseBinops) { |
405 JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY); | 380 JSBitwiseTypedLoweringTester R; |
406 | 381 |
407 Type* types[] = { | 382 Type* types[] = { |
408 Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(), | 383 Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(), |
409 Type::Signed32(), Type::MinusZero(), Type::NaN(), | 384 Type::Signed32(), Type::MinusZero(), Type::NaN(), |
410 Type::OrderedNumber(), Type::PlainNumber(), Type::Undefined(), | 385 Type::OrderedNumber(), Type::PlainNumber(), Type::Undefined(), |
411 Type::Null(), Type::Boolean(), Type::Number(), | 386 Type::Null(), Type::Boolean(), Type::Number(), |
412 Type::String()}; | 387 Type::String()}; |
413 | 388 |
414 for (size_t i = 0; i < arraysize(types); ++i) { | 389 for (size_t i = 0; i < arraysize(types); ++i) { |
415 Node* p0 = R.Parameter(types[i], 0); | 390 Node* p0 = R.Parameter(types[i], 0); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 } else { | 560 } else { |
586 CHECK_EQ(IrOpcode::kHeapConstant, r->opcode()); | 561 CHECK_EQ(IrOpcode::kHeapConstant, r->opcode()); |
587 } | 562 } |
588 | 563 |
589 CHECK_EQ(n, add->InputAt(0)); | 564 CHECK_EQ(n, add->InputAt(0)); |
590 CHECK_EQ(r, add->InputAt(1)); | 565 CHECK_EQ(r, add->InputAt(1)); |
591 R.CheckEffectInput(R.start(), effect_use); | 566 R.CheckEffectInput(R.start(), effect_use); |
592 } | 567 } |
593 } | 568 } |
594 | 569 |
595 | 570 TEST(StringComparison) { |
596 TEST_WITH_STRONG(StringComparison) { | |
597 JSTypedLoweringTester R; | 571 JSTypedLoweringTester R; |
598 | 572 |
599 const Operator* ops[] = { | 573 const Operator* ops[] = { |
600 R.javascript.LessThan(language_mode), R.simplified.StringLessThan(), | 574 R.javascript.LessThan(), R.simplified.StringLessThan(), |
601 R.javascript.LessThanOrEqual(language_mode), | 575 R.javascript.LessThanOrEqual(), R.simplified.StringLessThanOrEqual(), |
602 R.simplified.StringLessThanOrEqual(), | 576 R.javascript.GreaterThan(), R.simplified.StringLessThan(), |
603 R.javascript.GreaterThan(language_mode), R.simplified.StringLessThan(), | 577 R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()}; |
604 R.javascript.GreaterThanOrEqual(language_mode), | |
605 R.simplified.StringLessThanOrEqual()}; | |
606 | 578 |
607 for (size_t i = 0; i < arraysize(kStringTypes); i++) { | 579 for (size_t i = 0; i < arraysize(kStringTypes); i++) { |
608 Node* p0 = R.Parameter(kStringTypes[i], 0); | 580 Node* p0 = R.Parameter(kStringTypes[i], 0); |
609 for (size_t j = 0; j < arraysize(kStringTypes); j++) { | 581 for (size_t j = 0; j < arraysize(kStringTypes); j++) { |
610 Node* p1 = R.Parameter(kStringTypes[j], 1); | 582 Node* p1 = R.Parameter(kStringTypes[j], 1); |
611 | 583 |
612 for (size_t k = 0; k < arraysize(ops); k += 2) { | 584 for (size_t k = 0; k < arraysize(ops); k += 2) { |
613 Node* cmp = R.Binop(ops[k], p0, p1); | 585 Node* cmp = R.Binop(ops[k], p0, p1); |
614 Node* r = R.reduce(cmp); | 586 Node* r = R.reduce(cmp); |
615 | 587 |
(...skipping 19 matching lines...) Expand all Loading... |
635 } else if (NodeProperties::GetType(val)->Is(Type::Boolean())) { | 607 } else if (NodeProperties::GetType(val)->Is(Type::Boolean())) { |
636 CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode()); | 608 CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode()); |
637 CHECK_EQ(val, converted->InputAt(0)); | 609 CHECK_EQ(val, converted->InputAt(0)); |
638 } else { | 610 } else { |
639 if (converted->opcode() == IrOpcode::kNumberConstant) return; | 611 if (converted->opcode() == IrOpcode::kNumberConstant) return; |
640 CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode()); | 612 CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode()); |
641 CHECK_EQ(val, converted->InputAt(0)); | 613 CHECK_EQ(val, converted->InputAt(0)); |
642 } | 614 } |
643 } | 615 } |
644 | 616 |
645 | 617 TEST(NumberComparison) { |
646 TEST_WITH_STRONG(NumberComparison) { | |
647 JSTypedLoweringTester R; | 618 JSTypedLoweringTester R; |
648 | 619 |
649 const Operator* ops[] = { | 620 const Operator* ops[] = { |
650 R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(), | 621 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
651 R.javascript.LessThanOrEqual(language_mode), | 622 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
652 R.simplified.NumberLessThanOrEqual(), | 623 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
653 R.javascript.GreaterThan(language_mode), R.simplified.NumberLessThan(), | 624 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; |
654 R.javascript.GreaterThanOrEqual(language_mode), | |
655 R.simplified.NumberLessThanOrEqual()}; | |
656 | 625 |
657 Node* const p0 = R.Parameter(Type::Number(), 0); | 626 Node* const p0 = R.Parameter(Type::Number(), 0); |
658 Node* const p1 = R.Parameter(Type::Number(), 1); | 627 Node* const p1 = R.Parameter(Type::Number(), 1); |
659 | 628 |
660 for (size_t k = 0; k < arraysize(ops); k += 2) { | 629 for (size_t k = 0; k < arraysize(ops); k += 2) { |
661 Node* cmp = R.Binop(ops[k], p0, p1); | 630 Node* cmp = R.Binop(ops[k], p0, p1); |
662 Node* r = R.reduce(cmp); | 631 Node* r = R.reduce(cmp); |
663 | 632 |
664 R.CheckBinop(ops[k + 1], r); | 633 R.CheckBinop(ops[k + 1], r); |
665 if (k >= 4) { | 634 if (k >= 4) { |
666 // GreaterThan and GreaterThanOrEqual commute the inputs | 635 // GreaterThan and GreaterThanOrEqual commute the inputs |
667 // and use the LessThan and LessThanOrEqual operators. | 636 // and use the LessThan and LessThanOrEqual operators. |
668 CheckIsConvertedToNumber(p1, r->InputAt(0)); | 637 CheckIsConvertedToNumber(p1, r->InputAt(0)); |
669 CheckIsConvertedToNumber(p0, r->InputAt(1)); | 638 CheckIsConvertedToNumber(p0, r->InputAt(1)); |
670 } else { | 639 } else { |
671 CheckIsConvertedToNumber(p0, r->InputAt(0)); | 640 CheckIsConvertedToNumber(p0, r->InputAt(0)); |
672 CheckIsConvertedToNumber(p1, r->InputAt(1)); | 641 CheckIsConvertedToNumber(p1, r->InputAt(1)); |
673 } | 642 } |
674 } | 643 } |
675 } | 644 } |
676 | 645 |
677 | 646 TEST(MixedComparison1) { |
678 TEST_WITH_STRONG(MixedComparison1) { | |
679 JSTypedLoweringTester R; | 647 JSTypedLoweringTester R; |
680 | 648 |
681 Type* types[] = {Type::Number(), Type::String(), | 649 Type* types[] = {Type::Number(), Type::String(), |
682 Type::Union(Type::Number(), Type::String(), R.main_zone())}; | 650 Type::Union(Type::Number(), Type::String(), R.main_zone())}; |
683 | 651 |
684 for (size_t i = 0; i < arraysize(types); i++) { | 652 for (size_t i = 0; i < arraysize(types); i++) { |
685 Node* p0 = R.Parameter(types[i], 0); | 653 Node* p0 = R.Parameter(types[i], 0); |
686 | 654 |
687 for (size_t j = 0; j < arraysize(types); j++) { | 655 for (size_t j = 0; j < arraysize(types); j++) { |
688 Node* p1 = R.Parameter(types[j], 1); | 656 Node* p1 = R.Parameter(types[j], 1); |
689 { | 657 { |
690 const Operator* less_than = R.javascript.LessThan(language_mode); | 658 const Operator* less_than = R.javascript.LessThan(); |
691 Node* cmp = R.Binop(less_than, p0, p1); | 659 Node* cmp = R.Binop(less_than, p0, p1); |
692 Node* r = R.reduce(cmp); | 660 Node* r = R.reduce(cmp); |
693 if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { | 661 if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) { |
694 R.CheckBinop(R.simplified.StringLessThan(), r); | 662 R.CheckBinop(R.simplified.StringLessThan(), r); |
695 } else if ((types[i]->Is(Type::Number()) && | 663 } else if ((types[i]->Is(Type::Number()) && |
696 types[j]->Is(Type::Number())) || | 664 types[j]->Is(Type::Number())) || |
697 (!is_strong(language_mode) && | 665 (!types[i]->Maybe(Type::String()) || |
698 (!types[i]->Maybe(Type::String()) || | 666 !types[j]->Maybe(Type::String()))) { |
699 !types[j]->Maybe(Type::String())))) { | |
700 R.CheckBinop(R.simplified.NumberLessThan(), r); | 667 R.CheckBinop(R.simplified.NumberLessThan(), r); |
701 } else { | 668 } else { |
702 // No reduction of mixed types. | 669 // No reduction of mixed types. |
703 CHECK_EQ(r->op(), less_than); | 670 CHECK_EQ(r->op(), less_than); |
704 } | 671 } |
705 } | 672 } |
706 } | 673 } |
707 } | 674 } |
708 } | 675 } |
709 | 676 |
710 | 677 TEST(RemoveToNumberEffects) { |
711 TEST_WITH_STRONG(RemoveToNumberEffects) { | |
712 JSTypedLoweringTester R; | 678 JSTypedLoweringTester R; |
713 | 679 |
714 Node* effect_use = NULL; | 680 Node* effect_use = NULL; |
715 for (int i = 0; i < 10; i++) { | 681 for (int i = 0; i < 10; i++) { |
716 Node* p0 = R.Parameter(Type::Number()); | 682 Node* p0 = R.Parameter(Type::Number()); |
717 Node* ton = R.Unop(R.javascript.ToNumber(), p0); | 683 Node* ton = R.Unop(R.javascript.ToNumber(), p0); |
718 Node* frame_state = R.EmptyFrameState(R.context()); | 684 Node* frame_state = R.EmptyFrameState(R.context()); |
719 effect_use = NULL; | 685 effect_use = NULL; |
720 | 686 |
721 switch (i) { | 687 switch (i) { |
722 case 0: | 688 case 0: |
723 CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( | 689 CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( |
724 R.javascript.ToNumber())); | 690 R.javascript.ToNumber())); |
725 effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(), | 691 effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(), |
726 frame_state, ton, R.start()); | 692 frame_state, ton, R.start()); |
727 break; | 693 break; |
728 case 1: | 694 case 1: |
729 CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( | 695 CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( |
730 R.javascript.ToNumber())); | 696 R.javascript.ToNumber())); |
731 effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(), | 697 effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(), |
732 frame_state, ton, R.start()); | 698 frame_state, ton, R.start()); |
733 break; | 699 break; |
734 case 2: | 700 case 2: |
735 effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start()); | 701 effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start()); |
736 case 3: | 702 case 3: |
737 effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), | 703 effect_use = |
738 ton, ton, R.context(), frame_state, | 704 R.graph.NewNode(R.javascript.Add(R.hints), ton, ton, R.context(), |
739 frame_state, ton, R.start()); | 705 frame_state, frame_state, ton, R.start()); |
740 break; | 706 break; |
741 case 4: | 707 case 4: |
742 effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), | 708 effect_use = |
743 p0, p0, R.context(), frame_state, | 709 R.graph.NewNode(R.javascript.Add(R.hints), p0, p0, R.context(), |
744 frame_state, ton, R.start()); | 710 frame_state, frame_state, ton, R.start()); |
745 break; | 711 break; |
746 case 5: | 712 case 5: |
747 effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start()); | 713 effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start()); |
748 break; | 714 break; |
749 case 6: | 715 case 6: |
750 effect_use = R.graph.NewNode(R.common.Return(), ton, ton, R.start()); | 716 effect_use = R.graph.NewNode(R.common.Return(), ton, ton, R.start()); |
751 } | 717 } |
752 | 718 |
753 R.CheckEffectInput(R.start(), ton); | 719 R.CheckEffectInput(R.start(), ton); |
754 if (effect_use != NULL) R.CheckEffectInput(ton, effect_use); | 720 if (effect_use != NULL) R.CheckEffectInput(ton, effect_use); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 | 865 |
900 TEST(StringEquality) { | 866 TEST(StringEquality) { |
901 JSTypedLoweringTester R; | 867 JSTypedLoweringTester R; |
902 Node* p0 = R.Parameter(Type::String()); | 868 Node* p0 = R.Parameter(Type::String()); |
903 Node* p1 = R.Parameter(Type::String()); | 869 Node* p1 = R.Parameter(Type::String()); |
904 | 870 |
905 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kStringEqual); | 871 CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kStringEqual); |
906 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual); | 872 CheckEqualityReduction(&R, false, p0, p1, IrOpcode::kStringEqual); |
907 } | 873 } |
908 | 874 |
909 | 875 TEST(RemovePureNumberBinopEffects) { |
910 TEST_WITH_STRONG(RemovePureNumberBinopEffects) { | |
911 JSTypedLoweringTester R; | 876 JSTypedLoweringTester R; |
912 | 877 |
913 const Operator* ops[] = { | 878 const Operator* ops[] = { |
914 R.javascript.Equal(), | 879 R.javascript.Equal(), R.simplified.NumberEqual(), |
915 R.simplified.NumberEqual(), | 880 R.javascript.Add(R.hints), R.simplified.NumberAdd(), |
916 R.javascript.Add(language_mode, R.hints), | 881 R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(), |
917 R.simplified.NumberAdd(), | 882 R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(), |
918 R.javascript.Subtract(language_mode, R.hints), | 883 R.javascript.Divide(R.hints), R.simplified.NumberDivide(), |
919 R.simplified.NumberSubtract(), | 884 R.javascript.Modulus(R.hints), R.simplified.NumberModulus(), |
920 R.javascript.Multiply(language_mode, R.hints), | 885 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
921 R.simplified.NumberMultiply(), | 886 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
922 R.javascript.Divide(language_mode, R.hints), | |
923 R.simplified.NumberDivide(), | |
924 R.javascript.Modulus(language_mode, R.hints), | |
925 R.simplified.NumberModulus(), | |
926 R.javascript.LessThan(language_mode), | |
927 R.simplified.NumberLessThan(), | |
928 R.javascript.LessThanOrEqual(language_mode), | |
929 R.simplified.NumberLessThanOrEqual(), | |
930 }; | 887 }; |
931 | 888 |
932 for (size_t j = 0; j < arraysize(ops); j += 2) { | 889 for (size_t j = 0; j < arraysize(ops); j += 2) { |
933 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); | 890 BinopEffectsTester B(ops[j], Type::Number(), Type::Number()); |
934 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 891 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
935 | 892 |
936 B.R.CheckBinop(B.result->opcode(), B.result); | 893 B.R.CheckBinop(B.result->opcode(), B.result); |
937 | 894 |
938 B.CheckNoOp(0); | 895 B.CheckNoOp(0); |
939 B.CheckNoOp(1); | 896 B.CheckNoOp(1); |
940 | 897 |
941 B.CheckEffectsRemoved(); | 898 B.CheckEffectsRemoved(); |
942 } | 899 } |
943 } | 900 } |
944 | 901 |
945 | 902 |
946 TEST(OrderNumberBinopEffects1) { | 903 TEST(OrderNumberBinopEffects1) { |
947 JSTypedLoweringTester R; | 904 JSTypedLoweringTester R; |
948 | 905 |
949 const Operator* ops[] = { | 906 const Operator* ops[] = { |
950 R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), | 907 R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(), |
951 R.simplified.NumberSubtract(), | 908 R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(), |
952 R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), | 909 R.javascript.Divide(R.hints), R.simplified.NumberDivide(), |
953 R.simplified.NumberMultiply(), | |
954 R.javascript.Divide(LanguageMode::SLOPPY, R.hints), | |
955 R.simplified.NumberDivide(), | |
956 }; | 910 }; |
957 | 911 |
958 for (size_t j = 0; j < arraysize(ops); j += 2) { | 912 for (size_t j = 0; j < arraysize(ops); j += 2) { |
959 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol()); | 913 BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol()); |
960 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 914 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
961 | 915 |
962 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 916 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
963 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 917 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
964 | 918 |
965 CHECK_EQ(B.p0, i0->InputAt(0)); | 919 CHECK_EQ(B.p0, i0->InputAt(0)); |
966 CHECK_EQ(B.p1, i1->InputAt(0)); | 920 CHECK_EQ(B.p1, i1->InputAt(0)); |
967 | 921 |
968 // Effects should be ordered start -> i0 -> i1 -> effect_use | 922 // Effects should be ordered start -> i0 -> i1 -> effect_use |
969 B.CheckEffectOrdering(i0, i1); | 923 B.CheckEffectOrdering(i0, i1); |
970 } | 924 } |
971 } | 925 } |
972 | 926 |
973 | 927 |
974 TEST(OrderNumberBinopEffects2) { | 928 TEST(OrderNumberBinopEffects2) { |
975 JSTypedLoweringTester R; | 929 JSTypedLoweringTester R; |
976 | 930 |
977 const Operator* ops[] = { | 931 const Operator* ops[] = { |
978 R.javascript.Add(LanguageMode::SLOPPY, R.hints), | 932 R.javascript.Add(R.hints), R.simplified.NumberAdd(), |
979 R.simplified.NumberAdd(), | 933 R.javascript.Subtract(R.hints), R.simplified.NumberSubtract(), |
980 R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), | 934 R.javascript.Multiply(R.hints), R.simplified.NumberMultiply(), |
981 R.simplified.NumberSubtract(), | 935 R.javascript.Divide(R.hints), R.simplified.NumberDivide(), |
982 R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), | |
983 R.simplified.NumberMultiply(), | |
984 R.javascript.Divide(LanguageMode::SLOPPY, R.hints), | |
985 R.simplified.NumberDivide(), | |
986 }; | 936 }; |
987 | 937 |
988 for (size_t j = 0; j < arraysize(ops); j += 2) { | 938 for (size_t j = 0; j < arraysize(ops); j += 2) { |
989 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol()); | 939 BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol()); |
990 | 940 |
991 Node* i0 = B.CheckNoOp(0); | 941 Node* i0 = B.CheckNoOp(0); |
992 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 942 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
993 | 943 |
994 CHECK_EQ(B.p0, i0); | 944 CHECK_EQ(B.p0, i0); |
995 CHECK_EQ(B.p1, i1->InputAt(0)); | 945 CHECK_EQ(B.p1, i1->InputAt(0)); |
(...skipping 14 matching lines...) Expand all Loading... |
1010 // Effects should be ordered start -> i0 -> effect_use | 960 // Effects should be ordered start -> i0 -> effect_use |
1011 B.CheckEffectOrdering(i0); | 961 B.CheckEffectOrdering(i0); |
1012 } | 962 } |
1013 } | 963 } |
1014 | 964 |
1015 | 965 |
1016 TEST(OrderCompareEffects) { | 966 TEST(OrderCompareEffects) { |
1017 JSTypedLoweringTester R; | 967 JSTypedLoweringTester R; |
1018 | 968 |
1019 const Operator* ops[] = { | 969 const Operator* ops[] = { |
1020 R.javascript.GreaterThan(LanguageMode::SLOPPY), | 970 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
1021 R.simplified.NumberLessThan(), | 971 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
1022 R.javascript.GreaterThanOrEqual(LanguageMode::SLOPPY), | |
1023 R.simplified.NumberLessThanOrEqual(), | |
1024 }; | 972 }; |
1025 | 973 |
1026 for (size_t j = 0; j < arraysize(ops); j += 2) { | 974 for (size_t j = 0; j < arraysize(ops); j += 2) { |
1027 BinopEffectsTester B(ops[j], Type::Symbol(), Type::String()); | 975 BinopEffectsTester B(ops[j], Type::Symbol(), Type::String()); |
1028 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 976 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
1029 | 977 |
1030 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 978 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
1031 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 979 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
1032 | 980 |
1033 // Inputs should be commuted. | 981 // Inputs should be commuted. |
(...skipping 26 matching lines...) Expand all Loading... |
1060 CHECK_EQ(B.p1, i0); // Should be commuted. | 1008 CHECK_EQ(B.p1, i0); // Should be commuted. |
1061 CHECK_EQ(B.p0, i1->InputAt(0)); | 1009 CHECK_EQ(B.p0, i1->InputAt(0)); |
1062 | 1010 |
1063 // Effects should be ordered start -> i0 -> effect_use | 1011 // Effects should be ordered start -> i0 -> effect_use |
1064 B.CheckEffectOrdering(i1); | 1012 B.CheckEffectOrdering(i1); |
1065 } | 1013 } |
1066 } | 1014 } |
1067 | 1015 |
1068 | 1016 |
1069 TEST(Int32BinopEffects) { | 1017 TEST(Int32BinopEffects) { |
1070 JSBitwiseTypedLoweringTester R(LanguageMode::SLOPPY); | 1018 JSBitwiseTypedLoweringTester R; |
1071 for (int j = 0; j < R.kNumberOps; j += 2) { | 1019 for (int j = 0; j < R.kNumberOps; j += 2) { |
1072 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; | 1020 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; |
1073 BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right)); | 1021 BinopEffectsTester B(R.ops[j], I32Type(signed_left), I32Type(signed_right)); |
1074 CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode()); | 1022 CHECK_EQ(R.ops[j + 1]->opcode(), B.result->op()->opcode()); |
1075 | 1023 |
1076 B.R.CheckBinop(B.result->opcode(), B.result); | 1024 B.R.CheckBinop(B.result->opcode(), B.result); |
1077 | 1025 |
1078 B.CheckNoOp(0); | 1026 B.CheckNoOp(0); |
1079 B.CheckNoOp(1); | 1027 B.CheckNoOp(1); |
1080 | 1028 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); | 1088 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); |
1141 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); | 1089 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); |
1142 | 1090 |
1143 CHECK_EQ(B.p0, ii0->InputAt(0)); | 1091 CHECK_EQ(B.p0, ii0->InputAt(0)); |
1144 CHECK_EQ(B.p1, ii1->InputAt(0)); | 1092 CHECK_EQ(B.p1, ii1->InputAt(0)); |
1145 | 1093 |
1146 B.CheckEffectOrdering(ii0, ii1); | 1094 B.CheckEffectOrdering(ii0, ii1); |
1147 } | 1095 } |
1148 } | 1096 } |
1149 | 1097 |
1150 | 1098 TEST(Int32AddNarrowing) { |
1151 TEST_WITH_STRONG(Int32AddNarrowing) { | |
1152 { | 1099 { |
1153 JSBitwiseTypedLoweringTester R(language_mode); | 1100 JSBitwiseTypedLoweringTester R; |
1154 | 1101 |
1155 for (int o = 0; o < R.kNumberOps; o += 2) { | 1102 for (int o = 0; o < R.kNumberOps; o += 2) { |
1156 for (size_t i = 0; i < arraysize(kInt32Types); i++) { | 1103 for (size_t i = 0; i < arraysize(kInt32Types); i++) { |
1157 Node* n0 = R.Parameter(kInt32Types[i]); | 1104 Node* n0 = R.Parameter(kInt32Types[i]); |
1158 for (size_t j = 0; j < arraysize(kInt32Types); j++) { | 1105 for (size_t j = 0; j < arraysize(kInt32Types); j++) { |
1159 Node* n1 = R.Parameter(kInt32Types[j]); | 1106 Node* n1 = R.Parameter(kInt32Types[j]); |
1160 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); | 1107 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); |
1161 | 1108 |
1162 for (int l = 0; l < 2; l++) { | 1109 for (int l = 0; l < 2; l++) { |
1163 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); | 1110 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); |
1164 Node* or_node = | 1111 Node* or_node = |
1165 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); | 1112 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); |
1166 Node* r = R.reduce(or_node); | 1113 Node* r = R.reduce(or_node); |
1167 | 1114 |
1168 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); | 1115 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); |
1169 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); | 1116 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); |
1170 } | 1117 } |
1171 } | 1118 } |
1172 } | 1119 } |
1173 } | 1120 } |
1174 } | 1121 } |
1175 { | 1122 { |
1176 JSBitwiseShiftTypedLoweringTester R(language_mode); | 1123 JSBitwiseShiftTypedLoweringTester R; |
1177 | 1124 |
1178 for (int o = 0; o < R.kNumberOps; o += 2) { | 1125 for (int o = 0; o < R.kNumberOps; o += 2) { |
1179 for (size_t i = 0; i < arraysize(kInt32Types); i++) { | 1126 for (size_t i = 0; i < arraysize(kInt32Types); i++) { |
1180 Node* n0 = R.Parameter(kInt32Types[i]); | 1127 Node* n0 = R.Parameter(kInt32Types[i]); |
1181 for (size_t j = 0; j < arraysize(kInt32Types); j++) { | 1128 for (size_t j = 0; j < arraysize(kInt32Types); j++) { |
1182 Node* n1 = R.Parameter(kInt32Types[j]); | 1129 Node* n1 = R.Parameter(kInt32Types[j]); |
1183 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); | 1130 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); |
1184 | 1131 |
1185 for (int l = 0; l < 2; l++) { | 1132 for (int l = 0; l < 2; l++) { |
1186 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); | 1133 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); |
1187 Node* or_node = | 1134 Node* or_node = |
1188 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); | 1135 R.Binop(R.ops[o], l ? add_node : one, l ? one : add_node); |
1189 Node* r = R.reduce(or_node); | 1136 Node* r = R.reduce(or_node); |
1190 | 1137 |
1191 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); | 1138 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); |
1192 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); | 1139 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); |
1193 } | 1140 } |
1194 } | 1141 } |
1195 } | 1142 } |
1196 } | 1143 } |
1197 } | 1144 } |
1198 { | 1145 { |
1199 JSBitwiseTypedLoweringTester R(language_mode); | 1146 JSBitwiseTypedLoweringTester R; |
1200 | 1147 |
1201 for (int o = 0; o < R.kNumberOps; o += 2) { | 1148 for (int o = 0; o < R.kNumberOps; o += 2) { |
1202 Node* n0 = R.Parameter(I32Type(R.signedness[o])); | 1149 Node* n0 = R.Parameter(I32Type(R.signedness[o])); |
1203 Node* n1 = R.Parameter(I32Type(R.signedness[o + 1])); | 1150 Node* n1 = R.Parameter(I32Type(R.signedness[o + 1])); |
1204 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); | 1151 Node* one = R.graph.NewNode(R.common.NumberConstant(1)); |
1205 | 1152 |
1206 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); | 1153 Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1); |
1207 Node* or_node = R.Binop(R.ops[o], add_node, one); | 1154 Node* or_node = R.Binop(R.ops[o], add_node, one); |
1208 Node* other_use = R.Binop(R.simplified.NumberAdd(), add_node, one); | 1155 Node* other_use = R.Binop(R.simplified.NumberAdd(), add_node, one); |
1209 Node* r = R.reduce(or_node); | 1156 Node* r = R.reduce(or_node); |
1210 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); | 1157 CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode()); |
1211 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); | 1158 CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode()); |
1212 // Conversion to int32 should be done. | 1159 // Conversion to int32 should be done. |
1213 CheckToI32(add_node, r->InputAt(0), R.signedness[o]); | 1160 CheckToI32(add_node, r->InputAt(0), R.signedness[o]); |
1214 CheckToI32(one, r->InputAt(1), R.signedness[o + 1]); | 1161 CheckToI32(one, r->InputAt(1), R.signedness[o + 1]); |
1215 // The other use should also not be touched. | 1162 // The other use should also not be touched. |
1216 CHECK_EQ(add_node, other_use->InputAt(0)); | 1163 CHECK_EQ(add_node, other_use->InputAt(0)); |
1217 CHECK_EQ(one, other_use->InputAt(1)); | 1164 CHECK_EQ(one, other_use->InputAt(1)); |
1218 } | 1165 } |
1219 } | 1166 } |
1220 } | 1167 } |
1221 | 1168 |
1222 | 1169 TEST(Int32Comparisons) { |
1223 TEST_WITH_STRONG(Int32Comparisons) { | |
1224 JSTypedLoweringTester R; | 1170 JSTypedLoweringTester R; |
1225 | 1171 |
1226 struct Entry { | 1172 struct Entry { |
1227 const Operator* js_op; | 1173 const Operator* js_op; |
1228 const Operator* uint_op; | 1174 const Operator* uint_op; |
1229 const Operator* int_op; | 1175 const Operator* int_op; |
1230 const Operator* num_op; | 1176 const Operator* num_op; |
1231 bool commute; | 1177 bool commute; |
1232 }; | 1178 }; |
1233 | 1179 |
1234 Entry ops[] = { | 1180 Entry ops[] = { |
1235 {R.javascript.LessThan(language_mode), R.machine.Uint32LessThan(), | 1181 {R.javascript.LessThan(), R.machine.Uint32LessThan(), |
1236 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false}, | 1182 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), false}, |
1237 {R.javascript.LessThanOrEqual(language_mode), | 1183 {R.javascript.LessThanOrEqual(), R.machine.Uint32LessThanOrEqual(), |
1238 R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(), | 1184 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
1239 R.simplified.NumberLessThanOrEqual(), false}, | 1185 false}, |
1240 {R.javascript.GreaterThan(language_mode), R.machine.Uint32LessThan(), | 1186 {R.javascript.GreaterThan(), R.machine.Uint32LessThan(), |
1241 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true}, | 1187 R.machine.Int32LessThan(), R.simplified.NumberLessThan(), true}, |
1242 {R.javascript.GreaterThanOrEqual(language_mode), | 1188 {R.javascript.GreaterThanOrEqual(), R.machine.Uint32LessThanOrEqual(), |
1243 R.machine.Uint32LessThanOrEqual(), R.machine.Int32LessThanOrEqual(), | 1189 R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
1244 R.simplified.NumberLessThanOrEqual(), true} | 1190 true}}; |
1245 }; | |
1246 | 1191 |
1247 for (size_t o = 0; o < arraysize(ops); o++) { | 1192 for (size_t o = 0; o < arraysize(ops); o++) { |
1248 for (size_t i = 0; i < arraysize(kNumberTypes); i++) { | 1193 for (size_t i = 0; i < arraysize(kNumberTypes); i++) { |
1249 Type* t0 = kNumberTypes[i]; | 1194 Type* t0 = kNumberTypes[i]; |
1250 Node* p0 = R.Parameter(t0, 0); | 1195 Node* p0 = R.Parameter(t0, 0); |
1251 | 1196 |
1252 for (size_t j = 0; j < arraysize(kNumberTypes); j++) { | 1197 for (size_t j = 0; j < arraysize(kNumberTypes); j++) { |
1253 Type* t1 = kNumberTypes[j]; | 1198 Type* t1 = kNumberTypes[j]; |
1254 Node* p1 = R.Parameter(t1, 1); | 1199 Node* p1 = R.Parameter(t1, 1); |
1255 | 1200 |
(...skipping 17 matching lines...) Expand all Loading... |
1273 CHECK_EQ(p1, r->InputAt(1)); | 1218 CHECK_EQ(p1, r->InputAt(1)); |
1274 } | 1219 } |
1275 } | 1220 } |
1276 } | 1221 } |
1277 } | 1222 } |
1278 } | 1223 } |
1279 | 1224 |
1280 } // namespace compiler | 1225 } // namespace compiler |
1281 } // namespace internal | 1226 } // namespace internal |
1282 } // namespace v8 | 1227 } // namespace v8 |
OLD | NEW |