| 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 |