| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index d3f1a9e09024c8f1643eb53bddc3b595b3953d3e..d6a3f995f0e8e6baeb0418b303cc5aa6ae90c5bf 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1308,6 +1308,30 @@ const char* HUnaryMathOperation::OpName() const {
|
| }
|
|
|
|
|
| +Range* HUnaryMathOperation::InferRange(Zone* zone) {
|
| + Representation r = representation();
|
| + if (r.IsSmiOrInteger32() && value()->HasRange()) {
|
| + if (op() == kMathAbs) {
|
| + int upper = value()->range()->upper();
|
| + int lower = value()->range()->lower();
|
| + bool spans_zero = value()->range()->CanBeZero();
|
| + // Math.abs(kMinInt) overflows its representation, on which the
|
| + // instruction deopts. Hence clamp it to kMaxInt.
|
| + int abs_upper = upper == kMinInt ? kMaxInt : abs(upper);
|
| + int abs_lower = lower == kMinInt ? kMaxInt : abs(lower);
|
| + Range* result =
|
| + new(zone) Range(spans_zero ? 0 : Min(abs_lower, abs_upper),
|
| + Max(abs_lower, abs_upper));
|
| + // In case of Smi representation, clamp Math.abs(Smi::kMinValue) to
|
| + // Smi::kMaxValue.
|
| + if (r.IsSmi()) result->ClampToSmi();
|
| + return result;
|
| + }
|
| + }
|
| + return HValue::InferRange(zone);
|
| +}
|
| +
|
| +
|
| void HUnaryMathOperation::PrintDataTo(StringStream* stream) {
|
| const char* name = OpName();
|
| stream->Add("%s ", name);
|
|
|