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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/compiler/control-builders.h" | 7 #include "src/compiler/control-builders.h" |
8 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 89 |
90 ElementAccess ForBackingStoreElement(MachineType rep) { | 90 ElementAccess ForBackingStoreElement(MachineType rep) { |
91 ElementAccess access = {kUntaggedBase, | 91 ElementAccess access = {kUntaggedBase, |
92 kNonHeapObjectHeaderSize - kHeapObjectTag, | 92 kNonHeapObjectHeaderSize - kHeapObjectTag, |
93 Type::Any(), rep}; | 93 Type::Any(), rep}; |
94 return access; | 94 return access; |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 | 98 |
| 99 #ifndef V8_TARGET_ARCH_ARM64 |
| 100 // TODO(titzer): these result in a stub call that doesn't work on ARM64. |
| 101 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. |
| 102 // TODO(titzer): test tagged representation for input to NumberToInt32. |
| 103 TEST(RunNumberToInt32_float64) { |
| 104 // TODO(titzer): explicit load/stores here are only because of representations |
| 105 double input; |
| 106 int32_t result; |
| 107 SimplifiedLoweringTester<Object*> t; |
| 108 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
| 109 kMachFloat64}; |
| 110 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
| 111 Node* convert = t.NumberToInt32(loaded); |
| 112 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), |
| 113 kMachInt32}; |
| 114 t.StoreField(store, t.PointerConstant(&result), convert); |
| 115 t.Return(t.jsgraph.TrueConstant()); |
| 116 t.LowerAllNodes(); |
| 117 t.GenerateCode(); |
| 118 |
| 119 if (Pipeline::SupportedTarget()) { |
| 120 FOR_FLOAT64_INPUTS(i) { |
| 121 input = *i; |
| 122 int32_t expected = DoubleToInt32(*i); |
| 123 t.Call(); |
| 124 CHECK_EQ(expected, result); |
| 125 } |
| 126 } |
| 127 } |
| 128 |
| 129 |
| 130 // TODO(titzer): test tagged representation for input to NumberToUint32. |
| 131 TEST(RunNumberToUint32_float64) { |
| 132 // TODO(titzer): explicit load/stores here are only because of representations |
| 133 double input; |
| 134 uint32_t result; |
| 135 SimplifiedLoweringTester<Object*> t; |
| 136 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), |
| 137 kMachFloat64}; |
| 138 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
| 139 Node* convert = t.NumberToUint32(loaded); |
| 140 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), |
| 141 kMachUint32}; |
| 142 t.StoreField(store, t.PointerConstant(&result), convert); |
| 143 t.Return(t.jsgraph.TrueConstant()); |
| 144 t.LowerAllNodes(); |
| 145 t.GenerateCode(); |
| 146 |
| 147 if (Pipeline::SupportedTarget()) { |
| 148 FOR_FLOAT64_INPUTS(i) { |
| 149 input = *i; |
| 150 uint32_t expected = DoubleToUint32(*i); |
| 151 t.Call(); |
| 152 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); |
| 153 } |
| 154 } |
| 155 } |
| 156 #endif |
| 157 |
| 158 |
99 // Create a simple JSObject with a unique map. | 159 // Create a simple JSObject with a unique map. |
100 static Handle<JSObject> TestObject() { | 160 static Handle<JSObject> TestObject() { |
101 static int index = 0; | 161 static int index = 0; |
102 char buffer[50]; | 162 char buffer[50]; |
103 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); | 163 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); |
104 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); | 164 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); |
105 } | 165 } |
106 | 166 |
107 | 167 |
108 TEST(RunLoadMap) { | 168 TEST(RunLoadMap) { |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepWord32 | 962 // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepWord32 |
903 TestingGraph t(Type::Signed32()); | 963 TestingGraph t(Type::Signed32()); |
904 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); | 964 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); |
905 Node* use = t.Use(trunc, kTypeInt32); | 965 Node* use = t.Use(trunc, kTypeInt32); |
906 t.Return(use); | 966 t.Return(use); |
907 t.Lower(); | 967 t.Lower(); |
908 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0)); | 968 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0)); |
909 } | 969 } |
910 | 970 |
911 | 971 |
| 972 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { |
| 973 // NumberToInt32(x: kRepFloat64) used as kMachInt32 |
| 974 TestingGraph t(Type::Number()); |
| 975 Node* p0 = t.ExampleWithOutput(kMachFloat64); |
| 976 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0); |
| 977 Node* use = t.Use(trunc, kMachInt32); |
| 978 t.Return(use); |
| 979 t.Lower(); |
| 980 CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); |
| 981 } |
| 982 |
| 983 |
| 984 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) { |
| 985 // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachInt32 |
| 986 TestingGraph t(Type::Number()); |
| 987 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); |
| 988 Node* use = t.Use(trunc, kMachInt32); |
| 989 t.Return(use); |
| 990 t.Lower(); |
| 991 Node* node = use->InputAt(0); |
| 992 CHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, node->opcode()); |
| 993 Node* of = node->InputAt(0); |
| 994 CHECK_EQ(IrOpcode::kChangeTaggedToFloat64, of->opcode()); |
| 995 CHECK_EQ(t.p0, of->InputAt(0)); |
| 996 } |
| 997 |
| 998 |
912 TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) { | 999 TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) { |
913 // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepTagged | 1000 // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepTagged |
914 } | 1001 } |
915 | 1002 |
916 | 1003 |
917 TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) { | 1004 TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) { |
918 // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepWord32 | 1005 // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepWord32 |
919 // | kTypeInt32 | 1006 // | kTypeInt32 |
920 } | 1007 } |
921 | 1008 |
922 | 1009 |
923 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { | |
924 // TODO(titzer): NumberToInt32(x: kRepFloat64) used as kRepWord32 | | |
925 // kTypeUint32 | |
926 } | |
927 | |
928 | |
929 TEST(LowerNumberToUint32_to_nop) { | 1010 TEST(LowerNumberToUint32_to_nop) { |
930 // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged | 1011 // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged |
931 TestingGraph t(Type::Unsigned32()); | 1012 TestingGraph t(Type::Unsigned32()); |
932 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); | 1013 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); |
933 Node* use = t.Use(trunc, kRepTagged); | 1014 Node* use = t.Use(trunc, kRepTagged); |
934 t.Return(use); | 1015 t.Return(use); |
935 t.Lower(); | 1016 t.Lower(); |
936 CHECK_EQ(t.p0, use->InputAt(0)); | 1017 CHECK_EQ(t.p0, use->InputAt(0)); |
937 } | 1018 } |
938 | 1019 |
(...skipping 13 matching lines...) Expand all Loading... |
952 // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 | 1033 // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 |
953 TestingGraph t(Type::Unsigned32()); | 1034 TestingGraph t(Type::Unsigned32()); |
954 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); | 1035 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); |
955 Node* use = t.Use(trunc, kTypeUint32); | 1036 Node* use = t.Use(trunc, kTypeUint32); |
956 t.Return(use); | 1037 t.Return(use); |
957 t.Lower(); | 1038 t.Lower(); |
958 CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0)); | 1039 CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0)); |
959 } | 1040 } |
960 | 1041 |
961 | 1042 |
| 1043 TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32) { |
| 1044 // NumberToUint32(x: kRepFloat64) used as kMachUint32 |
| 1045 TestingGraph t(Type::Number()); |
| 1046 Node* p0 = t.ExampleWithOutput(kMachFloat64); |
| 1047 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), p0); |
| 1048 Node* use = t.Use(trunc, kMachUint32); |
| 1049 t.Return(use); |
| 1050 t.Lower(); |
| 1051 CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); |
| 1052 } |
| 1053 |
| 1054 |
| 1055 TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) { |
| 1056 // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachUint32 |
| 1057 TestingGraph t(Type::Number()); |
| 1058 Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); |
| 1059 Node* use = t.Use(trunc, kMachUint32); |
| 1060 t.Return(use); |
| 1061 t.Lower(); |
| 1062 Node* node = use->InputAt(0); |
| 1063 CHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, node->opcode()); |
| 1064 Node* of = node->InputAt(0); |
| 1065 CHECK_EQ(IrOpcode::kChangeTaggedToFloat64, of->opcode()); |
| 1066 CHECK_EQ(t.p0, of->InputAt(0)); |
| 1067 } |
| 1068 |
| 1069 |
962 TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) { | 1070 TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) { |
963 // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as | 1071 // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as |
964 // kRepTagged | 1072 // kRepTagged |
965 } | 1073 } |
966 | 1074 |
967 | 1075 |
968 TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) { | 1076 TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) { |
969 // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as | 1077 // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as |
970 // kRepWord32 | 1078 // kRepWord32 |
971 } | 1079 } |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 | 1449 |
1342 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1450 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1343 t.p1, t.start, t.start); | 1451 t.p1, t.start, t.start); |
1344 t.Effect(store); | 1452 t.Effect(store); |
1345 t.Lower(); | 1453 t.Lower(); |
1346 | 1454 |
1347 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1455 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1348 CHECK_EQ(t.p0, store->InputAt(0)); | 1456 CHECK_EQ(t.p0, store->InputAt(0)); |
1349 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1457 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1350 } | 1458 } |
OLD | NEW |