blob: e37d4a2913bf702c386680102ee24f3ff6839bee [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// 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
3// found in the LICENSE file.
4
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/code-factory.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006#include "src/compiler/access-builder.h"
7#include "src/compiler/js-graph.h"
8#include "src/compiler/js-operator.h"
9#include "src/compiler/js-typed-lowering.h"
10#include "src/compiler/machine-operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/compiler/node-properties.h"
12#include "src/compiler/operator-properties.h"
13#include "src/isolate-inl.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014#include "test/unittests/compiler/compiler-test-utils.h"
15#include "test/unittests/compiler/graph-unittest.h"
16#include "test/unittests/compiler/node-test-utils.h"
17#include "testing/gmock-support.h"
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019using testing::_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040020using testing::BitEq;
21using testing::IsNaN;
22
23
24namespace v8 {
25namespace internal {
26namespace compiler {
27
28namespace {
29
30const ExternalArrayType kExternalArrayTypes[] = {
31 kExternalUint8Array, kExternalInt8Array, kExternalUint16Array,
32 kExternalInt16Array, kExternalUint32Array, kExternalInt32Array,
33 kExternalFloat32Array, kExternalFloat64Array};
34
35
36const double kFloat64Values[] = {
37 -V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
38 -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
39 -1.67813e+72, -2.3382e+55, -3.179e+30, -1.441e+09, -1.0647e+09,
40 -7.99361e+08, -5.77375e+08, -2.20984e+08, -32757, -13171, -9970, -3984,
41 -107, -105, -92, -77, -61, -0.000208163, -1.86685e-06, -1.17296e-10,
42 -9.26358e-11, -5.08004e-60, -1.74753e-65, -1.06561e-71, -5.67879e-79,
43 -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
44 -4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278, -2.03855e-282,
45 -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0, 0.0, 2.22507e-308,
46 1.30127e-270, 7.62898e-260, 4.00313e-249, 3.16829e-233, 1.85244e-228,
47 2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94, 1.35292e-90,
48 2.85394e-83, 1.78323e-77, 5.4967e-57, 1.03207e-25, 4.57401e-25, 1.58738e-05,
49 2, 125, 2310, 9636, 14802, 17168, 28945, 29305, 4.81336e+07, 1.41207e+08,
50 4.65962e+08, 1.40499e+09, 2.12648e+09, 8.80006e+30, 1.4446e+45, 1.12164e+54,
51 2.48188e+89, 6.71121e+102, 3.074e+112, 4.9699e+152, 5.58383e+166,
52 4.30654e+172, 7.08824e+185, 9.6586e+214, 2.028e+223, 6.63277e+243,
53 1.56192e+261, 1.23202e+269, 5.72883e+289, 8.5798e+290, 1.40256e+294,
54 1.79769e+308, V8_INFINITY};
55
56
57const size_t kIndices[] = {0, 1, 42, 100, 1024};
58
59
60const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0, -42.0,
61 -1.0, 0.0, 1.0, 42.0,
62 1000.0, INT_MAX, UINT_MAX, V8_INFINITY};
63
64
65Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
66 Type::Number(), Type::String(), Type::Object()};
67
68
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069STATIC_ASSERT(LANGUAGE_END == 3);
70const LanguageMode kLanguageModes[] = {SLOPPY, STRICT, STRONG};
Emily Bernierd0a1eb72015-03-24 16:35:39 -040071
72} // namespace
73
74
75class JSTypedLoweringTest : public TypedGraphTest {
76 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077 JSTypedLoweringTest()
78 : TypedGraphTest(3), javascript_(zone()), deps_(isolate(), zone()) {}
79 ~JSTypedLoweringTest() override {}
Emily Bernierd0a1eb72015-03-24 16:35:39 -040080
81 protected:
82 Reduction Reduce(Node* node) {
83 MachineOperatorBuilder machine(zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 SimplifiedOperatorBuilder simplified(zone());
85 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
86 &machine);
87 // TODO(titzer): mock the GraphReducer here for better unit testing.
88 GraphReducer graph_reducer(zone(), graph());
89 JSTypedLowering reducer(&graph_reducer, &deps_,
90 JSTypedLowering::kDeoptimizationEnabled, &jsgraph,
91 zone());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040092 return reducer.Reduce(node);
93 }
94
95 Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) {
96 Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 JSArrayBuffer::Setup(buffer, isolate(), true, bytes, byte_length);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040098 return buffer;
99 }
100
101 Matcher<Node*> IsIntPtrConstant(intptr_t value) {
102 return sizeof(value) == 4 ? IsInt32Constant(static_cast<int32_t>(value))
103 : IsInt64Constant(static_cast<int64_t>(value));
104 }
105
106 JSOperatorBuilder* javascript() { return &javascript_; }
107
108 private:
109 JSOperatorBuilder javascript_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 CompilationDependencies deps_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111};
112
113
114// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400115// Constant propagation
116
117
118TEST_F(JSTypedLoweringTest, ParameterWithMinusZero) {
119 {
120 Reduction r = Reduce(
121 Parameter(Type::Constant(factory()->minus_zero_value(), zone())));
122 ASSERT_TRUE(r.Changed());
123 EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
124 }
125 {
126 Reduction r = Reduce(Parameter(Type::MinusZero()));
127 ASSERT_TRUE(r.Changed());
128 EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
129 }
130 {
131 Reduction r = Reduce(Parameter(
132 Type::Union(Type::MinusZero(),
133 Type::Constant(factory()->NewNumber(0), zone()), zone())));
134 EXPECT_FALSE(r.Changed());
135 }
136}
137
138
139TEST_F(JSTypedLoweringTest, ParameterWithNull) {
140 Handle<HeapObject> null = factory()->null_value();
141 {
142 Reduction r = Reduce(Parameter(Type::Constant(null, zone())));
143 ASSERT_TRUE(r.Changed());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 EXPECT_THAT(r.replacement(), IsHeapConstant(null));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145 }
146 {
147 Reduction r = Reduce(Parameter(Type::Null()));
148 ASSERT_TRUE(r.Changed());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 EXPECT_THAT(r.replacement(), IsHeapConstant(null));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400150 }
151}
152
153
154TEST_F(JSTypedLoweringTest, ParameterWithNaN) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 const double kNaNs[] = {-std::numeric_limits<double>::quiet_NaN(),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400156 std::numeric_limits<double>::quiet_NaN(),
157 std::numeric_limits<double>::signaling_NaN()};
158 TRACED_FOREACH(double, nan, kNaNs) {
159 Handle<Object> constant = factory()->NewNumber(nan);
160 Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
161 ASSERT_TRUE(r.Changed());
162 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
163 }
164 {
165 Reduction r =
166 Reduce(Parameter(Type::Constant(factory()->nan_value(), zone())));
167 ASSERT_TRUE(r.Changed());
168 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
169 }
170 {
171 Reduction r = Reduce(Parameter(Type::NaN()));
172 ASSERT_TRUE(r.Changed());
173 EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
174 }
175}
176
177
178TEST_F(JSTypedLoweringTest, ParameterWithPlainNumber) {
179 TRACED_FOREACH(double, value, kFloat64Values) {
180 Handle<Object> constant = factory()->NewNumber(value);
181 Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
182 ASSERT_TRUE(r.Changed());
183 EXPECT_THAT(r.replacement(), IsNumberConstant(value));
184 }
185 TRACED_FOREACH(double, value, kIntegerValues) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186 Reduction r = Reduce(Parameter(Type::Range(value, value, zone())));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400187 ASSERT_TRUE(r.Changed());
188 EXPECT_THAT(r.replacement(), IsNumberConstant(value));
189 }
190}
191
192
193TEST_F(JSTypedLoweringTest, ParameterWithUndefined) {
194 Handle<HeapObject> undefined = factory()->undefined_value();
195 {
196 Reduction r = Reduce(Parameter(Type::Undefined()));
197 ASSERT_TRUE(r.Changed());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198 EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400199 }
200 {
201 Reduction r = Reduce(Parameter(Type::Constant(undefined, zone())));
202 ASSERT_TRUE(r.Changed());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400204 }
205}
206
207
208// -----------------------------------------------------------------------------
209// JSToBoolean
210
211
212TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
213 Node* input = Parameter(Type::Boolean(), 0);
214 Node* context = Parameter(Type::Any(), 1);
215 Reduction r =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
217 input, context, graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400218 ASSERT_TRUE(r.Changed());
219 EXPECT_EQ(input, r.replacement());
220}
221
222
223TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400224 Node* input = Parameter(
225 Type::Union(
226 Type::MinusZero(),
227 Type::Union(
228 Type::NaN(),
229 Type::Union(
230 Type::Null(),
231 Type::Union(
232 Type::Undefined(),
233 Type::Union(
234 Type::Undetectable(),
235 Type::Union(
236 Type::Constant(factory()->false_value(), zone()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237 Type::Range(0.0, 0.0, zone()), zone()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400238 zone()),
239 zone()),
240 zone()),
241 zone()),
242 zone()),
243 0);
244 Node* context = Parameter(Type::Any(), 1);
245 Reduction r =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
247 input, context, graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400248 ASSERT_TRUE(r.Changed());
249 EXPECT_THAT(r.replacement(), IsFalseConstant());
250}
251
252
253TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
254 Node* input = Parameter(
255 Type::Union(
256 Type::Constant(factory()->true_value(), zone()),
257 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
258 zone()),
259 0);
260 Node* context = Parameter(Type::Any(), 1);
261 Reduction r =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
263 input, context, graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400264 ASSERT_TRUE(r.Changed());
265 EXPECT_THAT(r.replacement(), IsTrueConstant());
266}
267
268
269TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400271 Node* context = Parameter(Type::Any(), 1);
272 Reduction r =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000273 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
274 input, context, graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400275 ASSERT_TRUE(r.Changed());
276 EXPECT_THAT(r.replacement(), IsTrueConstant());
277}
278
279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) {
281 Node* input = Parameter(Type::OrderedNumber(), 0);
282 Node* context = Parameter(Type::Any(), 1);
283 Reduction r =
284 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
285 input, context, graph()->start()));
286 ASSERT_TRUE(r.Changed());
287 EXPECT_THAT(r.replacement(),
288 IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0.0))));
289}
290
291
292TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
293 Node* input = Parameter(Type::String(), 0);
294 Node* context = Parameter(Type::Any(), 1);
295 Reduction r =
296 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
297 input, context, graph()->start()));
298 ASSERT_TRUE(r.Changed());
299 EXPECT_THAT(
300 r.replacement(),
301 IsNumberLessThan(IsNumberConstant(0.0),
302 IsLoadField(AccessBuilder::ForStringLength(), input,
303 graph()->start(), graph()->start())));
304}
305
306
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400307TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) {
308 Node* input = Parameter(Type::Any(), 0);
309 Node* context = Parameter(Type::Any(), 1);
310 Reduction r =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000311 Reduce(graph()->NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
312 input, context, graph()->start()));
313 ASSERT_FALSE(r.Changed());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400314}
315
316
317// -----------------------------------------------------------------------------
318// JSToNumber
319
320
321TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
322 Node* const input = Parameter(Type::PlainPrimitive(), 0);
323 Node* const context = Parameter(Type::Any(), 1);
324 Node* const effect = graph()->start();
325 Node* const control = graph()->start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326 Reduction r =
327 Reduce(graph()->NewNode(javascript()->ToNumber(), input, context,
328 EmptyFrameState(), effect, control));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400329 ASSERT_TRUE(r.Changed());
330 EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)),
331 graph()->start(), control));
332}
333
334
335// -----------------------------------------------------------------------------
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336// JSToObject
337
338
339TEST_F(JSTypedLoweringTest, JSToObjectWithAny) {
340 Node* const input = Parameter(Type::Any(), 0);
341 Node* const context = Parameter(Type::Any(), 1);
342 Node* const frame_state = EmptyFrameState();
343 Node* const effect = graph()->start();
344 Node* const control = graph()->start();
345 Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input,
346 context, frame_state, effect, control));
347 ASSERT_TRUE(r.Changed());
348 EXPECT_THAT(r.replacement(), IsPhi(MachineRepresentation::kTagged, _, _, _));
349}
350
351
352TEST_F(JSTypedLoweringTest, JSToObjectWithReceiver) {
353 Node* const input = Parameter(Type::Receiver(), 0);
354 Node* const context = Parameter(Type::Any(), 1);
355 Node* const frame_state = EmptyFrameState();
356 Node* const effect = graph()->start();
357 Node* const control = graph()->start();
358 Reduction r = Reduce(graph()->NewNode(javascript()->ToObject(), input,
359 context, frame_state, effect, control));
360 ASSERT_TRUE(r.Changed());
361 EXPECT_EQ(input, r.replacement());
362}
363
364
365// -----------------------------------------------------------------------------
366// JSToString
367
368
369TEST_F(JSTypedLoweringTest, JSToStringWithBoolean) {
370 Node* const input = Parameter(Type::Boolean(), 0);
371 Node* const context = Parameter(Type::Any(), 1);
372 Node* const frame_state = EmptyFrameState();
373 Node* const effect = graph()->start();
374 Node* const control = graph()->start();
375 Reduction r = Reduce(graph()->NewNode(javascript()->ToString(), input,
376 context, frame_state, effect, control));
377 ASSERT_TRUE(r.Changed());
378 EXPECT_THAT(r.replacement(),
379 IsSelect(MachineRepresentation::kTagged, input,
380 IsHeapConstant(factory()->true_string()),
381 IsHeapConstant(factory()->false_string())));
382}
383
384
385// -----------------------------------------------------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400386// JSStrictEqual
387
388
389TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
390 Node* const the_hole = HeapConstant(factory()->the_hole_value());
391 Node* const context = UndefinedConstant();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400392 TRACED_FOREACH(Type*, type, kJSTypes) {
393 Node* const lhs = Parameter(type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000394 Reduction r =
395 Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, the_hole,
396 context, graph()->start(), graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400397 ASSERT_TRUE(r.Changed());
398 EXPECT_THAT(r.replacement(), IsFalseConstant());
399 }
400}
401
402
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000403TEST_F(JSTypedLoweringTest, JSStrictEqualWithUnique) {
404 Node* const lhs = Parameter(Type::Unique(), 0);
405 Node* const rhs = Parameter(Type::Unique(), 1);
406 Node* const context = Parameter(Type::Any(), 2);
407 Reduction r =
408 Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs, rhs, context,
409 graph()->start(), graph()->start()));
410 ASSERT_TRUE(r.Changed());
411 EXPECT_THAT(r.replacement(), IsReferenceEqual(Type::Unique(), lhs, rhs));
412}
413
414
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400415// -----------------------------------------------------------------------------
416// JSShiftLeft
417
418
419TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000420 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400421 Node* const lhs = Parameter(Type::Signed32());
422 Node* const context = UndefinedConstant();
423 Node* const effect = graph()->start();
424 Node* const control = graph()->start();
425 TRACED_FORRANGE(double, rhs, 0, 31) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100426 Reduction r = Reduce(graph()->NewNode(
427 javascript()->ShiftLeft(hints), lhs, NumberConstant(rhs), context,
428 EmptyFrameState(), EmptyFrameState(), effect, control));
429 ASSERT_TRUE(r.Changed());
430 EXPECT_THAT(r.replacement(),
431 IsNumberShiftLeft(lhs, IsNumberConstant(BitEq(rhs))));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400432 }
433}
434
435
436TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400438 Node* const lhs = Parameter(Type::Signed32());
439 Node* const rhs = Parameter(Type::Unsigned32());
440 Node* const context = UndefinedConstant();
441 Node* const effect = graph()->start();
442 Node* const control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100443 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(hints), lhs,
444 rhs, context, EmptyFrameState(),
445 EmptyFrameState(), effect, control));
446 ASSERT_TRUE(r.Changed());
447 EXPECT_THAT(r.replacement(), IsNumberShiftLeft(lhs, rhs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400448}
449
450
451// -----------------------------------------------------------------------------
452// JSShiftRight
453
454
455TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400457 Node* const lhs = Parameter(Type::Signed32());
458 Node* const context = UndefinedConstant();
459 Node* const effect = graph()->start();
460 Node* const control = graph()->start();
461 TRACED_FORRANGE(double, rhs, 0, 31) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100462 Reduction r = Reduce(graph()->NewNode(
463 javascript()->ShiftRight(hints), lhs, NumberConstant(rhs), context,
464 EmptyFrameState(), EmptyFrameState(), effect, control));
465 ASSERT_TRUE(r.Changed());
466 EXPECT_THAT(r.replacement(),
467 IsNumberShiftRight(lhs, IsNumberConstant(BitEq(rhs))));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400468 }
469}
470
471
472TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400474 Node* const lhs = Parameter(Type::Signed32());
475 Node* const rhs = Parameter(Type::Unsigned32());
476 Node* const context = UndefinedConstant();
477 Node* const effect = graph()->start();
478 Node* const control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100479 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(hints), lhs,
480 rhs, context, EmptyFrameState(),
481 EmptyFrameState(), effect, control));
482 ASSERT_TRUE(r.Changed());
483 EXPECT_THAT(r.replacement(), IsNumberShiftRight(lhs, rhs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400484}
485
486
487// -----------------------------------------------------------------------------
488// JSShiftRightLogical
489
490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491TEST_F(JSTypedLoweringTest,
492 JSShiftRightLogicalWithUnsigned32AndConstant) {
493 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400494 Node* const lhs = Parameter(Type::Unsigned32());
495 Node* const context = UndefinedConstant();
496 Node* const effect = graph()->start();
497 Node* const control = graph()->start();
498 TRACED_FORRANGE(double, rhs, 0, 31) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100499 Reduction r = Reduce(graph()->NewNode(
500 javascript()->ShiftRightLogical(hints), lhs, NumberConstant(rhs),
501 context, EmptyFrameState(), EmptyFrameState(), effect, control));
502 ASSERT_TRUE(r.Changed());
503 EXPECT_THAT(r.replacement(),
504 IsNumberShiftRightLogical(lhs, IsNumberConstant(BitEq(rhs))));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400505 }
506}
507
508
509TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000510 BinaryOperationHints const hints = BinaryOperationHints::Any();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400511 Node* const lhs = Parameter(Type::Unsigned32());
512 Node* const rhs = Parameter(Type::Unsigned32());
513 Node* const context = UndefinedConstant();
514 Node* const effect = graph()->start();
515 Node* const control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100516 Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(hints),
517 lhs, rhs, context, EmptyFrameState(),
518 EmptyFrameState(), effect, control));
519 ASSERT_TRUE(r.Changed());
520 EXPECT_THAT(r.replacement(), IsNumberShiftRightLogical(lhs, rhs));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400521}
522
523
524// -----------------------------------------------------------------------------
525// JSLoadContext
526
527
528TEST_F(JSTypedLoweringTest, JSLoadContext) {
529 Node* const context = Parameter(Type::Any());
530 Node* const effect = graph()->start();
531 static bool kBooleans[] = {false, true};
532 TRACED_FOREACH(size_t, index, kIndices) {
533 TRACED_FOREACH(bool, immutable, kBooleans) {
534 Reduction const r1 = Reduce(
535 graph()->NewNode(javascript()->LoadContext(0, index, immutable),
536 context, context, effect));
537 ASSERT_TRUE(r1.Changed());
538 EXPECT_THAT(r1.replacement(),
539 IsLoadField(AccessBuilder::ForContextSlot(index), context,
540 effect, graph()->start()));
541
542 Reduction const r2 = Reduce(
543 graph()->NewNode(javascript()->LoadContext(1, index, immutable),
544 context, context, effect));
545 ASSERT_TRUE(r2.Changed());
546 EXPECT_THAT(r2.replacement(),
547 IsLoadField(AccessBuilder::ForContextSlot(index),
548 IsLoadField(AccessBuilder::ForContextSlot(
549 Context::PREVIOUS_INDEX),
550 context, effect, graph()->start()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551 _, graph()->start()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400552 }
553 }
554}
555
556
557// -----------------------------------------------------------------------------
558// JSStoreContext
559
560
561TEST_F(JSTypedLoweringTest, JSStoreContext) {
562 Node* const context = Parameter(Type::Any());
563 Node* const effect = graph()->start();
564 Node* const control = graph()->start();
565 TRACED_FOREACH(size_t, index, kIndices) {
566 TRACED_FOREACH(Type*, type, kJSTypes) {
567 Node* const value = Parameter(type);
568
569 Reduction const r1 =
570 Reduce(graph()->NewNode(javascript()->StoreContext(0, index), context,
571 value, context, effect, control));
572 ASSERT_TRUE(r1.Changed());
573 EXPECT_THAT(r1.replacement(),
574 IsStoreField(AccessBuilder::ForContextSlot(index), context,
575 value, effect, control));
576
577 Reduction const r2 =
578 Reduce(graph()->NewNode(javascript()->StoreContext(1, index), context,
579 value, context, effect, control));
580 ASSERT_TRUE(r2.Changed());
581 EXPECT_THAT(r2.replacement(),
582 IsStoreField(AccessBuilder::ForContextSlot(index),
583 IsLoadField(AccessBuilder::ForContextSlot(
584 Context::PREVIOUS_INDEX),
585 context, effect, graph()->start()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000586 value, _, control));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400587 }
588 }
589}
590
591
592// -----------------------------------------------------------------------------
593// JSLoadProperty
594
595
596TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
597 const size_t kLength = 17;
598 double backing_store[kLength];
599 Handle<JSArrayBuffer> buffer =
600 NewArrayBuffer(backing_store, sizeof(backing_store));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601 VectorSlotPair feedback;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400602 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100603 Handle<JSTypedArray> array =
604 factory()->NewJSTypedArray(type, buffer, 0, kLength);
605 int const element_size = static_cast<int>(array->element_size());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400606
Ben Murdoch097c5b22016-05-18 11:27:45 +0100607 Node* key = Parameter(
608 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
609 Node* base = HeapConstant(array);
610 Node* vector = UndefinedConstant();
611 Node* context = UndefinedConstant();
612 Node* effect = graph()->start();
613 Node* control = graph()->start();
614 Reduction r = Reduce(graph()->NewNode(
615 javascript()->LoadProperty(feedback), base, key, vector, context,
616 EmptyFrameState(), EmptyFrameState(), effect, control));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000617
Ben Murdoch097c5b22016-05-18 11:27:45 +0100618 Matcher<Node*> offset_matcher =
619 element_size == 1
620 ? key
621 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000622
Ben Murdoch097c5b22016-05-18 11:27:45 +0100623 ASSERT_TRUE(r.Changed());
624 EXPECT_THAT(
625 r.replacement(),
626 IsLoadBuffer(BufferAccess(type),
627 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
628 offset_matcher,
629 IsNumberConstant(array->byte_length()->Number()), effect,
630 control));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400631 }
632}
633
634
635TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
636 const size_t kLength = 17;
637 double backing_store[kLength];
638 Handle<JSArrayBuffer> buffer =
639 NewArrayBuffer(backing_store, sizeof(backing_store));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000640 VectorSlotPair feedback;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400641 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100642 Handle<JSTypedArray> array =
643 factory()->NewJSTypedArray(type, buffer, 0, kLength);
644 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400645
Ben Murdoch097c5b22016-05-18 11:27:45 +0100646 int min = random_number_generator()->NextInt(static_cast<int>(kLength));
647 int max = random_number_generator()->NextInt(static_cast<int>(kLength));
648 if (min > max) std::swap(min, max);
649 Node* key = Parameter(Type::Range(min, max, zone()));
650 Node* base = HeapConstant(array);
651 Node* vector = UndefinedConstant();
652 Node* context = UndefinedConstant();
653 Node* effect = graph()->start();
654 Node* control = graph()->start();
655 Reduction r = Reduce(graph()->NewNode(
656 javascript()->LoadProperty(feedback), base, key, vector, context,
657 EmptyFrameState(), EmptyFrameState(), effect, control));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000658
Ben Murdoch097c5b22016-05-18 11:27:45 +0100659 ASSERT_TRUE(r.Changed());
660 EXPECT_THAT(
661 r.replacement(),
662 IsLoadElement(access,
663 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
664 key, effect, control));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400665 }
666}
667
668
669// -----------------------------------------------------------------------------
670// JSStoreProperty
671
672
673TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
674 const size_t kLength = 17;
675 double backing_store[kLength];
676 Handle<JSArrayBuffer> buffer =
677 NewArrayBuffer(backing_store, sizeof(backing_store));
678 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000679 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400680 Handle<JSTypedArray> array =
681 factory()->NewJSTypedArray(type, buffer, 0, kLength);
682 int const element_size = static_cast<int>(array->element_size());
683
684 Node* key = Parameter(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000685 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400686 Node* base = HeapConstant(array);
687 Node* value =
688 Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000689 Node* vector = UndefinedConstant();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400690 Node* context = UndefinedConstant();
691 Node* effect = graph()->start();
692 Node* control = graph()->start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000693 VectorSlotPair feedback;
694 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
695 Node* node = graph()->NewNode(op, base, key, value, vector, context,
696 EmptyFrameState(), EmptyFrameState(),
697 effect, control);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400698 Reduction r = Reduce(node);
699
700 Matcher<Node*> offset_matcher =
701 element_size == 1
702 ? key
703 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
704
705 ASSERT_TRUE(r.Changed());
706 EXPECT_THAT(
707 r.replacement(),
708 IsStoreBuffer(BufferAccess(type),
709 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
710 offset_matcher,
711 IsNumberConstant(array->byte_length()->Number()), value,
712 effect, control));
713 }
714 }
715}
716
717
718TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
719 const size_t kLength = 17;
720 double backing_store[kLength];
721 Handle<JSArrayBuffer> buffer =
722 NewArrayBuffer(backing_store, sizeof(backing_store));
723 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400725 Handle<JSTypedArray> array =
726 factory()->NewJSTypedArray(type, buffer, 0, kLength);
727 int const element_size = static_cast<int>(array->element_size());
728
729 Node* key = Parameter(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000730 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400731 Node* base = HeapConstant(array);
732 Node* value = Parameter(Type::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000733 Node* vector = UndefinedConstant();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400734 Node* context = UndefinedConstant();
735 Node* effect = graph()->start();
736 Node* control = graph()->start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000737 VectorSlotPair feedback;
738 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
739 Node* node = graph()->NewNode(op, base, key, value, vector, context,
740 EmptyFrameState(), EmptyFrameState(),
741 effect, control);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400742 Reduction r = Reduce(node);
743
744 Matcher<Node*> offset_matcher =
745 element_size == 1
746 ? key
747 : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
748
749 Matcher<Node*> value_matcher =
750 IsToNumber(value, context, effect, control);
751 Matcher<Node*> effect_matcher = value_matcher;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400752
753 ASSERT_TRUE(r.Changed());
754 EXPECT_THAT(
755 r.replacement(),
756 IsStoreBuffer(BufferAccess(type),
757 IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
758 offset_matcher,
759 IsNumberConstant(array->byte_length()->Number()),
760 value_matcher, effect_matcher, control));
761 }
762 }
763}
764
765
766TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
767 const size_t kLength = 17;
768 double backing_store[kLength];
769 Handle<JSArrayBuffer> buffer =
770 NewArrayBuffer(backing_store, sizeof(backing_store));
771 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000772 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400773 Handle<JSTypedArray> array =
774 factory()->NewJSTypedArray(type, buffer, 0, kLength);
775 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
776
777 int min = random_number_generator()->NextInt(static_cast<int>(kLength));
778 int max = random_number_generator()->NextInt(static_cast<int>(kLength));
779 if (min > max) std::swap(min, max);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000780 Node* key = Parameter(Type::Range(min, max, zone()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400781 Node* base = HeapConstant(array);
782 Node* value = Parameter(access.type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000783 Node* vector = UndefinedConstant();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400784 Node* context = UndefinedConstant();
785 Node* effect = graph()->start();
786 Node* control = graph()->start();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000787 VectorSlotPair feedback;
788 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
789 Node* node = graph()->NewNode(op, base, key, value, vector, context,
790 EmptyFrameState(), EmptyFrameState(),
791 effect, control);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400792 Reduction r = Reduce(node);
793
794 ASSERT_TRUE(r.Changed());
795 EXPECT_THAT(
796 r.replacement(),
797 IsStoreElement(
798 access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
799 key, value, effect, control));
800 }
801 }
802}
803
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000804
805// -----------------------------------------------------------------------------
806// JSLoadNamed
807
808
809TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) {
810 VectorSlotPair feedback;
811 Handle<Name> name = factory()->length_string();
812 Node* const receiver = Parameter(Type::String(), 0);
813 Node* const vector = Parameter(Type::Internal(), 1);
814 Node* const context = UndefinedConstant();
815 Node* const effect = graph()->start();
816 Node* const control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100817 Reduction const r = Reduce(graph()->NewNode(
818 javascript()->LoadNamed(name, feedback), receiver, vector, context,
819 EmptyFrameState(), EmptyFrameState(), effect, control));
820 ASSERT_TRUE(r.Changed());
821 EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(),
822 receiver, effect, control));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000823}
824
825
826TEST_F(JSTypedLoweringTest, JSLoadNamedFunctionPrototype) {
827 VectorSlotPair feedback;
828 Handle<Name> name = factory()->prototype_string();
829 Handle<JSFunction> function = isolate()->object_function();
830 Handle<JSObject> function_prototype(JSObject::cast(function->prototype()));
831 Node* const receiver = Parameter(Type::Constant(function, zone()), 0);
832 Node* const vector = Parameter(Type::Internal(), 1);
833 Node* const context = Parameter(Type::Internal(), 2);
834 Node* const effect = graph()->start();
835 Node* const control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100836 Reduction const r = Reduce(graph()->NewNode(
837 javascript()->LoadNamed(name, feedback), receiver, vector, context,
838 EmptyFrameState(), EmptyFrameState(), effect, control));
839 ASSERT_TRUE(r.Changed());
840 EXPECT_THAT(r.replacement(), IsHeapConstant(function_prototype));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000841}
842
843
844// -----------------------------------------------------------------------------
845// JSAdd
846
847
848TEST_F(JSTypedLoweringTest, JSAddWithString) {
849 BinaryOperationHints const hints = BinaryOperationHints::Any();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850 Node* lhs = Parameter(Type::String(), 0);
851 Node* rhs = Parameter(Type::String(), 1);
852 Node* context = Parameter(Type::Any(), 2);
853 Node* frame_state0 = EmptyFrameState();
854 Node* frame_state1 = EmptyFrameState();
855 Node* effect = graph()->start();
856 Node* control = graph()->start();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100857 Reduction r =
858 Reduce(graph()->NewNode(javascript()->Add(hints), lhs, rhs, context,
859 frame_state0, frame_state1, effect, control));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860 ASSERT_TRUE(r.Changed());
861 EXPECT_THAT(r.replacement(),
862 IsCall(_, IsHeapConstant(CodeFactory::StringAdd(
863 isolate(), STRING_ADD_CHECK_NONE,
864 NOT_TENURED).code()),
865 lhs, rhs, context, frame_state0, effect, control));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000866}
867
868
869// -----------------------------------------------------------------------------
870// JSInstanceOf
871// Test that instanceOf is reduced if and only if the right-hand side is a
872// function constant. Functional correctness is ensured elsewhere.
873
874
875TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithoutSmiCheck) {
876 Node* const context = Parameter(Type::Any());
877 Node* const frame_state = EmptyFrameState();
878 Node* const effect = graph()->start();
879 Node* const control = graph()->start();
880
881 // Reduce if left-hand side is known to be an object.
882 Node* instanceOf =
883 graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Object(), 0),
884 HeapConstant(isolate()->object_function()), context,
885 frame_state, effect, control);
886 Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
887 frame_state, effect, control);
888 Reduction r = Reduce(instanceOf);
889 ASSERT_TRUE(r.Changed());
890 ASSERT_EQ(r.replacement(), dummy->InputAt(0));
891 ASSERT_NE(instanceOf, dummy->InputAt(0));
892}
893
894
895TEST_F(JSTypedLoweringTest, JSInstanceOfSpecializationWithSmiCheck) {
896 Node* const context = Parameter(Type::Any());
897 Node* const frame_state = EmptyFrameState();
898 Node* const effect = graph()->start();
899 Node* const control = graph()->start();
900
901 // Reduce if left-hand side could be a Smi.
902 Node* instanceOf =
903 graph()->NewNode(javascript()->InstanceOf(), Parameter(Type::Any(), 0),
904 HeapConstant(isolate()->object_function()), context,
905 frame_state, effect, control);
906 Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
907 frame_state, effect, control);
908 Reduction r = Reduce(instanceOf);
909 ASSERT_TRUE(r.Changed());
910 ASSERT_EQ(r.replacement(), dummy->InputAt(0));
911 ASSERT_NE(instanceOf, dummy->InputAt(0));
912}
913
914
915TEST_F(JSTypedLoweringTest, JSInstanceOfNoSpecialization) {
916 Node* const context = Parameter(Type::Any());
917 Node* const frame_state = EmptyFrameState();
918 Node* const effect = graph()->start();
919 Node* const control = graph()->start();
920
921 // Do not reduce if right-hand side is not a function constant.
922 Node* instanceOf = graph()->NewNode(
923 javascript()->InstanceOf(), Parameter(Type::Any(), 0),
924 Parameter(Type::Any()), context, frame_state, effect, control);
925 Node* dummy = graph()->NewNode(javascript()->ToObject(), instanceOf, context,
926 frame_state, effect, control);
927 Reduction r = Reduce(instanceOf);
928 ASSERT_FALSE(r.Changed());
929 ASSERT_EQ(instanceOf, dummy->InputAt(0));
930}
931
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400932} // namespace compiler
933} // namespace internal
934} // namespace v8