| Index: src/compiler/machine-operator-reducer.cc
|
| diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
|
| index ba0b7a1893b1fa0f6ea1b126c5cf454c905a4fdd..d94ffff6f805987e57526c91bb0149bbdb125ff5 100644
|
| --- a/src/compiler/machine-operator-reducer.cc
|
| +++ b/src/compiler/machine-operator-reducer.cc
|
| @@ -832,6 +832,24 @@ Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
|
| return ReplaceInt32(m.left().Value() & m.right().Value());
|
| }
|
| if (m.LeftEqualsRight()) return Replace(m.left().node()); // x & x => x
|
| + if (m.right().HasValue()) {
|
| + int32_t const mask = m.right().Value();
|
| + Type* left_type = NodeProperties::GetBounds(m.left().node()).upper;
|
| + if (left_type->IsRange() && left_type->Min() >= kMinInt &&
|
| + left_type->Max() <= kMaxInt) {
|
| + // If the left hand side known one bits and unknown bits are preserve by
|
| + // the mask then the bitwise-and operation can be eliminated.
|
| + uint32_t left_min = left_type->Min(), left_max = left_type->Max();
|
| + uint32_t changes = left_min ^ left_max;
|
| + unsigned known_count = base::bits::CountLeadingZeros32(changes);
|
| + uint32_t known_mask = known_count > 0 ? -1 << (32 - known_count) : 0;
|
| + uint32_t known_ones = left_min & known_mask;
|
| + if ((known_ones & mask) == known_ones &&
|
| + (~known_mask & mask) == ~known_mask) { // x & K => x
|
| + return Replace(m.left().node());
|
| + }
|
| + }
|
| + }
|
| if (m.left().IsWord32And() && m.right().HasValue()) {
|
| Int32BinopMatcher mleft(m.left().node());
|
| if (mleft.right().HasValue()) { // (x & K) & K => x & K
|
|
|