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/v8.h" | 5 #include "src/v8.h" |
6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
7 | 7 |
8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 JSTypedLoweringTester R; | 677 JSTypedLoweringTester R; |
678 | 678 |
679 const Operator* ops[] = { | 679 const Operator* ops[] = { |
680 R.javascript.LessThan(), R.simplified.NumberLessThan(), | 680 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
681 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 681 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
682 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 682 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
683 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; | 683 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; |
684 | 684 |
685 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 685 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
686 Type* t0 = kJSTypes[i]; | 686 Type* t0 = kJSTypes[i]; |
687 if (t0->Is(Type::String())) continue; // skip Type::String | 687 // Skip Type::String and Type::Receiver which might coerce into a string. |
| 688 if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue; |
688 Node* p0 = R.Parameter(t0, 0); | 689 Node* p0 = R.Parameter(t0, 0); |
689 | 690 |
690 for (size_t j = 0; j < arraysize(kJSTypes); j++) { | 691 for (size_t j = 0; j < arraysize(kJSTypes); j++) { |
691 Type* t1 = kJSTypes[j]; | 692 Type* t1 = kJSTypes[j]; |
692 if (t1->Is(Type::String())) continue; // skip Type::String | 693 // Skip Type::String and Type::Receiver which might coerce into a string. |
| 694 if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue; |
693 Node* p1 = R.Parameter(t1, 1); | 695 Node* p1 = R.Parameter(t1, 1); |
694 | 696 |
695 for (size_t k = 0; k < arraysize(ops); k += 2) { | 697 for (size_t k = 0; k < arraysize(ops); k += 2) { |
696 Node* cmp = R.Binop(ops[k], p0, p1); | 698 Node* cmp = R.Binop(ops[k], p0, p1); |
697 Node* r = R.reduce(cmp); | 699 Node* r = R.reduce(cmp); |
698 | 700 |
699 R.CheckPureBinop(ops[k + 1], r); | 701 R.CheckPureBinop(ops[k + 1], r); |
700 if (k >= 4) { | 702 if (k >= 4) { |
701 // GreaterThan and GreaterThanOrEqual commute the inputs | 703 // GreaterThan and GreaterThanOrEqual commute the inputs |
702 // and use the LessThan and LessThanOrEqual operators. | 704 // and use the LessThan and LessThanOrEqual operators. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 } | 741 } |
740 } | 742 } |
741 } | 743 } |
742 } | 744 } |
743 } | 745 } |
744 | 746 |
745 | 747 |
746 TEST(ObjectComparison) { | 748 TEST(ObjectComparison) { |
747 JSTypedLoweringTester R; | 749 JSTypedLoweringTester R; |
748 | 750 |
749 Node* p0 = R.Parameter(Type::Object(), 0); | 751 Node* p0 = R.Parameter(Type::Number(), 0); |
750 Node* p1 = R.Parameter(Type::Object(), 1); | 752 Node* p1 = R.Parameter(Type::Object(), 1); |
751 | 753 |
752 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); | 754 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); |
753 Node* effect_use = R.UseForEffect(cmp); | 755 Node* effect_use = R.UseForEffect(cmp); |
754 | 756 |
755 R.CheckEffectInput(R.start(), cmp); | 757 R.CheckEffectInput(R.start(), cmp); |
756 R.CheckEffectInput(cmp, effect_use); | 758 R.CheckEffectInput(cmp, effect_use); |
757 | 759 |
758 Node* r = R.reduce(cmp); | 760 Node* r = R.reduce(cmp); |
759 | 761 |
760 R.CheckPureBinop(R.simplified.NumberLessThan(), r); | 762 R.CheckPureBinop(R.simplified.NumberLessThan(), r); |
761 | 763 |
762 Node* i0 = r->InputAt(0); | 764 Node* i0 = r->InputAt(0); |
763 Node* i1 = r->InputAt(1); | 765 Node* i1 = r->InputAt(1); |
764 | 766 |
765 CHECK_NE(p0, i0); | 767 CHECK_EQ(p0, i0); |
766 CHECK_NE(p1, i1); | 768 CHECK_NE(p1, i1); |
767 CHECK_EQ(IrOpcode::kJSToNumber, i0->opcode()); | 769 CHECK_EQ(IrOpcode::kParameter, i0->opcode()); |
768 CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode()); | 770 CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode()); |
769 | 771 |
770 // Check effect chain is correct. | 772 // Check effect chain is correct. |
771 R.CheckEffectInput(R.start(), i0); | 773 R.CheckEffectInput(R.start(), i1); |
772 R.CheckEffectInput(i0, i1); | |
773 R.CheckEffectInput(i1, effect_use); | 774 R.CheckEffectInput(i1, effect_use); |
774 } | 775 } |
775 | 776 |
776 | 777 |
777 TEST(UnaryNot) { | 778 TEST(UnaryNot) { |
778 JSTypedLoweringTester R; | 779 JSTypedLoweringTester R; |
779 const Operator* opnot = R.javascript.UnaryNot(); | 780 const Operator* opnot = R.javascript.UnaryNot(); |
780 | 781 |
781 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 782 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
782 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); | 783 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 | 1078 |
1078 TEST(OrderCompareEffects) { | 1079 TEST(OrderCompareEffects) { |
1079 JSTypedLoweringTester R; | 1080 JSTypedLoweringTester R; |
1080 | 1081 |
1081 const Operator* ops[] = { | 1082 const Operator* ops[] = { |
1082 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 1083 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
1083 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 1084 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
1084 }; | 1085 }; |
1085 | 1086 |
1086 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1087 for (size_t j = 0; j < arraysize(ops); j += 2) { |
1087 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); | 1088 BinopEffectsTester B(ops[j], Type::Boolean(), Type::String()); |
1088 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 1089 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
1089 | 1090 |
1090 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1091 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
1091 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1092 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
1092 | 1093 |
1093 // Inputs should be commuted. | 1094 // Inputs should be commuted. |
1094 CHECK_EQ(B.p1, i0->InputAt(0)); | 1095 CHECK_EQ(B.p1, i0->InputAt(0)); |
1095 CHECK_EQ(B.p0, i1->InputAt(0)); | 1096 CHECK_EQ(B.p0, i1->InputAt(0)); |
1096 | 1097 |
1097 // But effects should be ordered start -> i1 -> i0 -> effect_use | 1098 // But effects should be ordered start -> i1 -> i0 -> effect_use |
1098 B.CheckEffectOrdering(i1, i0); | 1099 B.CheckEffectOrdering(i1, i0); |
1099 } | 1100 } |
1100 | 1101 |
1101 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1102 for (size_t j = 0; j < arraysize(ops); j += 2) { |
1102 BinopEffectsTester B(ops[j], Type::Number(), Type::Object()); | 1103 BinopEffectsTester B(ops[j], Type::Number(), Type::Boolean()); |
1103 | 1104 |
1104 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 1105 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
1105 Node* i1 = B.result->InputAt(1); | 1106 Node* i1 = B.result->InputAt(1); |
1106 | 1107 |
1107 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. | 1108 CHECK_EQ(B.p1, i0->InputAt(0)); // Should be commuted. |
1108 CHECK_EQ(B.p0, i1); | 1109 CHECK_EQ(B.p0, i1); |
1109 | 1110 |
1110 // Effects should be ordered start -> i1 -> effect_use | 1111 // Effects should be ordered start -> i1 -> effect_use |
1111 B.CheckEffectOrdering(i0); | 1112 B.CheckEffectOrdering(i0); |
1112 } | 1113 } |
1113 | 1114 |
1114 for (size_t j = 0; j < arraysize(ops); j += 2) { | 1115 for (size_t j = 0; j < arraysize(ops); j += 2) { |
1115 BinopEffectsTester B(ops[j], Type::Object(), Type::Number()); | 1116 BinopEffectsTester B(ops[j], Type::Boolean(), Type::Number()); |
1116 | 1117 |
1117 Node* i0 = B.result->InputAt(0); | 1118 Node* i0 = B.result->InputAt(0); |
1118 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 1119 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
1119 | 1120 |
1120 CHECK_EQ(B.p1, i0); // Should be commuted. | 1121 CHECK_EQ(B.p1, i0); // Should be commuted. |
1121 CHECK_EQ(B.p0, i1->InputAt(0)); | 1122 CHECK_EQ(B.p0, i1->InputAt(0)); |
1122 | 1123 |
1123 // Effects should be ordered start -> i0 -> effect_use | 1124 // Effects should be ordered start -> i0 -> effect_use |
1124 B.CheckEffectOrdering(i1); | 1125 B.CheckEffectOrdering(i1); |
1125 } | 1126 } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 CHECK_EQ(p1, r->InputAt(0)); | 1368 CHECK_EQ(p1, r->InputAt(0)); |
1368 CHECK_EQ(p0, r->InputAt(1)); | 1369 CHECK_EQ(p0, r->InputAt(1)); |
1369 } else { | 1370 } else { |
1370 CHECK_EQ(p0, r->InputAt(0)); | 1371 CHECK_EQ(p0, r->InputAt(0)); |
1371 CHECK_EQ(p1, r->InputAt(1)); | 1372 CHECK_EQ(p1, r->InputAt(1)); |
1372 } | 1373 } |
1373 } | 1374 } |
1374 } | 1375 } |
1375 } | 1376 } |
1376 } | 1377 } |
OLD | NEW |