Assume signed for converting to word32/float64 unless use or output is explicitly unsigned.

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
titzer@chromium.org 2014-08-12 08:09:24 +00:00
parent f3ccf2d51b
commit 81047ea644
2 changed files with 21 additions and 33 deletions

View File

@ -88,7 +88,7 @@ class RepresentationChanger {
} else if (use_type & rFloat64) {
return GetFloat64RepresentationFor(node, output_type);
} else if (use_type & rWord32) {
return GetWord32RepresentationFor(node, output_type);
return GetWord32RepresentationFor(node, output_type, use_type & tUint32);
} else if (use_type & rBit) {
return GetBitRepresentationFor(node, output_type);
} else if (use_type & rWord64) {
@ -165,10 +165,8 @@ class RepresentationChanger {
if (output_type & rWord32) {
if (output_type & tUint32) {
op = machine()->ChangeUint32ToFloat64();
} else if (output_type & tInt32) {
op = machine()->ChangeInt32ToFloat64();
} else {
return TypeError(node, output_type, rFloat64);
op = machine()->ChangeInt32ToFloat64();
}
} else if (output_type & rTagged) {
op = simplified()->ChangeTaggedToFloat64();
@ -178,22 +176,23 @@ class RepresentationChanger {
return jsgraph()->graph()->NewNode(op, node);
}
Node* GetWord32RepresentationFor(Node* node, RepTypeUnion output_type) {
Node* GetWord32RepresentationFor(Node* node, RepTypeUnion output_type,
bool use_unsigned) {
// Eagerly fold representation changes for constants.
switch (node->opcode()) {
case IrOpcode::kInt32Constant:
return node; // No change necessary.
case IrOpcode::kNumberConstant:
case IrOpcode::kFloat64Constant: {
if (output_type & tUint32) {
int32_t value = static_cast<int32_t>(
static_cast<uint32_t>(ValueOf<double>(node->op())));
return jsgraph()->Int32Constant(value);
} else if (output_type & tInt32) {
int32_t value = FastD2I(ValueOf<double>(node->op()));
return jsgraph()->Int32Constant(value);
double value = ValueOf<double>(node->op());
if (value < 0) {
DCHECK(IsInt32Double(value));
int32_t iv = static_cast<int32_t>(value);
return jsgraph()->Int32Constant(iv);
} else {
return TypeError(node, output_type, rWord32);
DCHECK(IsUint32Double(value));
int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
return jsgraph()->Int32Constant(iv);
}
}
default:
@ -202,20 +201,16 @@ class RepresentationChanger {
// Select the correct X -> Word32 operator.
Operator* op = NULL;
if (output_type & rFloat64) {
if (output_type & tUint32) {
if (output_type & tUint32 || use_unsigned) {
op = machine()->ChangeFloat64ToUint32();
} else if (output_type & tInt32) {
op = machine()->ChangeFloat64ToInt32();
} else {
return TypeError(node, output_type, rWord32);
op = machine()->ChangeFloat64ToInt32();
}
} else if (output_type & rTagged) {
if (output_type & tUint32) {
if (output_type & tUint32 || use_unsigned) {
op = simplified()->ChangeTaggedToUint32();
} else if (output_type & tInt32) {
op = simplified()->ChangeTaggedToInt32();
} else {
return TypeError(node, output_type, rWord32);
op = simplified()->ChangeTaggedToInt32();
}
} else if (output_type & rBit) {
return node; // Sloppy comparison -> word32.

View File

@ -192,18 +192,11 @@ TEST(SingleChanges) {
TEST(SignednessInWord32) {
RepresentationChangerTester r;
// TODO(titzer): these are currently type errors because the output type is
// not specified. Maybe the RepresentationChanger should assume anything to or
// from {rWord32} is {tInt32}, i.e. signed, if not it is explicitly otherwise?
r.CheckTypeError(rTagged, rWord32 | tInt32);
r.CheckTypeError(rTagged, rWord32 | tUint32);
r.CheckTypeError(rWord32, rFloat64);
r.CheckTypeError(rFloat64, rWord32);
// CheckChange(IrOpcode::kChangeTaggedToInt32, rTagged, rWord32 | tInt32);
// CheckChange(IrOpcode::kChangeTaggedToUint32, rTagged, rWord32 | tUint32);
// CheckChange(IrOpcode::kChangeInt32ToFloat64, rWord32, rFloat64);
// CheckChange(IrOpcode::kChangeFloat64ToInt32, rFloat64, rWord32);
// TODO(titzer): assume that uses of a word32 without a sign mean tInt32.
CheckChange(IrOpcode::kChangeTaggedToInt32, rTagged, rWord32 | tInt32);
CheckChange(IrOpcode::kChangeTaggedToUint32, rTagged, rWord32 | tUint32);
CheckChange(IrOpcode::kChangeInt32ToFloat64, rWord32, rFloat64);
CheckChange(IrOpcode::kChangeFloat64ToInt32, rFloat64, rWord32);
}