Skip to content

Commit 4b38c15

Browse files
bmeurerCommit bot
authored andcommitted
[turbofan] Add TruncationMode for TruncateFloat64ToInt32.
We actually need round to zero truncation to implement the counterpart of LDoubleToI in TurboFan, which tries to convert a double to an integer as required for keyed load/store optimizations. Drive-by-cleanup: Reduce some code duplication in the InstructionSelector implementations. [email protected] Review URL: https://codereview.chromium.org/1225993002 Cr-Commit-Position: refs/heads/master@{#29527}
1 parent 3973642 commit 4b38c15

17 files changed

+235
-159
lines changed

src/compiler/arm/instruction-selector-arm.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,17 @@ void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
914914
}
915915

916916

917+
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
918+
switch (TruncationModeOf(node->op())) {
919+
case TruncationMode::kJavaScript:
920+
return VisitRR(this, kArchTruncateDoubleToI, node);
921+
case TruncationMode::kRoundToZero:
922+
return VisitRR(this, kArmVcvtS32F64, node);
923+
}
924+
UNREACHABLE();
925+
}
926+
927+
917928
void InstructionSelector::VisitFloat32Add(Node* node) {
918929
ArmOperandGenerator g(this);
919930
Float32BinopMatcher m(node);

src/compiler/arm64/instruction-selector-arm64.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,9 +1237,18 @@ void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
12371237

12381238

12391239
void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
1240-
Arm64OperandGenerator g(this);
1241-
Emit(kArm64Float64ToFloat32, g.DefineAsRegister(node),
1242-
g.UseRegister(node->InputAt(0)));
1240+
VisitRR(this, kArm64Float64ToFloat32, node);
1241+
}
1242+
1243+
1244+
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
1245+
switch (TruncationModeOf(node->op())) {
1246+
case TruncationMode::kJavaScript:
1247+
return VisitRR(this, kArchTruncateDoubleToI, node);
1248+
case TruncationMode::kRoundToZero:
1249+
return VisitRR(this, kArm64Float64ToInt32, node);
1250+
}
1251+
UNREACHABLE();
12431252
}
12441253

12451254

src/compiler/ia32/instruction-selector-ia32.cc

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,14 @@ class IA32OperandGenerator final : public OperandGenerator {
127127

128128
namespace {
129129

130-
void VisitROFloat(InstructionSelector* selector, Node* node,
131-
ArchOpcode opcode) {
130+
void VisitRO(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
132131
IA32OperandGenerator g(selector);
133132
selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
134133
}
135134

136135

137-
void VisitRRFloat(InstructionSelector* selector, Node* node,
138-
InstructionCode opcode) {
136+
void VisitRR(InstructionSelector* selector, Node* node,
137+
InstructionCode opcode) {
139138
IA32OperandGenerator g(selector);
140139
selector->Emit(opcode, g.DefineAsRegister(node),
141140
g.UseRegister(node->InputAt(0)));
@@ -648,38 +647,43 @@ void InstructionSelector::VisitUint32Mod(Node* node) {
648647

649648

650649
void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
651-
IA32OperandGenerator g(this);
652-
Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
650+
VisitRO(this, node, kSSEFloat32ToFloat64);
653651
}
654652

655653

656654
void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
657-
IA32OperandGenerator g(this);
658-
Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
655+
VisitRO(this, node, kSSEInt32ToFloat64);
659656
}
660657

661658

662659
void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
663-
IA32OperandGenerator g(this);
664-
Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
660+
VisitRO(this, node, kSSEUint32ToFloat64);
665661
}
666662

667663

668664
void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
669-
IA32OperandGenerator g(this);
670-
Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
665+
VisitRO(this, node, kSSEFloat64ToInt32);
671666
}
672667

673668

674669
void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
675-
IA32OperandGenerator g(this);
676-
Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
670+
VisitRO(this, node, kSSEFloat64ToUint32);
677671
}
678672

679673

680674
void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
681-
IA32OperandGenerator g(this);
682-
Emit(kSSEFloat64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
675+
VisitRO(this, node, kSSEFloat64ToFloat32);
676+
}
677+
678+
679+
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
680+
switch (TruncationModeOf(node->op())) {
681+
case TruncationMode::kJavaScript:
682+
return VisitRR(this, node, kArchTruncateDoubleToI);
683+
case TruncationMode::kRoundToZero:
684+
return VisitRO(this, node, kSSEFloat64ToInt32);
685+
}
686+
UNREACHABLE();
683687
}
684688

685689

