blob: 0d6b5b282708118f4fb74fc29bfbf6319fe29806 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
5#include <limits>
6
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "test/cctest/cctest.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "test/cctest/compiler/codegen-tester.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "test/cctest/compiler/graph-builder-tester.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "test/cctest/compiler/value-helper.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
12#include "src/compiler/node-matchers.h"
13#include "src/compiler/representation-change.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015namespace v8 {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016namespace internal {
17namespace compiler {
18
19class RepresentationChangerTester : public HandleAndZoneScope,
20 public GraphAndBuilders {
21 public:
22 explicit RepresentationChangerTester(int num_parameters = 0)
23 : GraphAndBuilders(main_zone()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024 javascript_(main_zone()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025 jsgraph_(main_isolate(), main_graph_, &main_common_, &javascript_,
26 &main_simplified_, &main_machine_),
27 changer_(&jsgraph_, main_isolate()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028 Node* s = graph()->NewNode(common()->Start(num_parameters));
29 graph()->SetStart(s);
30 }
31
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 JSOperatorBuilder javascript_;
33 JSGraph jsgraph_;
34 RepresentationChanger changer_;
35
36 Isolate* isolate() { return main_isolate(); }
37 Graph* graph() { return main_graph_; }
38 CommonOperatorBuilder* common() { return &main_common_; }
39 JSGraph* jsgraph() { return &jsgraph_; }
40 RepresentationChanger* changer() { return &changer_; }
41
42 // TODO(titzer): use ValueChecker / ValueUtil
43 void CheckInt32Constant(Node* n, int32_t expected) {
44 Int32Matcher m(n);
45 CHECK(m.HasValue());
46 CHECK_EQ(expected, m.Value());
47 }
48
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 void CheckUint32Constant(Node* n, uint32_t expected) {
50 Uint32Matcher m(n);
51 CHECK(m.HasValue());
52 CHECK_EQ(static_cast<int>(expected), static_cast<int>(m.Value()));
53 }
54
55 void CheckFloat64Constant(Node* n, double expected) {
56 Float64Matcher m(n);
57 CHECK(m.HasValue());
Ben Murdochda12d292016-06-02 14:46:10 +010058 CHECK_DOUBLE_EQ(expected, m.Value());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 }
60
61 void CheckFloat32Constant(Node* n, float expected) {
62 CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode());
63 float fval = OpParameter<float>(n->op());
Ben Murdochda12d292016-06-02 14:46:10 +010064 CHECK_FLOAT_EQ(expected, fval);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040065 }
66
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 void CheckHeapConstant(Node* n, HeapObject* expected) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 HeapObjectMatcher m(n);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 CHECK(m.HasValue());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 CHECK_EQ(expected, *m.Value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 }
72
73 void CheckNumberConstant(Node* n, double expected) {
74 NumberMatcher m(n);
75 CHECK_EQ(IrOpcode::kNumberConstant, n->opcode());
76 CHECK(m.HasValue());
Ben Murdochda12d292016-06-02 14:46:10 +010077 CHECK_DOUBLE_EQ(expected, m.Value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 }
79
80 Node* Parameter(int index = 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 Node* n = graph()->NewNode(common()->Parameter(index), graph()->start());
82 NodeProperties::SetType(n, Type::Any());
83 return n;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 }
85
Ben Murdoch61f157c2016-09-16 13:49:30 +010086 Node* Return(Node* input) {
87 Node* n = graph()->NewNode(common()->Return(), input, graph()->start(),
88 graph()->start());
89 return n;
90 }
91
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 void CheckTypeError(MachineRepresentation from, Type* from_type,
93 MachineRepresentation to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094 changer()->testing_type_errors_ = true;
95 changer()->type_error_ = false;
96 Node* n = Parameter(0);
Ben Murdoch61f157c2016-09-16 13:49:30 +010097 Node* use = Return(n);
98 Node* c = changer()->GetRepresentationFor(n, from, from_type, use,
99 UseInfo(to, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100 CHECK(changer()->type_error_);
101 CHECK_EQ(n, c);
102 }
103
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 void CheckNop(MachineRepresentation from, Type* from_type,
105 MachineRepresentation to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 Node* n = Parameter(0);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100107 Node* use = Return(n);
108 Node* c = changer()->GetRepresentationFor(n, from, from_type, use,
109 UseInfo(to, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 CHECK_EQ(n, c);
111 }
112};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113
114
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115const MachineType kMachineTypes[] = {
116 MachineType::Float32(), MachineType::Float64(), MachineType::Int8(),
117 MachineType::Uint8(), MachineType::Int16(), MachineType::Uint16(),
118 MachineType::Int32(), MachineType::Uint32(), MachineType::Int64(),
119 MachineType::Uint64(), MachineType::AnyTagged()};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120
121
122TEST(BoolToBit_constant) {
123 RepresentationChangerTester r;
124
125 Node* true_node = r.jsgraph()->TrueConstant();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100126 Node* true_use = r.Return(true_node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127 Node* true_bit = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100128 true_node, MachineRepresentation::kTagged, Type::None(), true_use,
129 UseInfo(MachineRepresentation::kBit, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130 r.CheckInt32Constant(true_bit, 1);
131
132 Node* false_node = r.jsgraph()->FalseConstant();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100133 Node* false_use = r.Return(false_node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 Node* false_bit = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100135 false_node, MachineRepresentation::kTagged, Type::None(), false_use,
136 UseInfo(MachineRepresentation::kBit, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 r.CheckInt32Constant(false_bit, 0);
138}
139
140
141TEST(BitToBool_constant) {
142 RepresentationChangerTester r;
143
144 for (int i = -5; i < 5; i++) {
145 Node* node = r.jsgraph()->Int32Constant(i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100146 Node* use = r.Return(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 Node* val = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100148 node, MachineRepresentation::kBit, Type::Boolean(), use,
149 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value()
151 : r.isolate()->heap()->true_value());
152 }
153}
154
155
156TEST(ToTagged_constant) {
157 RepresentationChangerTester r;
158
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400159 {
160 FOR_FLOAT64_INPUTS(i) {
161 Node* n = r.jsgraph()->Float64Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100162 Node* use = r.Return(n);
163 Node* c = r.changer()->GetRepresentationFor(
164 n, MachineRepresentation::kFloat64, Type::None(), use,
165 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
166 r.CheckNumberConstant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400167 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168 }
169
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400170 {
171 FOR_FLOAT64_INPUTS(i) {
172 Node* n = r.jsgraph()->Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100173 Node* use = r.Return(n);
174 Node* c = r.changer()->GetRepresentationFor(
175 n, MachineRepresentation::kFloat64, Type::None(), use,
176 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
177 r.CheckNumberConstant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400178 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 }
180
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400181 {
182 FOR_FLOAT32_INPUTS(i) {
183 Node* n = r.jsgraph()->Float32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100184 Node* use = r.Return(n);
185 Node* c = r.changer()->GetRepresentationFor(
186 n, MachineRepresentation::kFloat32, Type::None(), use,
187 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
188 r.CheckNumberConstant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400189 }
190 }
191
192 {
193 FOR_INT32_INPUTS(i) {
194 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100195 Node* use = r.Return(n);
196 Node* c = r.changer()->GetRepresentationFor(
197 n, MachineRepresentation::kWord32, Type::Signed32(), use,
198 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
199 r.CheckNumberConstant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200 }
201 }
202
203 {
204 FOR_UINT32_INPUTS(i) {
205 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100206 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100208 n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
209 UseInfo(MachineRepresentation::kTagged, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400210 r.CheckNumberConstant(c, *i);
211 }
212 }
213}
214
215
216TEST(ToFloat64_constant) {
217 RepresentationChangerTester r;
218
219 {
220 FOR_FLOAT64_INPUTS(i) {
221 Node* n = r.jsgraph()->Float64Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100222 Node* use = r.Return(n);
223 Node* c = r.changer()->GetRepresentationFor(
224 n, MachineRepresentation::kFloat64, Type::None(), use,
225 UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
226 CHECK_EQ(n, c);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400227 }
228 }
229
230 {
231 FOR_FLOAT64_INPUTS(i) {
232 Node* n = r.jsgraph()->Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100233 Node* use = r.Return(n);
234 Node* c = r.changer()->GetRepresentationFor(
235 n, MachineRepresentation::kTagged, Type::None(), use,
236 UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
237 r.CheckFloat64Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400238 }
239 }
240
241 {
242 FOR_FLOAT32_INPUTS(i) {
243 Node* n = r.jsgraph()->Float32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100244 Node* use = r.Return(n);
245 Node* c = r.changer()->GetRepresentationFor(
246 n, MachineRepresentation::kFloat32, Type::None(), use,
247 UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
248 r.CheckFloat64Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400249 }
250 }
251
252 {
253 FOR_INT32_INPUTS(i) {
254 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100255 Node* use = r.Return(n);
256 Node* c = r.changer()->GetRepresentationFor(
257 n, MachineRepresentation::kWord32, Type::Signed32(), use,
258 UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
259 r.CheckFloat64Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400260 }
261 }
262
263 {
264 FOR_UINT32_INPUTS(i) {
265 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100266 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000267 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100268 n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
269 UseInfo(MachineRepresentation::kFloat64, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400270 r.CheckFloat64Constant(c, *i);
271 }
272 }
273}
274
275
276static bool IsFloat32Int32(int32_t val) {
277 return val >= -(1 << 23) && val <= (1 << 23);
278}
279
280
281static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); }
282
283
284TEST(ToFloat32_constant) {
285 RepresentationChangerTester r;
286
287 {
288 FOR_FLOAT32_INPUTS(i) {
289 Node* n = r.jsgraph()->Float32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100290 Node* use = r.Return(n);
291 Node* c = r.changer()->GetRepresentationFor(
292 n, MachineRepresentation::kFloat32, Type::None(), use,
293 UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
294 CHECK_EQ(n, c);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400295 }
296 }
297
298 {
299 FOR_FLOAT32_INPUTS(i) {
300 Node* n = r.jsgraph()->Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100301 Node* use = r.Return(n);
302 Node* c = r.changer()->GetRepresentationFor(
303 n, MachineRepresentation::kTagged, Type::None(), use,
304 UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
305 r.CheckFloat32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400306 }
307 }
308
309 {
310 FOR_FLOAT32_INPUTS(i) {
311 Node* n = r.jsgraph()->Float64Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100312 Node* use = r.Return(n);
313 Node* c = r.changer()->GetRepresentationFor(
314 n, MachineRepresentation::kFloat64, Type::None(), use,
315 UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
316 r.CheckFloat32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400317 }
318 }
319
320 {
321 FOR_INT32_INPUTS(i) {
322 if (!IsFloat32Int32(*i)) continue;
323 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100324 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100326 n, MachineRepresentation::kWord32, Type::Signed32(), use,
327 UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400328 r.CheckFloat32Constant(c, static_cast<float>(*i));
329 }
330 }
331
332 {
333 FOR_UINT32_INPUTS(i) {
334 if (!IsFloat32Uint32(*i)) continue;
335 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100336 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000337 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100338 n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
339 UseInfo(MachineRepresentation::kFloat32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400340 r.CheckFloat32Constant(c, static_cast<float>(*i));
341 }
342 }
343}
344
345
346TEST(ToInt32_constant) {
347 RepresentationChangerTester r;
348
349 {
350 FOR_INT32_INPUTS(i) {
351 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100352 Node* use = r.Return(n);
353 Node* c = r.changer()->GetRepresentationFor(
354 n, MachineRepresentation::kWord32, Type::Signed32(), use,
355 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
356 r.CheckInt32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400357 }
358 }
359
360 {
361 FOR_INT32_INPUTS(i) {
362 if (!IsFloat32Int32(*i)) continue;
363 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100364 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000365 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100366 n, MachineRepresentation::kFloat32, Type::Signed32(), use,
367 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400368 r.CheckInt32Constant(c, *i);
369 }
370 }
371
372 {
373 FOR_INT32_INPUTS(i) {
374 Node* n = r.jsgraph()->Float64Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100375 Node* use = r.Return(n);
376 Node* c = r.changer()->GetRepresentationFor(
377 n, MachineRepresentation::kFloat64, Type::Signed32(), use,
378 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
379 r.CheckInt32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400380 }
381 }
382
383 {
384 FOR_INT32_INPUTS(i) {
385 Node* n = r.jsgraph()->Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100386 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000387 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100388 n, MachineRepresentation::kTagged, Type::Signed32(), use,
389 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400390 r.CheckInt32Constant(c, *i);
391 }
392 }
393}
394
395
396TEST(ToUint32_constant) {
397 RepresentationChangerTester r;
398
399 {
400 FOR_UINT32_INPUTS(i) {
401 Node* n = r.jsgraph()->Int32Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100402 Node* use = r.Return(n);
403 Node* c = r.changer()->GetRepresentationFor(
404 n, MachineRepresentation::kWord32, Type::Unsigned32(), use,
405 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
406 r.CheckUint32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400407 }
408 }
409
410 {
411 FOR_UINT32_INPUTS(i) {
412 if (!IsFloat32Uint32(*i)) continue;
413 Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100414 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000415 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100416 n, MachineRepresentation::kFloat32, Type::Unsigned32(), use,
417 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400418 r.CheckUint32Constant(c, *i);
419 }
420 }
421
422 {
423 FOR_UINT32_INPUTS(i) {
424 Node* n = r.jsgraph()->Float64Constant(*i);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100425 Node* use = r.Return(n);
426 Node* c = r.changer()->GetRepresentationFor(
427 n, MachineRepresentation::kFloat64, Type::Unsigned32(), use,
428 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
429 r.CheckUint32Constant(c, *i);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400430 }
431 }
432
433 {
434 FOR_UINT32_INPUTS(i) {
435 Node* n = r.jsgraph()->Constant(static_cast<double>(*i));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100436 Node* use = r.Return(n);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 Node* c = r.changer()->GetRepresentationFor(
Ben Murdoch61f157c2016-09-16 13:49:30 +0100438 n, MachineRepresentation::kTagged, Type::Unsigned32(), use,
439 UseInfo(MachineRepresentation::kWord32, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400440 r.CheckUint32Constant(c, *i);
441 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 }
443}
444
445
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
447 Type* from_type, MachineRepresentation to) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000448 RepresentationChangerTester r;
449
450 Node* n = r.Parameter();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100451 Node* use = r.Return(n);
452 Node* c = r.changer()->GetRepresentationFor(n, from, from_type, use,
453 UseInfo(to, Truncation::None()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454
455 CHECK_NE(c, n);
456 CHECK_EQ(expected, c->opcode());
457 CHECK_EQ(n, c->InputAt(0));
458}
459
460
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400461static void CheckTwoChanges(IrOpcode::Value expected2,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 IrOpcode::Value expected1,
463 MachineRepresentation from, Type* from_type,
464 MachineRepresentation to) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400465 RepresentationChangerTester r;
466
467 Node* n = r.Parameter();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100468 Node* use = r.Return(n);
469 Node* c1 = r.changer()->GetRepresentationFor(n, from, from_type, use,
470 UseInfo(to, Truncation::None()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400471
472 CHECK_NE(c1, n);
473 CHECK_EQ(expected1, c1->opcode());
474 Node* c2 = c1->InputAt(0);
475 CHECK_NE(c2, n);
476 CHECK_EQ(expected2, c2->opcode());
477 CHECK_EQ(n, c2->InputAt(0));
478}
479
480
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481TEST(SingleChanges) {
Ben Murdochc5610432016-08-08 18:44:38 +0100482 CheckChange(IrOpcode::kChangeTaggedToBit, MachineRepresentation::kTagged,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000483 Type::None(), MachineRepresentation::kBit);
Ben Murdochc5610432016-08-08 18:44:38 +0100484 CheckChange(IrOpcode::kChangeBitToTagged, MachineRepresentation::kBit,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485 Type::None(), MachineRepresentation::kTagged);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486
Ben Murdochc5610432016-08-08 18:44:38 +0100487 CheckChange(IrOpcode::kChangeInt31ToTaggedSigned,
488 MachineRepresentation::kWord32, Type::Signed31(),
489 MachineRepresentation::kTagged);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000490 CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32,
491 Type::Signed32(), MachineRepresentation::kTagged);
492 CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32,
493 Type::Unsigned32(), MachineRepresentation::kTagged);
494 CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64,
Ben Murdochc5610432016-08-08 18:44:38 +0100495 Type::Number(), MachineRepresentation::kTagged);
496 CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
497 IrOpcode::kChangeInt31ToTaggedSigned,
498 MachineRepresentation::kFloat64, Type::Signed31(),
499 MachineRepresentation::kTagged);
500 CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
501 IrOpcode::kChangeInt32ToTagged,
502 MachineRepresentation::kFloat64, Type::Signed32(),
503 MachineRepresentation::kTagged);
504 CheckTwoChanges(IrOpcode::kChangeFloat64ToUint32,
505 IrOpcode::kChangeUint32ToTagged,
506 MachineRepresentation::kFloat64, Type::Unsigned32(),
507 MachineRepresentation::kTagged);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
510 Type::Signed32(), MachineRepresentation::kWord32);
511 CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
512 Type::Unsigned32(), MachineRepresentation::kWord32);
513 CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
Ben Murdochc5610432016-08-08 18:44:38 +0100514 Type::Number(), MachineRepresentation::kFloat64);
515 CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100516 Type::Number(), MachineRepresentation::kFloat64);
517 CheckChange(IrOpcode::kTruncateTaggedToFloat64,
518 MachineRepresentation::kTagged, Type::NumberOrUndefined(),
519 MachineRepresentation::kFloat64);
Ben Murdochc5610432016-08-08 18:44:38 +0100520 CheckTwoChanges(IrOpcode::kChangeTaggedSignedToInt32,
521 IrOpcode::kChangeInt32ToFloat64,
522 MachineRepresentation::kTagged, Type::TaggedSigned(),
523 MachineRepresentation::kFloat64);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000524
525 // Int32,Uint32 <-> Float64 are actually machine conversions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000526 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
527 Type::Signed32(), MachineRepresentation::kFloat64);
528 CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineRepresentation::kWord32,
529 Type::Unsigned32(), MachineRepresentation::kFloat64);
530 CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
531 Type::Signed32(), MachineRepresentation::kWord32);
532 CheckChange(IrOpcode::kChangeFloat64ToUint32, MachineRepresentation::kFloat64,
533 Type::Unsigned32(), MachineRepresentation::kWord32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400534
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000535 CheckChange(IrOpcode::kTruncateFloat64ToFloat32,
536 MachineRepresentation::kFloat64, Type::None(),
537 MachineRepresentation::kFloat32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400538
539 // Int32,Uint32 <-> Float32 require two changes.
540 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000541 IrOpcode::kTruncateFloat64ToFloat32,
542 MachineRepresentation::kWord32, Type::Signed32(),
543 MachineRepresentation::kFloat32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400544 CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000545 IrOpcode::kTruncateFloat64ToFloat32,
546 MachineRepresentation::kWord32, Type::Unsigned32(),
547 MachineRepresentation::kFloat32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400548 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000549 IrOpcode::kChangeFloat64ToInt32,
550 MachineRepresentation::kFloat32, Type::Signed32(),
551 MachineRepresentation::kWord32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400552 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000553 IrOpcode::kChangeFloat64ToUint32,
554 MachineRepresentation::kFloat32, Type::Unsigned32(),
555 MachineRepresentation::kWord32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400556
557 // Float32 <-> Tagged require two changes.
558 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000559 IrOpcode::kChangeFloat64ToTagged,
560 MachineRepresentation::kFloat32, Type::None(),
561 MachineRepresentation::kTagged);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400562 CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 IrOpcode::kTruncateFloat64ToFloat32,
564 MachineRepresentation::kTagged, Type::None(),
565 MachineRepresentation::kFloat32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000566}
567
568
569TEST(SignednessInWord32) {
570 RepresentationChangerTester r;
571
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
573 Type::Signed32(), MachineRepresentation::kWord32);
574 CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
575 Type::Unsigned32(), MachineRepresentation::kWord32);
576 CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
577 Type::None(), MachineRepresentation::kFloat64);
578 CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
579 Type::Signed32(), MachineRepresentation::kWord32);
Ben Murdochc5610432016-08-08 18:44:38 +0100580 CheckChange(IrOpcode::kTruncateFloat64ToWord32,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 MachineRepresentation::kFloat64, Type::Number(),
582 MachineRepresentation::kWord32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400583
584 CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000585 IrOpcode::kTruncateFloat64ToFloat32,
586 MachineRepresentation::kWord32, Type::None(),
587 MachineRepresentation::kFloat32);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400588 CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
Ben Murdochc5610432016-08-08 18:44:38 +0100589 IrOpcode::kTruncateFloat64ToWord32,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000590 MachineRepresentation::kFloat32, Type::Number(),
591 MachineRepresentation::kWord32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592}
593
594
595TEST(Nops) {
596 RepresentationChangerTester r;
597
598 // X -> X is always a nop for any single representation X.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000599 for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
600 r.CheckNop(kMachineTypes[i].representation(), Type::None(),
601 kMachineTypes[i].representation());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 }
603
604 // 32-bit floats.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000605 r.CheckNop(MachineRepresentation::kFloat32, Type::None(),
606 MachineRepresentation::kFloat32);
607 r.CheckNop(MachineRepresentation::kFloat32, Type::Number(),
608 MachineRepresentation::kFloat32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000609
610 // 32-bit words can be used as smaller word sizes and vice versa, because
611 // loads from memory implicitly sign or zero extend the value to the
612 // full machine word size, and stores implicitly truncate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000613 r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
614 MachineRepresentation::kWord8);
615 r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
616 MachineRepresentation::kWord16);
617 r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(),
618 MachineRepresentation::kWord32);
619 r.CheckNop(MachineRepresentation::kWord8, Type::Signed32(),
620 MachineRepresentation::kWord32);
621 r.CheckNop(MachineRepresentation::kWord16, Type::Signed32(),
622 MachineRepresentation::kWord32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000623
624 // kRepBit (result of comparison) is implicitly a wordish thing.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000625 r.CheckNop(MachineRepresentation::kBit, Type::None(),
626 MachineRepresentation::kWord8);
627 r.CheckNop(MachineRepresentation::kBit, Type::None(),
628 MachineRepresentation::kWord16);
629 r.CheckNop(MachineRepresentation::kBit, Type::None(),
630 MachineRepresentation::kWord32);
631 r.CheckNop(MachineRepresentation::kBit, Type::None(),
632 MachineRepresentation::kWord64);
633 r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
634 MachineRepresentation::kWord8);
635 r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
636 MachineRepresentation::kWord16);
637 r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
638 MachineRepresentation::kWord32);
639 r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
640 MachineRepresentation::kWord64);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000641}
642
643
644TEST(TypeErrors) {
645 RepresentationChangerTester r;
646
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000647 // Wordish cannot be implicitly converted to/from comparison conditions.
648 r.CheckTypeError(MachineRepresentation::kWord8, Type::None(),
649 MachineRepresentation::kBit);
650 r.CheckTypeError(MachineRepresentation::kWord16, Type::None(),
651 MachineRepresentation::kBit);
652 r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
653 MachineRepresentation::kBit);
654 r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
655 MachineRepresentation::kBit);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000656
657 // Floats cannot be implicitly converted to/from comparison conditions.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000658 r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(),
659 MachineRepresentation::kBit);
660 r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
661 MachineRepresentation::kFloat64);
662 r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
663 MachineRepresentation::kFloat64);
664
665 // Floats cannot be implicitly converted to/from comparison conditions.
666 r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(),
667 MachineRepresentation::kBit);
668 r.CheckTypeError(MachineRepresentation::kBit, Type::None(),
669 MachineRepresentation::kFloat32);
670 r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
671 MachineRepresentation::kFloat32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000672
673 // Word64 is internal and shouldn't be implicitly converted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000674 r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
675 MachineRepresentation::kTagged);
676 r.CheckTypeError(MachineRepresentation::kTagged, Type::None(),
677 MachineRepresentation::kWord64);
678 r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(),
679 MachineRepresentation::kWord64);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000680
681 // Word64 / Word32 shouldn't be implicitly converted.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682 r.CheckTypeError(MachineRepresentation::kWord64, Type::None(),
683 MachineRepresentation::kWord32);
684 r.CheckTypeError(MachineRepresentation::kWord32, Type::None(),
685 MachineRepresentation::kWord64);
686 r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(),
687 MachineRepresentation::kWord64);
688 r.CheckTypeError(MachineRepresentation::kWord32, Type::Unsigned32(),
689 MachineRepresentation::kWord64);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000691
692} // namespace compiler
693} // namespace internal
694} // namespace v8