From: verwaest@chromium.org Date: Tue, 4 Jun 2013 12:26:39 +0000 (+0000) Subject: Infer the range of XOR as limited by the highest possible changed bit. X-Git-Tag: upstream/4.7.83~14022 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=277ec5d7b2bc02267756a4c16d5f75df49aa48a3;p=platform%2Fupstream%2Fv8.git Infer the range of XOR as limited by the highest possible changed bit. R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/16361003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14933 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 3b18dab..1943cce 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -2310,7 +2310,39 @@ void HMathMinMax::InferRepresentation(HInferRepresentation* h_infer) { Range* HBitwise::InferRange(Zone* zone) { - if (op() == Token::BIT_XOR) return HValue::InferRange(zone); + if (op() == Token::BIT_XOR) { + if (left()->HasRange() && right()->HasRange()) { + // The maximum value has the high bit, and all bits below, set: + // (1 << high) - 1. + // If the range can be negative, the minimum int is a negative number with + // the high bit, and all bits below, unset: + // -(1 << high). + // If it cannot be negative, conservatively choose 0 as minimum int. + int64_t left_upper = left()->range()->upper(); + int64_t left_lower = left()->range()->lower(); + int64_t right_upper = right()->range()->upper(); + int64_t right_lower = right()->range()->lower(); + + if (left_upper < 0) left_upper = ~left_upper; + if (left_lower < 0) left_lower = ~left_lower; + if (right_upper < 0) right_upper = ~right_upper; + if (right_lower < 0) right_lower = ~right_lower; + + // Find the highest used bit. + int high = static_cast(log2(left_upper)); + high = Max(high, static_cast(log2(left_lower))); + high = Max(high, static_cast(log2(right_upper))); + high = Max(high, static_cast(log2(right_lower))); + + int64_t limit = 1; + limit <<= high + 1; + int32_t min = (left()->range()->CanBeNegative() || + right()->range()->CanBeNegative()) + ? static_cast(-limit) : 0; + return new(zone) Range(min, static_cast(limit - 1)); + } + return HValue::InferRange(zone); + } const int32_t kDefaultMask = static_cast(0xffffffff); int32_t left_mask = (left()->range() != NULL) ? left()->range()->Mask()