Commit cb3645fe authored by verwaest@chromium.org's avatar verwaest@chromium.org

Infer the range of Math.abs

R=jkummerow@chromium.org, svenpanne@chromium.org

Review URL: https://chromiumcodereview.appspot.com/16268009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14996 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 72098711
......@@ -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);
......
......@@ -271,6 +271,10 @@ class Range: public ZoneObject {
bool IsInSmiRange() const {
return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
}
void ClampToSmi() {
lower_ = Max(lower_, Smi::kMinValue);
upper_ = Min(upper_, Smi::kMaxValue);
}
void KeepOrder();
#ifdef DEBUG
void Verify() const;
......@@ -2644,6 +2648,8 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
}
}
virtual Range* InferRange(Zone* zone);
virtual HValue* Canonicalize();
BuiltinFunctionId op() const { return op_; }
......
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