| Index: runtime/vm/flow_graph_range_analysis.cc
|
| diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
|
| index f731c5539ca2586eb3dd9237f49d54e8a11f60e7..0f87533963516dfa48f77bb653950b4f690a644f 100644
|
| --- a/runtime/vm/flow_graph_range_analysis.cc
|
| +++ b/runtime/vm/flow_graph_range_analysis.cc
|
| @@ -2427,6 +2427,32 @@ bool Range::And(const Range* left_range,
|
| }
|
|
|
|
|
| +static int BitSize(const Range* range) {
|
| + const int64_t min = Range::ConstantMin(range).ConstantValue();
|
| + const int64_t max = Range::ConstantMax(range).ConstantValue();
|
| + return Utils::Maximum(Utils::BitLength(min), Utils::BitLength(max));
|
| +}
|
| +
|
| +
|
| +void Range::Xor(const Range* left_range,
|
| + const Range* right_range,
|
| + RangeBoundary* result_min,
|
| + RangeBoundary* result_max) {
|
| + const int bitsize =
|
| + Utils::Maximum(BitSize(left_range), BitSize(right_range));
|
| +
|
| + if (left_range->IsPositive() && right_range->IsPositive()) {
|
| + *result_min = RangeBoundary::FromConstant(0);
|
| + } else {
|
| + *result_min = RangeBoundary::FromConstant(
|
| + static_cast<int64_t>(-1) << bitsize);
|
| + }
|
| +
|
| + *result_max = RangeBoundary::FromConstant(
|
| + (static_cast<uint64_t>(1) << bitsize) - 1);
|
| +}
|
| +
|
| +
|
| static bool IsArrayLength(Definition* defn) {
|
| if (defn == NULL) {
|
| return false;
|
| @@ -2595,12 +2621,18 @@ void Range::BinaryOp(const Token::Kind op,
|
| Range::Shr(left_range, right_range, &min, &max);
|
| break;
|
| }
|
| +
|
| case Token::kBIT_AND:
|
| if (!Range::And(left_range, right_range, &min, &max)) {
|
| *result = Range::Full(RangeBoundary::kRangeBoundaryInt64);
|
| return;
|
| }
|
| break;
|
| +
|
| + case Token::kBIT_XOR:
|
| + Range::Xor(left_range, right_range, &min, &max);
|
| + break;
|
| +
|
| default:
|
| *result = Range::Full(RangeBoundary::kRangeBoundaryInt64);
|
| return;
|
|
|