Improve range analysis for modulo operations.

R=mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14884 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 09959efe
......@@ -1811,8 +1811,18 @@ Range* HMod::InferRange(Zone* zone) {
if (representation().IsInteger32()) {
Range* a = left()->range();
Range* b = right()->range();
Range* result = new(zone) Range();
if (a->CanBeMinusZero() || a->CanBeNegative()) {
// The magnitude of the modulus is bounded by the right operand. Note that
// apart for the cases involving kMinInt, the calculation below is the same
// as Max(Abs(b->lower()), Abs(b->upper())) - 1.
int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
// The result of the modulo operation has the sign of its left operand.
bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
a->CanBePositive() ? positive_bound : 0);
if (left_can_be_negative) {
result->set_can_be_minus_zero(true);
}
......
......@@ -263,6 +263,7 @@ class Range: public ZoneObject {
bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
bool CanBeNegative() const { return lower_ < 0; }
bool CanBePositive() const { return upper_ > 0; }
bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
bool IsMostGeneric() const {
return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
......
......@@ -232,6 +232,13 @@ T Min(T a, T b) {
}
// Returns the negative absolute value of its argument.
template <typename T>
T NegAbs(T a) {
return a < 0 ? a : -a;
}
inline int StrLength(const char* string) {
size_t length = strlen(string);
ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
......
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