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 |