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