20d5c069fe295dc8f47c6895674026fb8857dd60
[platform/upstream/nodejs.git] / deps / v8 / test / unittests / compiler / js-intrinsic-lowering-unittest.cc
1 // Copyright 2015 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
5 #include "src/compiler/access-builder.h"
6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/js-intrinsic-lowering.h"
8 #include "src/compiler/js-operator.h"
9 #include "test/unittests/compiler/graph-unittest.h"
10 #include "test/unittests/compiler/node-test-utils.h"
11 #include "testing/gmock-support.h"
12
13 using testing::_;
14 using testing::AllOf;
15 using testing::BitEq;
16 using testing::Capture;
17 using testing::CaptureEq;
18
19
20 namespace v8 {
21 namespace internal {
22 namespace compiler {
23
24 class JSIntrinsicLoweringTest : public GraphTest {
25  public:
26   JSIntrinsicLoweringTest() : GraphTest(3), javascript_(zone()) {}
27   ~JSIntrinsicLoweringTest() OVERRIDE {}
28
29  protected:
30   Reduction Reduce(Node* node) {
31     MachineOperatorBuilder machine(zone());
32     JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
33     JSIntrinsicLowering reducer(&jsgraph);
34     return reducer.Reduce(node);
35   }
36
37   JSOperatorBuilder* javascript() { return &javascript_; }
38
39  private:
40   JSOperatorBuilder javascript_;
41 };
42
43
44 // -----------------------------------------------------------------------------
45 // %_IsSmi
46
47
48 TEST_F(JSIntrinsicLoweringTest, InlineIsSmi) {
49   Node* const input = Parameter(0);
50   Node* const context = Parameter(1);
51   Node* const effect = graph()->start();
52   Node* const control = graph()->start();
53   Reduction const r = Reduce(
54       graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineIsSmi, 1),
55                        input, context, effect, control));
56   ASSERT_TRUE(r.Changed());
57   EXPECT_THAT(r.replacement(), IsObjectIsSmi(input));
58 }
59
60
61 // -----------------------------------------------------------------------------
62 // %_IsNonNegativeSmi
63
64
65 TEST_F(JSIntrinsicLoweringTest, InlineIsNonNegativeSmi) {
66   Node* const input = Parameter(0);
67   Node* const context = Parameter(1);
68   Node* const effect = graph()->start();
69   Node* const control = graph()->start();
70   Reduction const r = Reduce(graph()->NewNode(
71       javascript()->CallRuntime(Runtime::kInlineIsNonNegativeSmi, 1), input,
72       context, effect, control));
73   ASSERT_TRUE(r.Changed());
74   EXPECT_THAT(r.replacement(), IsObjectIsNonNegativeSmi(input));
75 }
76
77
78 // -----------------------------------------------------------------------------
79 // %_IsArray
80
81
82 TEST_F(JSIntrinsicLoweringTest, InlineIsArray) {
83   Node* const input = Parameter(0);
84   Node* const context = Parameter(1);
85   Node* const effect = graph()->start();
86   Node* const control = graph()->start();
87   Reduction const r = Reduce(
88       graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineIsArray, 1),
89                        input, context, effect, control));
90   ASSERT_TRUE(r.Changed());
91
92   Node* phi = r.replacement();
93   Capture<Node*> branch, if_false;
94   EXPECT_THAT(
95       phi,
96       IsPhi(
97           static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
98           IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
99                                     IsLoadField(AccessBuilder::ForMap(), input,
100                                                 effect, CaptureEq(&if_false)),
101                                     effect, _),
102                         IsInt32Constant(JS_ARRAY_TYPE)),
103           IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
104                                  IsBranch(IsObjectIsSmi(input), control))),
105                   AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
106 }
107
108
109 // -----------------------------------------------------------------------------
110 // %_IsFunction
111
112
113 TEST_F(JSIntrinsicLoweringTest, InlineIsFunction) {
114   Node* const input = Parameter(0);
115   Node* const context = Parameter(1);
116   Node* const effect = graph()->start();
117   Node* const control = graph()->start();
118   Reduction const r = Reduce(
119       graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineIsFunction, 1),
120                        input, context, effect, control));
121   ASSERT_TRUE(r.Changed());
122
123   Node* phi = r.replacement();
124   Capture<Node*> branch, if_false;
125   EXPECT_THAT(
126       phi,
127       IsPhi(
128           static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
129           IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
130                                     IsLoadField(AccessBuilder::ForMap(), input,
131                                                 effect, CaptureEq(&if_false)),
132                                     effect, _),
133                         IsInt32Constant(JS_FUNCTION_TYPE)),
134           IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
135                                  IsBranch(IsObjectIsSmi(input), control))),
136                   AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
137 }
138
139
140 // -----------------------------------------------------------------------------
141 // %_IsRegExp
142
143
144 TEST_F(JSIntrinsicLoweringTest, InlineIsRegExp) {
145   Node* const input = Parameter(0);
146   Node* const context = Parameter(1);
147   Node* const effect = graph()->start();
148   Node* const control = graph()->start();
149   Reduction const r = Reduce(
150       graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineIsRegExp, 1),
151                        input, context, effect, control));
152   ASSERT_TRUE(r.Changed());
153
154   Node* phi = r.replacement();
155   Capture<Node*> branch, if_false;
156   EXPECT_THAT(
157       phi,
158       IsPhi(
159           static_cast<MachineType>(kTypeBool | kRepTagged), IsFalseConstant(),
160           IsWord32Equal(IsLoadField(AccessBuilder::ForMapInstanceType(),
161                                     IsLoadField(AccessBuilder::ForMap(), input,
162                                                 effect, CaptureEq(&if_false)),
163                                     effect, _),
164                         IsInt32Constant(JS_REGEXP_TYPE)),
165           IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
166                                  IsBranch(IsObjectIsSmi(input), control))),
167                   AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
168 }
169
170
171 // -----------------------------------------------------------------------------
172 // %_ValueOf
173
174
175 TEST_F(JSIntrinsicLoweringTest, InlineValueOf) {
176   Node* const input = Parameter(0);
177   Node* const context = Parameter(1);
178   Node* const effect = graph()->start();
179   Node* const control = graph()->start();
180   Reduction const r = Reduce(
181       graph()->NewNode(javascript()->CallRuntime(Runtime::kInlineValueOf, 1),
182                        input, context, effect, control));
183   ASSERT_TRUE(r.Changed());
184
185   Node* phi = r.replacement();
186   Capture<Node*> branch0, if_false0, branch1, if_true1;
187   EXPECT_THAT(
188       phi,
189       IsPhi(
190           kMachAnyTagged, input,
191           IsPhi(kMachAnyTagged, IsLoadField(AccessBuilder::ForValue(), input,
192                                             effect, CaptureEq(&if_true1)),
193                 input,
194                 IsMerge(
195                     AllOf(CaptureEq(&if_true1), IsIfTrue(CaptureEq(&branch1))),
196                     IsIfFalse(AllOf(
197                         CaptureEq(&branch1),
198                         IsBranch(
199                             IsWord32Equal(
200                                 IsLoadField(
201                                     AccessBuilder::ForMapInstanceType(),
202                                     IsLoadField(AccessBuilder::ForMap(), input,
203                                                 effect, CaptureEq(&if_false0)),
204                                     effect, _),
205                                 IsInt32Constant(JS_VALUE_TYPE)),
206                             CaptureEq(&if_false0)))))),
207           IsMerge(
208               IsIfTrue(AllOf(CaptureEq(&branch0),
209                              IsBranch(IsObjectIsSmi(input), control))),
210               AllOf(CaptureEq(&if_false0), IsIfFalse(CaptureEq(&branch0))))));
211 }
212
213 }  // namespace compiler
214 }  // namespace internal
215 }  // namespace v8