Commit b9886ae9 authored by titzer@chromium.org's avatar titzer@chromium.org

Fix bugs in simplified lowering relating to int32/uint32 signs.

Lowering of NumberToUint32 and NumberToInt32 was not correctly accounting for the sign of the input and the sign of the output, emitting the wrong representation changes.

Along the way, I've found cases where MachineOperatorBuilder would break if fed a machine type for loads or stores that was not cached, requiring MachineOperatorBuilder to take zone to allocate operators for these cases.

R=bmeurer@chromium.org, jarin@chromium.org
BUG=

Review URL: https://codereview.chromium.org/714613002

Cr-Commit-Position: refs/heads/master@{#25247}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25247 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3aaaf5c5
...@@ -69,7 +69,7 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument( ...@@ -69,7 +69,7 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
CommonOperatorBuilder common(graph->zone()); CommonOperatorBuilder common(graph->zone());
Node* zero = graph->NewNode(common.Int32Constant(0)); Node* zero = graph->NewNode(common.Int32Constant(0));
Node* one = graph->NewNode(common.Int32Constant(1)); Node* one = graph->NewNode(common.Int32Constant(1));
MachineOperatorBuilder machine; MachineOperatorBuilder machine(graph->zone());
BasicBlockVector* blocks = schedule->rpo_order(); BasicBlockVector* blocks = schedule->rpo_order();
size_t block_number = 0; size_t block_number = 0;
for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks; for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "src/base/lazy-instance.h" #include "src/base/lazy-instance.h"
#include "src/compiler/opcodes.h" #include "src/compiler/opcodes.h"
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
#include "src/v8.h"
#include "src/zone-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -196,8 +198,9 @@ static base::LazyInstance<MachineOperatorGlobalCache>::type kCache = ...@@ -196,8 +198,9 @@ static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
LAZY_INSTANCE_INITIALIZER; LAZY_INSTANCE_INITIALIZER;
MachineOperatorBuilder::MachineOperatorBuilder(MachineType word, Flags flags) MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
: cache_(kCache.Get()), word_(word), flags_(flags) { Flags flags)
: zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
DCHECK(word == kRepWord32 || word == kRepWord64); DCHECK(word == kRepWord32 || word == kRepWord64);
} }
...@@ -220,8 +223,10 @@ const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { ...@@ -220,8 +223,10 @@ const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
default: default:
break; break;
} }
UNREACHABLE(); // Uncached.
return NULL; return new (zone_) Operator1<LoadRepresentation>( // --
IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
1, 1, 0, rep);
} }
...@@ -242,8 +247,10 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) { ...@@ -242,8 +247,10 @@ const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
default: default:
break; break;
} }
UNREACHABLE(); // Uncached.
return NULL; return new (zone_) Operator1<StoreRepresentation>( // --
IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
1, 0, 1, 0, rep);
} }
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -73,7 +73,7 @@ class MachineOperatorBuilder FINAL : public ZoneObject { ...@@ -73,7 +73,7 @@ class MachineOperatorBuilder FINAL : public ZoneObject {
}; };
typedef base::Flags<Flag, unsigned> Flags; typedef base::Flags<Flag, unsigned> Flags;
explicit MachineOperatorBuilder(MachineType word = kMachPtr, explicit MachineOperatorBuilder(Zone* zone, MachineType word = kMachPtr,
Flags supportedOperators = kNoFlags); Flags supportedOperators = kNoFlags);
const Operator* Word32And(); const Operator* Word32And();
...@@ -211,6 +211,7 @@ class MachineOperatorBuilder FINAL : public ZoneObject { ...@@ -211,6 +211,7 @@ class MachineOperatorBuilder FINAL : public ZoneObject {
#undef PSEUDO_OP_LIST #undef PSEUDO_OP_LIST
private: private:
Zone* zone_;
const MachineOperatorGlobalCache& cache_; const MachineOperatorGlobalCache& cache_;
const MachineType word_; const MachineType word_;
const Flags flags_; const Flags flags_;
......
...@@ -53,7 +53,8 @@ class PipelineData { ...@@ -53,7 +53,8 @@ class PipelineData {
graph_(new (graph_zone()) Graph(graph_zone())), graph_(new (graph_zone()) Graph(graph_zone())),
source_positions_(new SourcePositionTable(graph())), source_positions_(new SourcePositionTable(graph())),
machine_(new (graph_zone()) MachineOperatorBuilder( machine_(new (graph_zone()) MachineOperatorBuilder(
kMachPtr, InstructionSelector::SupportedMachineOperatorFlags())), graph_zone(), kMachPtr,
InstructionSelector::SupportedMachineOperatorFlags())),
common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())), common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())),
javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())), javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())),
jsgraph_(new (graph_zone()) jsgraph_(new (graph_zone())
......
...@@ -17,7 +17,7 @@ RawMachineAssembler::RawMachineAssembler(Graph* graph, ...@@ -17,7 +17,7 @@ RawMachineAssembler::RawMachineAssembler(Graph* graph,
MachineOperatorBuilder::Flags flags) MachineOperatorBuilder::Flags flags)
: GraphBuilder(graph), : GraphBuilder(graph),
schedule_(new (zone()) Schedule(zone())), schedule_(new (zone()) Schedule(zone())),
machine_(word, flags), machine_(zone(), word, flags),
common_(zone()), common_(zone()),
machine_sig_(machine_sig), machine_sig_(machine_sig),
call_descriptor_( call_descriptor_(
......
...@@ -672,8 +672,11 @@ class RepresentationSelector { ...@@ -672,8 +672,11 @@ class RepresentationSelector {
VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else if ((in & kTypeMask) == kTypeUint32 || } else if ((in & kTypeMask) == kTypeUint32 ||
(in & kTypeMask) == kTypeInt32 || in_upper->Is(Type::Unsigned32())) {
in_upper->Is(Type::Unsigned32()) || // Just change representation if necessary.
VisitUnop(node, kTypeUint32 | kRepWord32, kTypeInt32 | kRepWord32);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else if ((in & kTypeMask) == kTypeInt32 ||
(in & kRepMask) == kRepWord32) { (in & kRepMask) == kRepWord32) {
// Just change representation if necessary. // Just change representation if necessary.
VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32);
...@@ -697,12 +700,15 @@ class RepresentationSelector { ...@@ -697,12 +700,15 @@ class RepresentationSelector {
VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else if ((in & kTypeMask) == kTypeUint32 || } else if ((in & kTypeMask) == kTypeUint32 ||
(in & kTypeMask) == kTypeInt32 || in_upper->Is(Type::Unsigned32())) {
in_upper->Is(Type::Signed32()) ||
(in & kRepMask) == kRepWord32) {
// Just change representation if necessary. // Just change representation if necessary.
VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else if ((in & kTypeMask) == kTypeInt32 ||
(in & kRepMask) == kRepWord32) {
// Just change representation if necessary.
VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32);
if (lower()) DeferReplacement(node, node->InputAt(0));
} else { } else {
// Require the input in float64 format and perform truncation. // Require the input in float64 format and perform truncation.
// TODO(turbofan): avoid a truncation with a smi check. // TODO(turbofan): avoid a truncation with a smi check.
......
...@@ -1033,8 +1033,7 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { ...@@ -1033,8 +1033,7 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
lhs = Rangify(lhs, t); lhs = Rangify(lhs, t);
rhs = Rangify(rhs, t); rhs = Rangify(rhs, t);
if (lhs->IsRange() && rhs->IsRange()) { if (lhs->IsRange() && rhs->IsRange()) {
// TODO(titzer): fix me. return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
// return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
} }
return Type::OrderedNumber(); return Type::OrderedNumber();
} }
......
...@@ -61,6 +61,7 @@ class GraphAndBuilders { ...@@ -61,6 +61,7 @@ class GraphAndBuilders {
explicit GraphAndBuilders(Zone* zone) explicit GraphAndBuilders(Zone* zone)
: main_graph_(new (zone) Graph(zone)), : main_graph_(new (zone) Graph(zone)),
main_common_(zone), main_common_(zone),
main_machine_(zone),
main_simplified_(zone) {} main_simplified_(zone) {}
protected: protected:
......
...@@ -33,6 +33,7 @@ class InstructionTester : public HandleAndZoneScope { ...@@ -33,6 +33,7 @@ class InstructionTester : public HandleAndZoneScope {
info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()), info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
linkage(zone(), &info), linkage(zone(), &info),
common(zone()), common(zone()),
machine(zone()),
code(NULL) {} code(NULL) {}
~InstructionTester() { delete code; } ~InstructionTester() { delete code; }
......
...@@ -22,7 +22,7 @@ class JSCacheTesterHelper { ...@@ -22,7 +22,7 @@ class JSCacheTesterHelper {
main_common_(zone), main_common_(zone),
main_javascript_(zone), main_javascript_(zone),
main_typer_(&main_graph_, MaybeHandle<Context>()), main_typer_(&main_graph_, MaybeHandle<Context>()),
main_machine_() {} main_machine_(zone) {}
Graph main_graph_; Graph main_graph_;
CommonOperatorBuilder main_common_; CommonOperatorBuilder main_common_;
JSOperatorBuilder main_javascript_; JSOperatorBuilder main_javascript_;
......
...@@ -21,7 +21,7 @@ class ContextSpecializationTester : public HandleAndZoneScope, ...@@ -21,7 +21,7 @@ class ContextSpecializationTester : public HandleAndZoneScope,
: DirectGraphBuilder(new (main_zone()) Graph(main_zone())), : DirectGraphBuilder(new (main_zone()) Graph(main_zone())),
common_(main_zone()), common_(main_zone()),
javascript_(main_zone()), javascript_(main_zone()),
machine_(), machine_(main_zone()),
simplified_(main_zone()), simplified_(main_zone()),
jsgraph_(graph(), common(), &javascript_, &machine_), jsgraph_(graph(), common(), &javascript_, &machine_),
info_(main_isolate(), main_zone()) {} info_(main_isolate(), main_zone()) {}
......
...@@ -21,6 +21,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { ...@@ -21,6 +21,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
binop(NULL), binop(NULL),
unop(NULL), unop(NULL),
javascript(main_zone()), javascript(main_zone()),
machine(main_zone()),
simplified(main_zone()), simplified(main_zone()),
common(main_zone()), common(main_zone()),
graph(main_zone()), graph(main_zone()),
......
...@@ -56,6 +56,7 @@ class ReducerTester : public HandleAndZoneScope { ...@@ -56,6 +56,7 @@ class ReducerTester : public HandleAndZoneScope {
: isolate(main_isolate()), : isolate(main_isolate()),
binop(NULL), binop(NULL),
unop(NULL), unop(NULL),
machine(main_zone()),
common(main_zone()), common(main_zone()),
graph(main_zone()), graph(main_zone()),
javascript(main_zone()), javascript(main_zone()),
......
...@@ -163,7 +163,8 @@ TEST(BuildMulNodeGraph) { ...@@ -163,7 +163,8 @@ TEST(BuildMulNodeGraph) {
Schedule schedule(scope.main_zone()); Schedule schedule(scope.main_zone());
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
MachineOperatorBuilder machine; // TODO(titzer): use test operators.
MachineOperatorBuilder machine(scope.main_zone());
Node* start = graph.NewNode(common.Start(0)); Node* start = graph.NewNode(common.Start(0));
graph.SetStart(start); graph.SetStart(start);
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/v8.h" #include "src/v8.h"
#include "test/cctest/cctest.h"
#include "src/compiler/access-builder.h" #include "src/compiler/access-builder.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
...@@ -12,17 +11,21 @@ ...@@ -12,17 +11,21 @@
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/graph-visualizer.h" #include "src/compiler/graph-visualizer.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
#include "src/compiler/schedule.h" #include "src/compiler/schedule.h"
#include "src/compiler/scheduler.h" #include "src/compiler/scheduler.h"
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
#include "src/compiler/verifier.h" #include "src/compiler/verifier.h"
#include "test/cctest/cctest.h"
using namespace v8::internal; using namespace v8::internal;
using namespace v8::internal::compiler; using namespace v8::internal::compiler;
Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, 0, 1,
0, 0);
// TODO(titzer): pull RPO tests out to their own file. // TODO(titzer): pull RPO tests out to their own file.
static void CheckRPONumbers(BasicBlockVector* order, size_t expected, static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
bool loops_allowed) { bool loops_allowed) {
...@@ -1571,7 +1574,6 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) { ...@@ -1571,7 +1574,6 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common_builder(scope.main_zone()); CommonOperatorBuilder common_builder(scope.main_zone());
JSOperatorBuilder js_builder(scope.main_zone()); JSOperatorBuilder js_builder(scope.main_zone());
MachineOperatorBuilder machine_builder;
const Operator* op; const Operator* op;
Handle<HeapObject> object = Handle<HeapObject> object =
...@@ -1607,7 +1609,7 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) { ...@@ -1607,7 +1609,7 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) {
Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil); Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
USE(n20); USE(n20);
n20->ReplaceInput(0, n9); n20->ReplaceInput(0, n9);
op = machine_builder.Int32Add(); op = &kIntAdd;
Node* n19 = graph.NewNode(op, nil, nil); Node* n19 = graph.NewNode(op, nil, nil);
USE(n19); USE(n19);
op = common_builder.Phi(kMachAnyTagged, 2); op = common_builder.Phi(kMachAnyTagged, 2);
...@@ -1731,7 +1733,6 @@ TEST(FloatingDiamond2) { ...@@ -1731,7 +1733,6 @@ TEST(FloatingDiamond2) {
HandleAndZoneScope scope; HandleAndZoneScope scope;
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1740,7 +1741,7 @@ TEST(FloatingDiamond2) { ...@@ -1740,7 +1741,7 @@ TEST(FloatingDiamond2) {
Node* p1 = graph.NewNode(common.Parameter(1), start); Node* p1 = graph.NewNode(common.Parameter(1), start);
Node* d1 = CreateDiamond(&graph, &common, p0); Node* d1 = CreateDiamond(&graph, &common, p0);
Node* d2 = CreateDiamond(&graph, &common, p1); Node* d2 = CreateDiamond(&graph, &common, p1);
Node* add = graph.NewNode(machine.Int32Add(), d1, d2); Node* add = graph.NewNode(&kIntAdd, d1, d2);
Node* ret = graph.NewNode(common.Return(), add, start, start); Node* ret = graph.NewNode(common.Return(), add, start, start);
Node* end = graph.NewNode(common.End(), ret, start); Node* end = graph.NewNode(common.End(), ret, start);
...@@ -1754,7 +1755,6 @@ TEST(FloatingDiamond3) { ...@@ -1754,7 +1755,6 @@ TEST(FloatingDiamond3) {
HandleAndZoneScope scope; HandleAndZoneScope scope;
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1763,7 +1763,7 @@ TEST(FloatingDiamond3) { ...@@ -1763,7 +1763,7 @@ TEST(FloatingDiamond3) {
Node* p1 = graph.NewNode(common.Parameter(1), start); Node* p1 = graph.NewNode(common.Parameter(1), start);
Node* d1 = CreateDiamond(&graph, &common, p0); Node* d1 = CreateDiamond(&graph, &common, p0);
Node* d2 = CreateDiamond(&graph, &common, p1); Node* d2 = CreateDiamond(&graph, &common, p1);
Node* add = graph.NewNode(machine.Int32Add(), d1, d2); Node* add = graph.NewNode(&kIntAdd, d1, d2);
Node* d3 = CreateDiamond(&graph, &common, add); Node* d3 = CreateDiamond(&graph, &common, add);
Node* ret = graph.NewNode(common.Return(), d3, start, start); Node* ret = graph.NewNode(common.Return(), d3, start, start);
Node* end = graph.NewNode(common.End(), ret, start); Node* end = graph.NewNode(common.End(), ret, start);
...@@ -1779,7 +1779,6 @@ TEST(NestedFloatingDiamonds) { ...@@ -1779,7 +1779,6 @@ TEST(NestedFloatingDiamonds) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
SimplifiedOperatorBuilder simplified(scope.main_zone()); SimplifiedOperatorBuilder simplified(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1821,7 +1820,6 @@ TEST(NestedFloatingDiamondWithLoop) { ...@@ -1821,7 +1820,6 @@ TEST(NestedFloatingDiamondWithLoop) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
SimplifiedOperatorBuilder simplified(scope.main_zone()); SimplifiedOperatorBuilder simplified(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1837,7 +1835,7 @@ TEST(NestedFloatingDiamondWithLoop) { ...@@ -1837,7 +1835,7 @@ TEST(NestedFloatingDiamondWithLoop) {
Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop); Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
// TODO(mstarzinger): Make scheduler deal with non-empty loops here. // TODO(mstarzinger): Make scheduler deal with non-empty loops here.
// Node* add = graph.NewNode(machine.IntAdd(), ind, fv); // Node* add = graph.NewNode(&kIntAdd, ind, fv);
Node* br1 = graph.NewNode(common.Branch(), ind, loop); Node* br1 = graph.NewNode(common.Branch(), ind, loop);
Node* t1 = graph.NewNode(common.IfTrue(), br1); Node* t1 = graph.NewNode(common.IfTrue(), br1);
...@@ -1863,7 +1861,6 @@ TEST(LoopedFloatingDiamond1) { ...@@ -1863,7 +1861,6 @@ TEST(LoopedFloatingDiamond1) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
SimplifiedOperatorBuilder simplified(scope.main_zone()); SimplifiedOperatorBuilder simplified(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1873,7 +1870,7 @@ TEST(LoopedFloatingDiamond1) { ...@@ -1873,7 +1870,7 @@ TEST(LoopedFloatingDiamond1) {
Node* c = graph.NewNode(common.Int32Constant(7)); Node* c = graph.NewNode(common.Int32Constant(7));
Node* loop = graph.NewNode(common.Loop(2), start, start); Node* loop = graph.NewNode(common.Loop(2), start, start);
Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop); Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
Node* add = graph.NewNode(machine.IntAdd(), ind, c); Node* add = graph.NewNode(&kIntAdd, ind, c);
Node* br = graph.NewNode(common.Branch(), add, loop); Node* br = graph.NewNode(common.Branch(), add, loop);
Node* t = graph.NewNode(common.IfTrue(), br); Node* t = graph.NewNode(common.IfTrue(), br);
...@@ -1902,7 +1899,6 @@ TEST(LoopedFloatingDiamond2) { ...@@ -1902,7 +1899,6 @@ TEST(LoopedFloatingDiamond2) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
SimplifiedOperatorBuilder simplified(scope.main_zone()); SimplifiedOperatorBuilder simplified(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
...@@ -1919,7 +1915,7 @@ TEST(LoopedFloatingDiamond2) { ...@@ -1919,7 +1915,7 @@ TEST(LoopedFloatingDiamond2) {
Node* m1 = graph.NewNode(common.Merge(2), t1, f1); Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind, m1); Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind, m1);
Node* add = graph.NewNode(machine.IntAdd(), ind, phi1); Node* add = graph.NewNode(&kIntAdd, ind, phi1);
Node* br = graph.NewNode(common.Branch(), add, loop); Node* br = graph.NewNode(common.Branch(), add, loop);
Node* t = graph.NewNode(common.IfTrue(), br); Node* t = graph.NewNode(common.IfTrue(), br);
...@@ -1942,7 +1938,6 @@ TEST(PhisPushedDownToDifferentBranches) { ...@@ -1942,7 +1938,6 @@ TEST(PhisPushedDownToDifferentBranches) {
Graph graph(scope.main_zone()); Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone()); CommonOperatorBuilder common(scope.main_zone());
SimplifiedOperatorBuilder simplified(scope.main_zone()); SimplifiedOperatorBuilder simplified(scope.main_zone());
MachineOperatorBuilder machine;
Node* start = graph.NewNode(common.Start(2)); Node* start = graph.NewNode(common.Start(2));
graph.SetStart(start); graph.SetStart(start);
......
...@@ -744,6 +744,17 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { ...@@ -744,6 +744,17 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
} }
} }
Node* ExampleWithTypeAndRep(Type* type, MachineType mach_type) {
FieldAccess access = {kUntaggedBase, 0, Handle<Name>::null(), type,
mach_type};
// TODO(titzer): using loads here just to force the representation is ugly.
Node* node = graph()->NewNode(simplified()->LoadField(access),
jsgraph.IntPtrConstant(0), graph()->start(),
graph()->start());
NodeProperties::SetBounds(node, Bounds(type));
return node;
}
Node* Use(Node* node, MachineType type) { Node* Use(Node* node, MachineType type) {
if (type & kTypeInt32) { if (type & kTypeInt32) {
return graph()->NewNode(machine()->Int32LessThan(), node, return graph()->NewNode(machine()->Int32LessThan(), node,
...@@ -757,6 +768,9 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { ...@@ -757,6 +768,9 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
} else if (type & kRepWord64) { } else if (type & kRepWord64) {
return graph()->NewNode(machine()->Int64LessThan(), node, return graph()->NewNode(machine()->Int64LessThan(), node,
Int64Constant(1)); Int64Constant(1));
} else if (type & kRepWord32) {
return graph()->NewNode(machine()->Word32Equal(), node,
jsgraph.Int32Constant(1));
} else { } else {
return graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), node, return graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), node,
jsgraph.TrueConstant()); jsgraph.TrueConstant());
...@@ -1060,9 +1074,7 @@ TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) { ...@@ -1060,9 +1074,7 @@ TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) {
TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) {
// NumberToInt32(x: kRepFloat64) used as kMachInt32 // NumberToInt32(x: kRepFloat64) used as kMachInt32
TestingGraph t(Type::Number()); TestingGraph t(Type::Number());
Node* p0 = t.ExampleWithOutput(kMachFloat64); Node* p0 = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
// TODO(titzer): run the typer here, or attach machine type to param.
NodeProperties::SetBounds(p0, Bounds(Type::Number()));
Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0);
Node* use = t.Use(trunc, kMachInt32); Node* use = t.Use(trunc, kMachInt32);
t.Return(use); t.Return(use);
...@@ -1086,17 +1098,6 @@ TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) { ...@@ -1086,17 +1098,6 @@ TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) {
} }
TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) {
// TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepTagged
}
TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) {
// TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepWord32
// | kTypeInt32
}
TEST(LowerNumberToUint32_to_nop) { TEST(LowerNumberToUint32_to_nop) {
// NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged
TestingGraph t(Type::Unsigned32()); TestingGraph t(Type::Unsigned32());
...@@ -1159,20 +1160,67 @@ TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) { ...@@ -1159,20 +1160,67 @@ TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) {
} }
TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) { TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_uint32) {
// TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as // NumberToUint32(x: kRepFloat64) used as kRepWord32
// kRepTagged TestingGraph t(Type::Unsigned32());
Node* input = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), input);
Node* use = t.Use(trunc, kRepWord32);
t.Return(use);
t.Lower();
CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, input, use->InputAt(0));
} }
TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) { TEST(LowerNumberToUI32_of_Float64_used_as_word32) {
// TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
// kRepWord32 // kType(Int,Uint)32 | kRepWord32
Type* types[] = {Type::Signed32(), Type::Unsigned32()};
MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
for (int i = 0; i < 2; i++) {
for (int u = 0; u < 3; u++) {
TestingGraph t(types[i]);
Node* input = t.ExampleWithTypeAndRep(
types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
: t.simplified()->NumberToUint32();
Node* trunc = t.graph()->NewNode(op, input);
Node* use = t.Use(trunc, static_cast<MachineType>(kRepWord32 | mach[u]));
t.Return(use);
t.Lower();
IrOpcode::Value opcode = i == 0 ? IrOpcode::kChangeFloat64ToInt32
: IrOpcode::kChangeFloat64ToUint32;
CheckChangeOf(opcode, input, use->InputAt(0));
}
}
} }
TEST(LowerNumberToUint32_to_TruncateFloat64ToUint32) { TEST(LowerNumberToUI32_of_Float64_used_as_tagged) {
// TODO(titzer): NumberToUint32(x: kRepFloat64) used as kRepWord32 // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
// kType(Int,Uint)32 | kRepTagged
Type* types[] = {Type::Signed32(), Type::Unsigned32(), Type::Any()};
MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
for (int i = 0; i < 2; i++) {
for (int u = 0; u < 3; u++) {
TestingGraph t(types[i]);
Node* input = t.ExampleWithTypeAndRep(
types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
: t.simplified()->NumberToUint32();
Node* trunc = t.graph()->NewNode(op, input);
// TODO(titzer): we use the store here to force the representation.
FieldAccess access = {kTaggedBase, 0, Handle<Name>(), types[u],
static_cast<MachineType>(mach[u] | kRepTagged)};
Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
trunc, t.start, t.start);
t.Effect(store);
t.Lower();
CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, input, store->InputAt(2));
}
}
} }
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function g1(i) {
var x = i * 1;
return (x >>> 0) % 1000000000000;
}
function g2(i) {
var x = i * 1;
return ((x >>> 0) % 1000000000000) | 0;
}
function test1() {
assertEquals(2294967296, g1(-2000000000));
assertEquals(2294967295, g1(-2000000001));
assertEquals(2294967290, g1(-2000000006));
assertEquals(2147483651, g1(-2147483645));
assertEquals(2147483650, g1(-2147483646));
assertEquals(2147483649, g1(-2147483647));
assertEquals(2147483648, g1(-2147483648));
assertEquals(2147483647, g1(-2147483649));
assertEquals(3000000000, g1(3000000000));
assertEquals(3000000001, g1(3000000001));
assertEquals(3000000002, g1(3000000002));
assertEquals(4000000000, g1(4000000000));
assertEquals(4000400001, g1(4000400001));
assertEquals(4000400002, g1(4000400002));
assertEquals(3, g1(4294967299));
assertEquals(2, g1(4294967298));
assertEquals(1, g1(4294967297));
assertEquals(0, g1(4294967296));
assertEquals(4294967295, g1(4294967295));
assertEquals(4294967294, g1(4294967294));
assertEquals(4294967293, g1(4294967293));
assertEquals(4294967292, g1(4294967292));
}
%NeverOptimizeFunction(test1);
test1();
function test2() {
assertEquals(-2000000000, g2(-2000000000));
assertEquals(-2000000001, g2(-2000000001));
assertEquals(-2000000006, g2(-2000000006));
assertEquals(-2147483645, g2(-2147483645));
assertEquals(-2147483646, g2(-2147483646));
assertEquals(-2147483647, g2(-2147483647));
assertEquals(-2147483648, g2(-2147483648));
assertEquals(2147483647, g2(-2147483649));
assertEquals(-1294967296, g2(3000000000));
assertEquals(-1294967295, g2(3000000001));
assertEquals(-1294967294, g2(3000000002));
assertEquals(-294967296, g2(4000000000));
assertEquals(-294567295, g2(4000400001));
assertEquals(-294567294, g2(4000400002));
assertEquals(3, g2(4294967299));
assertEquals(2, g2(4294967298));
assertEquals(1, g2(4294967297));
assertEquals(0, g2(4294967296));
assertEquals(-1, g2(4294967295));
assertEquals(-2, g2(4294967294));
assertEquals(-3, g2(4294967293));
assertEquals(-4, g2(4294967292));
}
%NeverOptimizeFunction(test2);
test2();
...@@ -66,7 +66,7 @@ class ChangeLoweringTest : public GraphTest { ...@@ -66,7 +66,7 @@ class ChangeLoweringTest : public GraphTest {
} }
Reduction Reduce(Node* node) { Reduction Reduce(Node* node) {
MachineOperatorBuilder machine(WordRepresentation()); MachineOperatorBuilder machine(zone(), WordRepresentation());
JSOperatorBuilder javascript(zone()); JSOperatorBuilder javascript(zone());
JSGraph jsgraph(graph(), common(), &javascript, &machine); JSGraph jsgraph(graph(), common(), &javascript, &machine);
CompilationInfo info(isolate(), zone()); CompilationInfo info(isolate(), zone());
......
...@@ -23,7 +23,7 @@ class JSBuiltinReducerTest : public TypedGraphTest { ...@@ -23,7 +23,7 @@ class JSBuiltinReducerTest : public TypedGraphTest {
protected: protected:
Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
MachineOperatorBuilder::Flag::kNoFlags) { MachineOperatorBuilder::Flag::kNoFlags) {
MachineOperatorBuilder machine(kMachPtr, flags); MachineOperatorBuilder machine(zone(), kMachPtr, flags);
JSGraph jsgraph(graph(), common(), javascript(), &machine); JSGraph jsgraph(graph(), common(), javascript(), &machine);
JSBuiltinReducer reducer(&jsgraph); JSBuiltinReducer reducer(&jsgraph);
return reducer.Reduce(node); return reducer.Reduce(node);
......
...@@ -38,7 +38,7 @@ class JSTypedLoweringTest : public TypedGraphTest { ...@@ -38,7 +38,7 @@ class JSTypedLoweringTest : public TypedGraphTest {
protected: protected:
Reduction Reduce(Node* node) { Reduction Reduce(Node* node) {
MachineOperatorBuilder machine; MachineOperatorBuilder machine(zone());
JSGraph jsgraph(graph(), common(), javascript(), &machine); JSGraph jsgraph(graph(), common(), javascript(), &machine);
JSTypedLowering reducer(&jsgraph); JSTypedLowering reducer(&jsgraph);
return reducer.Reduce(node); return reducer.Reduce(node);
......
...@@ -22,7 +22,7 @@ namespace compiler { ...@@ -22,7 +22,7 @@ namespace compiler {
class MachineOperatorReducerTest : public TypedGraphTest { class MachineOperatorReducerTest : public TypedGraphTest {
public: public:
explicit MachineOperatorReducerTest(int num_parameters = 2) explicit MachineOperatorReducerTest(int num_parameters = 2)
: TypedGraphTest(num_parameters) {} : TypedGraphTest(num_parameters), machine_(zone()) {}
protected: protected:
Reduction Reduce(Node* node) { Reduction Reduce(Node* node) {
......
...@@ -18,7 +18,7 @@ namespace compiler { ...@@ -18,7 +18,7 @@ namespace compiler {
class NodeMatcherTest : public GraphTest { class NodeMatcherTest : public GraphTest {
public: public:
NodeMatcherTest() {} NodeMatcherTest() : machine_(zone()) {}
virtual ~NodeMatcherTest() {} virtual ~NodeMatcherTest() {}
MachineOperatorBuilder* machine() { return &machine_; } MachineOperatorBuilder* machine() { return &machine_; }
......
...@@ -22,7 +22,7 @@ class SimplifiedOperatorReducerTest : public GraphTest { ...@@ -22,7 +22,7 @@ class SimplifiedOperatorReducerTest : public GraphTest {
protected: protected:
Reduction Reduce(Node* node) { Reduction Reduce(Node* node) {
MachineOperatorBuilder machine; MachineOperatorBuilder machine(zone());
JSOperatorBuilder javascript(zone()); JSOperatorBuilder javascript(zone());
JSGraph jsgraph(graph(), common(), &javascript, &machine); JSGraph jsgraph(graph(), common(), &javascript, &machine);
SimplifiedOperatorReducer reducer(&jsgraph); SimplifiedOperatorReducer reducer(&jsgraph);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment