| 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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 | 301 |
| 302 | 302 |
| 303 TEST(Int32BitwiseShifts) { | 303 TEST(Int32BitwiseShifts) { |
| 304 JSBitwiseShiftTypedLoweringTester R; | 304 JSBitwiseShiftTypedLoweringTester R; |
| 305 | 305 |
| 306 Type* types[] = { | 306 Type* types[] = { |
| 307 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), | 307 Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(), |
| 308 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), | 308 Type::Unsigned32(), Type::Signed32(), Type::MinusZero(), |
| 309 Type::NaN(), Type::OtherNumber(), Type::Undefined(), | 309 Type::NaN(), Type::OtherNumber(), Type::Undefined(), |
| 310 Type::Null(), Type::Boolean(), Type::Number(), | 310 Type::Null(), Type::Boolean(), Type::Number(), |
| 311 Type::String(), Type::Object()}; | 311 Type::String()}; |
| 312 | 312 |
| 313 for (size_t i = 0; i < arraysize(types); ++i) { | 313 for (size_t i = 0; i < arraysize(types); ++i) { |
| 314 Node* p0 = R.Parameter(types[i], 0); | 314 Node* p0 = R.Parameter(types[i], 0); |
| 315 | 315 |
| 316 for (size_t j = 0; j < arraysize(types); ++j) { | 316 for (size_t j = 0; j < arraysize(types); ++j) { |
| 317 Node* p1 = R.Parameter(types[j], 1); | 317 Node* p1 = R.Parameter(types[j], 1); |
| 318 | 318 |
| 319 for (int k = 0; k < R.kNumberOps; k += 2) { | 319 for (int k = 0; k < R.kNumberOps; k += 2) { |
| 320 Node* add = R.Binop(R.ops[k], p0, p1); | 320 Node* add = R.Binop(R.ops[k], p0, p1); |
| 321 Node* r = R.reduce(add); | 321 Node* r = R.reduce(add); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 }; | 360 }; |
| 361 | 361 |
| 362 | 362 |
| 363 TEST(Int32BitwiseBinops) { | 363 TEST(Int32BitwiseBinops) { |
| 364 JSBitwiseTypedLoweringTester R; | 364 JSBitwiseTypedLoweringTester R; |
| 365 | 365 |
| 366 Type* types[] = { | 366 Type* types[] = { |
| 367 Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(), | 367 Type::SignedSmall(), Type::UnsignedSmall(), Type::Unsigned32(), |
| 368 Type::Signed32(), Type::MinusZero(), Type::NaN(), | 368 Type::Signed32(), Type::MinusZero(), Type::NaN(), |
| 369 Type::OtherNumber(), Type::Undefined(), Type::Null(), | 369 Type::OtherNumber(), Type::Undefined(), Type::Null(), |
| 370 Type::Boolean(), Type::Number(), Type::String(), | 370 Type::Boolean(), Type::Number(), Type::String()}; |
| 371 Type::Object()}; | |
| 372 | 371 |
| 373 for (size_t i = 0; i < arraysize(types); ++i) { | 372 for (size_t i = 0; i < arraysize(types); ++i) { |
| 374 Node* p0 = R.Parameter(types[i], 0); | 373 Node* p0 = R.Parameter(types[i], 0); |
| 375 | 374 |
| 376 for (size_t j = 0; j < arraysize(types); ++j) { | 375 for (size_t j = 0; j < arraysize(types); ++j) { |
| 377 Node* p1 = R.Parameter(types[j], 1); | 376 Node* p1 = R.Parameter(types[j], 1); |
| 378 | 377 |
| 379 for (int k = 0; k < R.kNumberOps; k += 2) { | 378 for (int k = 0; k < R.kNumberOps; k += 2) { |
| 380 Node* add = R.Binop(R.ops[k], p0, p1); | 379 Node* add = R.Binop(R.ops[k], p0, p1); |
| 381 Node* r = R.reduce(add); | 380 Node* r = R.reduce(add); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 | 683 |
| 685 TEST(NumberComparison) { | 684 TEST(NumberComparison) { |
| 686 JSTypedLoweringTester R; | 685 JSTypedLoweringTester R; |
| 687 | 686 |
| 688 const Operator* ops[] = { | 687 const Operator* ops[] = { |
| 689 R.javascript.LessThan(), R.simplified.NumberLessThan(), | 688 R.javascript.LessThan(), R.simplified.NumberLessThan(), |
| 690 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), | 689 R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(), |
| 691 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), | 690 R.javascript.GreaterThan(), R.simplified.NumberLessThan(), |
| 692 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; | 691 R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()}; |
| 693 | 692 |
| 694 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 693 Node* const p0 = R.Parameter(Type::Number(), 0); |
| 695 Type* t0 = kJSTypes[i]; | 694 Node* const p1 = R.Parameter(Type::Number(), 1); |
| 696 // Skip Type::String and Type::Receiver which might coerce into a string. | |
| 697 if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue; | |
| 698 Node* p0 = R.Parameter(t0, 0); | |
| 699 | 695 |
| 700 for (size_t j = 0; j < arraysize(kJSTypes); j++) { | 696 for (size_t k = 0; k < arraysize(ops); k += 2) { |
| 701 Type* t1 = kJSTypes[j]; | 697 Node* cmp = R.Binop(ops[k], p0, p1); |
| 702 // Skip Type::String and Type::Receiver which might coerce into a string. | 698 Node* r = R.reduce(cmp); |
| 703 if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue; | |
| 704 Node* p1 = R.Parameter(t1, 1); | |
| 705 | 699 |
| 706 for (size_t k = 0; k < arraysize(ops); k += 2) { | 700 R.CheckPureBinop(ops[k + 1], r); |
| 707 Node* cmp = R.Binop(ops[k], p0, p1); | 701 if (k >= 4) { |
| 708 Node* r = R.reduce(cmp); | 702 // GreaterThan and GreaterThanOrEqual commute the inputs |
| 709 | 703 // and use the LessThan and LessThanOrEqual operators. |
| 710 R.CheckPureBinop(ops[k + 1], r); | 704 CheckIsConvertedToNumber(p1, r->InputAt(0)); |
| 711 if (k >= 4) { | 705 CheckIsConvertedToNumber(p0, r->InputAt(1)); |
| 712 // GreaterThan and GreaterThanOrEqual commute the inputs | 706 } else { |
| 713 // and use the LessThan and LessThanOrEqual operators. | 707 CheckIsConvertedToNumber(p0, r->InputAt(0)); |
| 714 CheckIsConvertedToNumber(p1, r->InputAt(0)); | 708 CheckIsConvertedToNumber(p1, r->InputAt(1)); |
| 715 CheckIsConvertedToNumber(p0, r->InputAt(1)); | |
| 716 } else { | |
| 717 CheckIsConvertedToNumber(p0, r->InputAt(0)); | |
| 718 CheckIsConvertedToNumber(p1, r->InputAt(1)); | |
| 719 } | |
| 720 } | |
| 721 } | 709 } |
| 722 } | 710 } |
| 723 } | 711 } |
| 724 | 712 |
| 725 | 713 |
| 726 TEST(MixedComparison1) { | 714 TEST(MixedComparison1) { |
| 727 JSTypedLoweringTester R; | 715 JSTypedLoweringTester R; |
| 728 | 716 |
| 729 Type* types[] = {Type::Number(), Type::String(), | 717 Type* types[] = {Type::Number(), Type::String(), |
| 730 Type::Union(Type::Number(), Type::String(), R.main_zone())}; | 718 Type::Union(Type::Number(), Type::String(), R.main_zone())}; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 747 } | 735 } |
| 748 } else { | 736 } else { |
| 749 CHECK_EQ(cmp, r); // No reduction of mixed types. | 737 CHECK_EQ(cmp, r); // No reduction of mixed types. |
| 750 } | 738 } |
| 751 } | 739 } |
| 752 } | 740 } |
| 753 } | 741 } |
| 754 } | 742 } |
| 755 | 743 |
| 756 | 744 |
| 757 TEST(ObjectComparison) { | |
| 758 JSTypedLoweringTester R; | |
| 759 | |
| 760 Node* p0 = R.Parameter(Type::Number(), 0); | |
| 761 Node* p1 = R.Parameter(Type::Object(), 1); | |
| 762 | |
| 763 Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1); | |
| 764 Node* effect_use = R.UseForEffect(cmp); | |
| 765 | |
| 766 R.CheckEffectInput(R.start(), cmp); | |
| 767 R.CheckEffectInput(cmp, effect_use); | |
| 768 | |
| 769 Node* r = R.reduce(cmp); | |
| 770 | |
| 771 R.CheckPureBinop(R.simplified.NumberLessThan(), r); | |
| 772 | |
| 773 Node* i0 = r->InputAt(0); | |
| 774 Node* i1 = r->InputAt(1); | |
| 775 | |
| 776 CHECK_EQ(p0, i0); | |
| 777 CHECK_NE(p1, i1); | |
| 778 CHECK_EQ(IrOpcode::kParameter, i0->opcode()); | |
| 779 CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode()); | |
| 780 | |
| 781 // Check effect chain is correct. | |
| 782 R.CheckEffectInput(R.start(), i1); | |
| 783 R.CheckEffectInput(i1, effect_use); | |
| 784 } | |
| 785 | |
| 786 | |
| 787 TEST(UnaryNot) { | 745 TEST(UnaryNot) { |
| 788 JSTypedLoweringTester R; | 746 JSTypedLoweringTester R; |
| 789 const Operator* opnot = R.javascript.UnaryNot(); | 747 const Operator* opnot = R.javascript.UnaryNot(); |
| 790 | 748 |
| 791 for (size_t i = 0; i < arraysize(kJSTypes); i++) { | 749 for (size_t i = 0; i < arraysize(kJSTypes); i++) { |
| 792 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); | 750 Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i])); |
| 793 Node* use = R.graph.NewNode(R.common.Return(), orig); | 751 Node* use = R.graph.NewNode(R.common.Return(), orig); |
| 794 Node* r = R.reduce(orig); | 752 Node* r = R.reduce(orig); |
| 795 // TODO(titzer): test will break if/when js-typed-lowering constant folds. | 753 // TODO(titzer): test will break if/when js-typed-lowering constant folds. |
| 796 CHECK_EQ(IrOpcode::kBooleanNot, use->InputAt(0)->opcode()); | 754 CHECK_EQ(IrOpcode::kBooleanNot, use->InputAt(0)->opcode()); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 JSTypedLoweringTester R; | 982 JSTypedLoweringTester R; |
| 1025 | 983 |
| 1026 const Operator* ops[] = { | 984 const Operator* ops[] = { |
| 1027 R.javascript.Subtract(), R.simplified.NumberSubtract(), | 985 R.javascript.Subtract(), R.simplified.NumberSubtract(), |
| 1028 R.javascript.Multiply(), R.simplified.NumberMultiply(), | 986 R.javascript.Multiply(), R.simplified.NumberMultiply(), |
| 1029 R.javascript.Divide(), R.simplified.NumberDivide(), | 987 R.javascript.Divide(), R.simplified.NumberDivide(), |
| 1030 R.javascript.Modulus(), R.simplified.NumberModulus(), | 988 R.javascript.Modulus(), R.simplified.NumberModulus(), |
| 1031 }; | 989 }; |
| 1032 | 990 |
| 1033 for (size_t j = 0; j < arraysize(ops); j += 2) { | 991 for (size_t j = 0; j < arraysize(ops); j += 2) { |
| 1034 BinopEffectsTester B(ops[j], Type::Object(), Type::String()); | 992 BinopEffectsTester B(ops[j], Type::String(), Type::String()); |
| 1035 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); | 993 CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode()); |
| 1036 | 994 |
| 1037 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); | 995 Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true); |
| 1038 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); | 996 Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true); |
| 1039 | 997 |
| 1040 CHECK_EQ(B.p0, i0->InputAt(0)); | 998 CHECK_EQ(B.p0, i0->InputAt(0)); |
| 1041 CHECK_EQ(B.p1, i1->InputAt(0)); | 999 CHECK_EQ(B.p1, i1->InputAt(0)); |
| 1042 | 1000 |
| 1043 // Effects should be ordered start -> i0 -> i1 -> effect_use | 1001 // Effects should be ordered start -> i0 -> i1 -> effect_use |
| 1044 B.CheckEffectOrdering(i0, i1); | 1002 B.CheckEffectOrdering(i0, i1); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 B.R.CheckPureBinop(B.result->opcode(), B.result); | 1118 B.R.CheckPureBinop(B.result->opcode(), B.result); |
| 1161 | 1119 |
| 1162 B.CheckConvertedInput(NumberToI32(signed_left), 0, false); | 1120 B.CheckConvertedInput(NumberToI32(signed_left), 0, false); |
| 1163 B.CheckConvertedInput(NumberToI32(signed_right), 1, false); | 1121 B.CheckConvertedInput(NumberToI32(signed_right), 1, false); |
| 1164 | 1122 |
| 1165 B.CheckEffectsRemoved(); | 1123 B.CheckEffectsRemoved(); |
| 1166 } | 1124 } |
| 1167 | 1125 |
| 1168 for (int j = 0; j < R.kNumberOps; j += 2) { | 1126 for (int j = 0; j < R.kNumberOps; j += 2) { |
| 1169 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; | 1127 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; |
| 1170 BinopEffectsTester B(R.ops[j], Type::Number(), Type::Object()); | 1128 BinopEffectsTester B(R.ops[j], Type::Number(), Type::Primitive()); |
| 1171 | 1129 |
| 1172 B.R.CheckPureBinop(B.result->opcode(), B.result); | 1130 B.R.CheckPureBinop(B.result->opcode(), B.result); |
| 1173 | 1131 |
| 1174 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); | 1132 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); |
| 1175 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); | 1133 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); |
| 1176 | 1134 |
| 1177 CHECK_EQ(B.p0, i0->InputAt(0)); | 1135 CHECK_EQ(B.p0, i0->InputAt(0)); |
| 1178 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); | 1136 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); |
| 1179 | 1137 |
| 1180 CHECK_EQ(B.p1, ii1->InputAt(0)); | 1138 CHECK_EQ(B.p1, ii1->InputAt(0)); |
| 1181 | 1139 |
| 1182 B.CheckEffectOrdering(ii1); | 1140 B.CheckEffectOrdering(ii1); |
| 1183 } | 1141 } |
| 1184 | 1142 |
| 1185 for (int j = 0; j < R.kNumberOps; j += 2) { | 1143 for (int j = 0; j < R.kNumberOps; j += 2) { |
| 1186 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; | 1144 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; |
| 1187 BinopEffectsTester B(R.ops[j], Type::Object(), Type::Number()); | 1145 BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Number()); |
| 1188 | 1146 |
| 1189 B.R.CheckPureBinop(B.result->opcode(), B.result); | 1147 B.R.CheckPureBinop(B.result->opcode(), B.result); |
| 1190 | 1148 |
| 1191 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); | 1149 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); |
| 1192 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); | 1150 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); |
| 1193 | 1151 |
| 1194 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); | 1152 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); |
| 1195 CHECK_EQ(B.p1, i1->InputAt(0)); | 1153 CHECK_EQ(B.p1, i1->InputAt(0)); |
| 1196 | 1154 |
| 1197 CHECK_EQ(B.p0, ii0->InputAt(0)); | 1155 CHECK_EQ(B.p0, ii0->InputAt(0)); |
| 1198 | 1156 |
| 1199 B.CheckEffectOrdering(ii0); | 1157 B.CheckEffectOrdering(ii0); |
| 1200 } | 1158 } |
| 1201 | 1159 |
| 1202 for (int j = 0; j < R.kNumberOps; j += 2) { | 1160 for (int j = 0; j < R.kNumberOps; j += 2) { |
| 1203 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; | 1161 bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1]; |
| 1204 BinopEffectsTester B(R.ops[j], Type::Object(), Type::Object()); | 1162 BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Primitive()); |
| 1205 | 1163 |
| 1206 B.R.CheckPureBinop(B.result->opcode(), B.result); | 1164 B.R.CheckPureBinop(B.result->opcode(), B.result); |
| 1207 | 1165 |
| 1208 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); | 1166 Node* i0 = B.CheckConvertedInput(NumberToI32(signed_left), 0, false); |
| 1209 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); | 1167 Node* i1 = B.CheckConvertedInput(NumberToI32(signed_right), 1, false); |
| 1210 | 1168 |
| 1211 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); | 1169 Node* ii0 = B.CheckConverted(IrOpcode::kJSToNumber, i0->InputAt(0), true); |
| 1212 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); | 1170 Node* ii1 = B.CheckConverted(IrOpcode::kJSToNumber, i1->InputAt(0), true); |
| 1213 | 1171 |
| 1214 CHECK_EQ(B.p0, ii0->InputAt(0)); | 1172 CHECK_EQ(B.p0, ii0->InputAt(0)); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 CHECK_EQ(p1, r->InputAt(0)); | 1335 CHECK_EQ(p1, r->InputAt(0)); |
| 1378 CHECK_EQ(p0, r->InputAt(1)); | 1336 CHECK_EQ(p0, r->InputAt(1)); |
| 1379 } else { | 1337 } else { |
| 1380 CHECK_EQ(p0, r->InputAt(0)); | 1338 CHECK_EQ(p0, r->InputAt(0)); |
| 1381 CHECK_EQ(p1, r->InputAt(1)); | 1339 CHECK_EQ(p1, r->InputAt(1)); |
| 1382 } | 1340 } |
| 1383 } | 1341 } |
| 1384 } | 1342 } |
| 1385 } | 1343 } |
| 1386 } | 1344 } |
| OLD | NEW |