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/compiler/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
9 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
11 #include "src/compiler/typer.h" | 11 #include "src/compiler/typer.h" |
12 #include "test/unittests/compiler/compiler-test-utils.h" | 12 #include "test/unittests/compiler/compiler-test-utils.h" |
13 #include "test/unittests/compiler/graph-unittest.h" | 13 #include "test/unittests/compiler/graph-unittest.h" |
14 #include "test/unittests/compiler/node-test-utils.h" | 14 #include "test/unittests/compiler/node-test-utils.h" |
| 15 #include "testing/gmock-support.h" |
| 16 |
| 17 using testing::BitEq; |
| 18 |
15 | 19 |
16 namespace v8 { | 20 namespace v8 { |
17 namespace internal { | 21 namespace internal { |
18 namespace compiler { | 22 namespace compiler { |
19 | 23 |
20 namespace { | 24 namespace { |
21 | 25 |
22 const ExternalArrayType kExternalArrayTypes[] = { | 26 const ExternalArrayType kExternalArrayTypes[] = { |
23 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, | 27 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array, |
24 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, | 28 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 | 132 |
129 | 133 |
130 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { | 134 TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) { |
131 Node* input = Parameter(Type::OrderedNumber()); | 135 Node* input = Parameter(Type::OrderedNumber()); |
132 Node* context = UndefinedConstant(); | 136 Node* context = UndefinedConstant(); |
133 | 137 |
134 Reduction r = | 138 Reduction r = |
135 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); | 139 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); |
136 ASSERT_TRUE(r.Changed()); | 140 ASSERT_TRUE(r.Changed()); |
137 EXPECT_THAT(r.replacement(), | 141 EXPECT_THAT(r.replacement(), |
138 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0)))); | 142 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(BitEq(0.0))))); |
139 } | 143 } |
140 | 144 |
141 | 145 |
142 TEST_F(JSTypedLoweringTest, JSToBooleanWithString) { | 146 TEST_F(JSTypedLoweringTest, JSToBooleanWithString) { |
143 Node* input = Parameter(Type::String()); | 147 Node* input = Parameter(Type::String()); |
144 Node* context = UndefinedConstant(); | 148 Node* context = UndefinedConstant(); |
145 | 149 |
146 Reduction r = | 150 Reduction r = |
147 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); | 151 Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context)); |
148 ASSERT_TRUE(r.Changed()); | 152 ASSERT_TRUE(r.Changed()); |
149 EXPECT_THAT(r.replacement(), | 153 EXPECT_THAT(r.replacement(), |
150 IsBooleanNot(IsNumberEqual( | 154 IsBooleanNot(IsNumberEqual( |
151 IsLoadField(AccessBuilder::ForStringLength(), input, | 155 IsLoadField(AccessBuilder::ForStringLength(), input, |
152 graph()->start(), graph()->start()), | 156 graph()->start(), graph()->start()), |
153 IsNumberConstant(0)))); | 157 IsNumberConstant(BitEq(0.0))))); |
154 } | 158 } |
155 | 159 |
156 | 160 |
157 TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) { | 161 TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) { |
158 Node* p0 = Parameter(Type::OrderedNumber(), 0); | 162 Node* p0 = Parameter(Type::OrderedNumber(), 0); |
159 Node* p1 = Parameter(Type::Boolean(), 1); | 163 Node* p1 = Parameter(Type::Boolean(), 1); |
160 Node* context = UndefinedConstant(); | 164 Node* context = UndefinedConstant(); |
161 Node* control = graph()->start(); | 165 Node* control = graph()->start(); |
162 | 166 |
163 Reduction r = Reduce(graph()->NewNode( | 167 Reduction r = Reduce(graph()->NewNode( |
164 javascript()->ToBoolean(), | 168 javascript()->ToBoolean(), |
165 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control), | 169 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control), |
166 context)); | 170 context)); |
167 ASSERT_TRUE(r.Changed()); | 171 ASSERT_TRUE(r.Changed()); |
168 EXPECT_THAT( | 172 EXPECT_THAT(r.replacement(), |
169 r.replacement(), | 173 IsPhi(kMachAnyTagged, IsBooleanNot(IsNumberEqual( |
170 IsPhi(kMachAnyTagged, | 174 p0, IsNumberConstant(BitEq(0.0)))), |
171 IsBooleanNot(IsNumberEqual(p0, IsNumberConstant(0))), p1, control)); | 175 p1, control)); |
172 } | 176 } |
173 | 177 |
174 | 178 |
175 TEST_F(JSTypedLoweringTest, JSToBooleanWithSelect) { | 179 TEST_F(JSTypedLoweringTest, JSToBooleanWithSelect) { |
176 Node* p0 = Parameter(Type::Boolean(), 0); | 180 Node* p0 = Parameter(Type::Boolean(), 0); |
177 Node* p1 = Parameter(Type::DetectableReceiver(), 1); | 181 Node* p1 = Parameter(Type::DetectableReceiver(), 1); |
178 Node* p2 = Parameter(Type::OrderedNumber(), 2); | 182 Node* p2 = Parameter(Type::OrderedNumber(), 2); |
179 Node* context = UndefinedConstant(); | 183 Node* context = UndefinedConstant(); |
180 | 184 |
181 Reduction r = Reduce(graph()->NewNode( | 185 Reduction r = Reduce(graph()->NewNode( |
182 javascript()->ToBoolean(), | 186 javascript()->ToBoolean(), |
183 graph()->NewNode(common()->Select(kMachAnyTagged, BranchHint::kTrue), p0, | 187 graph()->NewNode(common()->Select(kMachAnyTagged, BranchHint::kTrue), p0, |
184 p1, p2), | 188 p1, p2), |
185 context)); | 189 context)); |
186 ASSERT_TRUE(r.Changed()); | 190 ASSERT_TRUE(r.Changed()); |
187 EXPECT_THAT(r.replacement(), | 191 EXPECT_THAT( |
188 IsSelect(kMachAnyTagged, p0, IsTrueConstant(), | 192 r.replacement(), |
189 IsBooleanNot(IsNumberEqual(p2, IsNumberConstant(0))))); | 193 IsSelect(kMachAnyTagged, p0, IsTrueConstant(), |
| 194 IsBooleanNot(IsNumberEqual(p2, IsNumberConstant(BitEq(0.0)))))); |
190 } | 195 } |
191 | 196 |
192 | 197 |
193 // ----------------------------------------------------------------------------- | 198 // ----------------------------------------------------------------------------- |
194 // JSToNumber | 199 // JSToNumber |
195 | 200 |
196 | 201 |
197 TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) { | 202 TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) { |
198 Node* const input = Parameter(Type::PlainPrimitive(), 0); | 203 Node* const input = Parameter(Type::PlainPrimitive(), 0); |
199 Node* const context = Parameter(Type::Any(), 1); | 204 Node* const context = Parameter(Type::Any(), 1); |
200 Node* const effect = graph()->start(); | 205 Node* const effect = graph()->start(); |
201 Node* const control = graph()->start(); | 206 Node* const control = graph()->start(); |
202 Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input, | 207 Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input, |
203 context, effect, control)); | 208 context, effect, control)); |
204 ASSERT_TRUE(r.Changed()); | 209 ASSERT_TRUE(r.Changed()); |
205 EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(0), | 210 EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)), |
206 graph()->start(), control)); | 211 graph()->start(), control)); |
207 } | 212 } |
208 | 213 |
209 | 214 |
210 // ----------------------------------------------------------------------------- | 215 // ----------------------------------------------------------------------------- |
211 // JSStrictEqual | 216 // JSStrictEqual |
212 | 217 |
213 | 218 |
214 TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) { | 219 TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) { |
215 Node* const the_hole = HeapConstant(factory()->the_hole_value()); | 220 Node* const the_hole = HeapConstant(factory()->the_hole_value()); |
(...skipping 12 matching lines...) Expand all Loading... |
228 | 233 |
229 // ----------------------------------------------------------------------------- | 234 // ----------------------------------------------------------------------------- |
230 // JSShiftLeft | 235 // JSShiftLeft |
231 | 236 |
232 | 237 |
233 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) { | 238 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) { |
234 Node* const lhs = Parameter(Type::Signed32()); | 239 Node* const lhs = Parameter(Type::Signed32()); |
235 Node* const context = UndefinedConstant(); | 240 Node* const context = UndefinedConstant(); |
236 Node* const effect = graph()->start(); | 241 Node* const effect = graph()->start(); |
237 Node* const control = graph()->start(); | 242 Node* const control = graph()->start(); |
238 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 243 TRACED_FORRANGE(double, rhs, 0, 31) { |
239 Reduction r = | 244 Reduction r = |
240 Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, | 245 Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, |
241 NumberConstant(rhs), context, effect, control)); | 246 NumberConstant(rhs), context, effect, control)); |
242 ASSERT_TRUE(r.Changed()); | 247 ASSERT_TRUE(r.Changed()); |
243 EXPECT_THAT(r.replacement(), IsWord32Shl(lhs, IsNumberConstant(rhs))); | 248 EXPECT_THAT(r.replacement(), |
| 249 IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs)))); |
244 } | 250 } |
245 } | 251 } |
246 | 252 |
247 | 253 |
248 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) { | 254 TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) { |
249 Node* const lhs = Parameter(Type::Signed32()); | 255 Node* const lhs = Parameter(Type::Signed32()); |
250 Node* const rhs = Parameter(Type::Unsigned32()); | 256 Node* const rhs = Parameter(Type::Unsigned32()); |
251 Node* const context = UndefinedConstant(); | 257 Node* const context = UndefinedConstant(); |
252 Node* const effect = graph()->start(); | 258 Node* const effect = graph()->start(); |
253 Node* const control = graph()->start(); | 259 Node* const control = graph()->start(); |
254 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, rhs, | 260 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, rhs, |
255 context, effect, control)); | 261 context, effect, control)); |
256 ASSERT_TRUE(r.Changed()); | 262 ASSERT_TRUE(r.Changed()); |
257 EXPECT_THAT(r.replacement(), | 263 EXPECT_THAT(r.replacement(), |
258 IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); | 264 IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); |
259 } | 265 } |
260 | 266 |
261 | 267 |
262 // ----------------------------------------------------------------------------- | 268 // ----------------------------------------------------------------------------- |
263 // JSShiftRight | 269 // JSShiftRight |
264 | 270 |
265 | 271 |
266 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) { | 272 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) { |
267 Node* const lhs = Parameter(Type::Signed32()); | 273 Node* const lhs = Parameter(Type::Signed32()); |
268 Node* const context = UndefinedConstant(); | 274 Node* const context = UndefinedConstant(); |
269 Node* const effect = graph()->start(); | 275 Node* const effect = graph()->start(); |
270 Node* const control = graph()->start(); | 276 Node* const control = graph()->start(); |
271 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 277 TRACED_FORRANGE(double, rhs, 0, 31) { |
272 Reduction r = | 278 Reduction r = |
273 Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, | 279 Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, |
274 NumberConstant(rhs), context, effect, control)); | 280 NumberConstant(rhs), context, effect, control)); |
275 ASSERT_TRUE(r.Changed()); | 281 ASSERT_TRUE(r.Changed()); |
276 EXPECT_THAT(r.replacement(), IsWord32Sar(lhs, IsNumberConstant(rhs))); | 282 EXPECT_THAT(r.replacement(), |
| 283 IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs)))); |
277 } | 284 } |
278 } | 285 } |
279 | 286 |
280 | 287 |
281 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) { | 288 TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) { |
282 Node* const lhs = Parameter(Type::Signed32()); | 289 Node* const lhs = Parameter(Type::Signed32()); |
283 Node* const rhs = Parameter(Type::Unsigned32()); | 290 Node* const rhs = Parameter(Type::Unsigned32()); |
284 Node* const context = UndefinedConstant(); | 291 Node* const context = UndefinedConstant(); |
285 Node* const effect = graph()->start(); | 292 Node* const effect = graph()->start(); |
286 Node* const control = graph()->start(); | 293 Node* const control = graph()->start(); |
287 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, rhs, | 294 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, rhs, |
288 context, effect, control)); | 295 context, effect, control)); |
289 ASSERT_TRUE(r.Changed()); | 296 ASSERT_TRUE(r.Changed()); |
290 EXPECT_THAT(r.replacement(), | 297 EXPECT_THAT(r.replacement(), |
291 IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); | 298 IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f)))); |
292 } | 299 } |
293 | 300 |
294 | 301 |
295 // ----------------------------------------------------------------------------- | 302 // ----------------------------------------------------------------------------- |
296 // JSShiftRightLogical | 303 // JSShiftRightLogical |
297 | 304 |
298 | 305 |
299 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) { | 306 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) { |
300 Node* const lhs = Parameter(Type::Unsigned32()); | 307 Node* const lhs = Parameter(Type::Unsigned32()); |
301 Node* const context = UndefinedConstant(); | 308 Node* const context = UndefinedConstant(); |
302 Node* const effect = graph()->start(); | 309 Node* const effect = graph()->start(); |
303 Node* const control = graph()->start(); | 310 Node* const control = graph()->start(); |
304 TRACED_FORRANGE(int32_t, rhs, 0, 31) { | 311 TRACED_FORRANGE(double, rhs, 0, 31) { |
305 Reduction r = | 312 Reduction r = |
306 Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs, | 313 Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs, |
307 NumberConstant(rhs), context, effect, control)); | 314 NumberConstant(rhs), context, effect, control)); |
308 ASSERT_TRUE(r.Changed()); | 315 ASSERT_TRUE(r.Changed()); |
309 EXPECT_THAT(r.replacement(), IsWord32Shr(lhs, IsNumberConstant(rhs))); | 316 EXPECT_THAT(r.replacement(), |
| 317 IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs)))); |
310 } | 318 } |
311 } | 319 } |
312 | 320 |
313 | 321 |
314 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) { | 322 TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) { |
315 Node* const lhs = Parameter(Type::Unsigned32()); | 323 Node* const lhs = Parameter(Type::Unsigned32()); |
316 Node* const rhs = Parameter(Type::Unsigned32()); | 324 Node* const rhs = Parameter(Type::Unsigned32()); |
317 Node* const context = UndefinedConstant(); | 325 Node* const context = UndefinedConstant(); |
318 Node* const effect = graph()->start(); | 326 Node* const effect = graph()->start(); |
319 Node* const control = graph()->start(); | 327 Node* const control = graph()->start(); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 IsStoreElement( | 634 IsStoreElement( |
627 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), | 635 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])), |
628 key, value, effect, control)); | 636 key, value, effect, control)); |
629 } | 637 } |
630 } | 638 } |
631 } | 639 } |
632 | 640 |
633 } // namespace compiler | 641 } // namespace compiler |
634 } // namespace internal | 642 } // namespace internal |
635 } // namespace v8 | 643 } // namespace v8 |
OLD | NEW |