Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index d3f1a9e09024c8f1643eb53bddc3b595b3953d3e..8d4211f1f0487a891d57fff958c4940c04ea6981 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -1308,6 +1308,29 @@ 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_lower = lower == kMinInt ? kMaxInt : abs(kMinInt); |
|
Jakob Kummerow
2013/06/07 09:02:33
I think you need to do this same trick for abs_upp
|
| + 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); |