@@ -791,22 +795,22 @@ void InstructionSelector::VisitFloat64Abs(Node* node) {
791795

792796

793797
void InstructionSelector::VisitFloat32Sqrt(Node* node) {
794-
VisitROFloat(this, node, kSSEFloat32Sqrt);
798+
VisitRO(this, node, kSSEFloat32Sqrt);
795799
}
796800

797801

798802
void InstructionSelector::VisitFloat64Sqrt(Node* node) {
799-
VisitROFloat(this, node, kSSEFloat64Sqrt);
803+
VisitRO(this, node, kSSEFloat64Sqrt);
800804
}
801805

802806

803807
void InstructionSelector::VisitFloat64RoundDown(Node* node) {
804-
VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown));
808+
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown));
805809
}
806810

807811

808812
void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
809-
VisitRRFloat(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
813+
VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
810814
}
811815

812816

src/compiler/instruction-selector.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -779,13 +779,6 @@ void InstructionSelector::VisitNode(Node* node) {
779779

780780
#if V8_TURBOFAN_BACKEND
781781

782-
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
783-
OperandGenerator g(this);
784-
Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
785-
g.UseRegister(node->InputAt(0)));
786-
}
787-
788-
789782
void InstructionSelector::VisitLoadStackPointer(Node* node) {
790783
OperandGenerator g(this);
791784
Emit(kArchStackPointer, g.DefineAsRegister(node));

src/compiler/machine-operator-reducer.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -646,14 +646,13 @@ Reduction MachineOperatorReducer::ReduceTruncateFloat64ToInt32(Node* node) {
646646
Node* const phi = m.node();
647647
DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
648648
if (phi->OwnedBy(node)) {
649-
// TruncateFloat64ToInt32(Phi[Float64](x1,...,xn))
650-
// => Phi[Int32](TruncateFloat64ToInt32(x1),
649+
// TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn))
650+
// => Phi[Int32](TruncateFloat64ToInt32[mode](x1),
651651
// ...,
652-
// TruncateFloat64ToInt32(xn))
652+
// TruncateFloat64ToInt32[mode](xn))
653653
const int value_input_count = phi->InputCount() - 1;
654654
for (int i = 0; i < value_input_count; ++i) {
655-
Node* input = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
656-
phi->InputAt(i));
655+
Node* input = graph()->NewNode(node->op(), phi->InputAt(i));
657656
// TODO(bmeurer): Reschedule input for reduction once we have Revisit()
658657
// instead of recursing into ReduceTruncateFloat64ToInt32() here.
659658
Reduction reduction = ReduceTruncateFloat64ToInt32(input);

src/compiler/machine-operator.cc

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@ namespace v8 {
1212
namespace internal {
1313
namespace compiler {
1414

15+
std::ostream& operator<<(std::ostream& os, TruncationMode mode) {
16+
switch (mode) {
17+
case TruncationMode::kJavaScript:
18+
return os << "JavaScript";
19+
case TruncationMode::kRoundToZero:
20+
return os << "RoundToZero";
21+
}
22+
UNREACHABLE();
23+
return os;
24+
}
25+
26+
27+
TruncationMode TruncationModeOf(Operator const* op) {
28+
DCHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, op->opcode());
29+
return OpParameter<TruncationMode>(op);
30+
}
31+
32+
1533
std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
1634
switch (kind) {
1735
case kNoWriteBarrier:
@@ -117,7 +135,6 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
117135
V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
118136
V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
119137
V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
120-
V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
121138
V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
122139
V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \
123140
V(Float32Add, Operator::kCommutative, 2, 0, 1) \
@@ -191,6 +208,19 @@ struct MachineOperatorGlobalCache {
191208
PURE_OPTIONAL_OP_LIST(PURE)
192209
#undef PURE
193210

211+
template <TruncationMode kMode>
212+
struct TruncateFloat64ToInt32Operator final
213+
: public Operator1<TruncationMode> {
214+
TruncateFloat64ToInt32Operator()
215+
: Operator1<TruncationMode>(IrOpcode::kTruncateFloat64ToInt32,
216+
Operator::kPure, "TruncateFloat64ToInt32",
217+
1, 0, 0, 1, 0, 0, kMode) {}
218+
};
219+
TruncateFloat64ToInt32Operator<TruncationMode::kJavaScript>
220+
kTruncateFloat64ToInt32JavaScript;
221+
TruncateFloat64ToInt32Operator<TruncationMode::kRoundToZero>
222+
kTruncateFloat64ToInt32RoundToZero;
223+
194224
#define LOAD(Type) \
195225
struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
196226
Load##Type##Operator() \
@@ -268,6 +298,20 @@ PURE_OP_LIST(PURE)
268298
PURE_OPTIONAL_OP_LIST(PURE)
269299
#undef PURE
270300

301+
302+
const Operator* MachineOperatorBuilder::TruncateFloat64ToInt32(
303+
TruncationMode mode) {
304+
switch (mode) {
305+
case TruncationMode::kJavaScript:
306+
return &cache_.kTruncateFloat64ToInt32JavaScript;
307+
case TruncationMode::kRoundToZero:
308+
return &cache_.kTruncateFloat64ToInt32RoundToZero;
309+
}
310+
UNREACHABLE();
311+
return nullptr;
312+
}
313+
314+
271315
const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
272316
switch (rep) {
273317
#define LOAD(Type) \

src/compiler/machine-operator.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ namespace compiler {
1616
struct MachineOperatorGlobalCache;
1717
class Operator;
1818

19+
1920
// For operators that are not supported on all platforms.
20-
class OptionalOperator {
21+
class OptionalOperator final {
2122
public:
2223
explicit OptionalOperator(const Operator* op) : op_(op) {}
2324

@@ -28,9 +29,25 @@ class OptionalOperator {
2829
}
2930

3031
private:
31-
const Operator* op_;
32+
const Operator* const op_;
33+
};
34+
35+
36+
// Supported float64 to int32 truncation modes.
37+
enum class TruncationMode : uint8_t {
38+
kJavaScript, // ES6 section 7.1.5
39+
kRoundToZero // Round towards zero. Implementation defined for NaN and ovf.
3240
};
3341

42+
V8_INLINE size_t hash_value(TruncationMode mode) {
43+
return static_cast<uint8_t>(mode);
44+
}
45+
46+
std::ostream& operator<<(std::ostream&, TruncationMode);
47+
48+
TruncationMode TruncationModeOf(Operator const*);
49+
50+
3451
// Supported write barrier modes.
3552
enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
3653

@@ -175,7 +192,7 @@ class MachineOperatorBuilder final : public ZoneObject {
175192
// These operators truncate numbers, both changing the representation of
176193
// the number and mapping multiple input values onto the same output value.
177194
const Operator* TruncateFloat64ToFloat32();
178-
const Operator* TruncateFloat64ToInt32(); // JavaScript semantics.
195+
const Operator* TruncateFloat64ToInt32(TruncationMode);
179196
const Operator* TruncateInt64ToInt32();
180197

181198
// Floating point operators always operate with IEEE 754 round-to-nearest

src/compiler/mips/instruction-selector-mips.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,17 @@ void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
391391
}
392392

393393

394+
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
395+
switch (TruncationModeOf(node->op())) {
396+
case TruncationMode::kJavaScript:
397+
return VisitRR(this, kArchTruncateDoubleToI, node);
398+
case TruncationMode::kRoundToZero:
399+
return VisitRR(this, kMipsTruncWD, node);
400+
}
401+
UNREACHABLE();
402+
}
403+
404+
394405
void InstructionSelector::VisitFloat32Add(Node* node) {
395406
VisitRRR(this, kMipsAddS, node);
396407
}

src/compiler/mips64/instruction-selector-mips64.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,17 @@ void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
539539
}
540540

541541

542+
void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
543+
switch (TruncationModeOf(node->op())) {
544+
case TruncationMode::kJavaScript:
545+
return VisitRR(this, kArchTruncateDoubleToI, node);
546+
case TruncationMode::kRoundToZero:
547+
return VisitRR(this, kMips64TruncWD, node);
548+
}
549+
UNREACHABLE();
550+
}
551+
552+
542553
void InstructionSelector::VisitFloat32Add(Node* node) {
543554
VisitRRR(this, kMips64AddS, node);
544555
}

src/compiler/raw-machine-assembler.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ class RawMachineAssembler : public GraphBuilder {
412412
Node* TruncateFloat64ToFloat32(Node* a) {
413413
return NewNode(machine()->TruncateFloat64ToFloat32(), a);
414414
}
415-
Node* TruncateFloat64ToInt32(Node* a) {
416-
return NewNode(machine()->TruncateFloat64ToInt32(), a);
415+
Node* TruncateFloat64ToInt32(TruncationMode mode, Node* a) {
416+
return NewNode(machine()->TruncateFloat64ToInt32(mode), a);
417417
}
418418
Node* TruncateInt64ToInt32(Node* a) {
419419
return NewNode(machine()->TruncateInt64ToInt32(), a);

0 commit comments

Comments
 (0)