diff options
Diffstat (limited to 'chromium/v8/src/compiler/machine-operator-reducer.cc')
-rw-r--r-- | chromium/v8/src/compiler/machine-operator-reducer.cc | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/chromium/v8/src/compiler/machine-operator-reducer.cc b/chromium/v8/src/compiler/machine-operator-reducer.cc index 5d61dfac6ab..3e2bacf90a6 100644 --- a/chromium/v8/src/compiler/machine-operator-reducer.cc +++ b/chromium/v8/src/compiler/machine-operator-reducer.cc @@ -1718,11 +1718,21 @@ Reduction MachineOperatorReducer::ReduceWordNAnd(Node* node) { namespace { // Represents an operation of the form `(source & mask) == masked_value`. +// where each bit set in masked_value also has to be set in mask. struct BitfieldCheck { - Node* source; - uint32_t mask; - uint32_t masked_value; - bool truncate_from_64_bit; + Node* const source; + uint32_t const mask; + uint32_t const masked_value; + bool const truncate_from_64_bit; + + BitfieldCheck(Node* source, uint32_t mask, uint32_t masked_value, + bool truncate_from_64_bit) + : source(source), + mask(mask), + masked_value(masked_value), + truncate_from_64_bit(truncate_from_64_bit) { + CHECK_EQ(masked_value & ~mask, 0); + } static base::Optional<BitfieldCheck> Detect(Node* node) { // There are two patterns to check for here: @@ -1737,14 +1747,16 @@ struct BitfieldCheck { if (eq.left().IsWord32And()) { Uint32BinopMatcher mand(eq.left().node()); if (mand.right().HasResolvedValue() && eq.right().HasResolvedValue()) { - BitfieldCheck result{mand.left().node(), mand.right().ResolvedValue(), - eq.right().ResolvedValue(), false}; + uint32_t mask = mand.right().ResolvedValue(); + uint32_t masked_value = eq.right().ResolvedValue(); + if ((masked_value & ~mask) != 0) return {}; if (mand.left().IsTruncateInt64ToInt32()) { - result.truncate_from_64_bit = true; - result.source = - NodeProperties::GetValueInput(mand.left().node(), 0); + return BitfieldCheck( + NodeProperties::GetValueInput(mand.left().node(), 0), mask, + masked_value, true); + } else { + return BitfieldCheck(mand.left().node(), mask, masked_value, false); } - return result; } } } else { @@ -1836,17 +1848,20 @@ Reduction MachineOperatorReducer::ReduceWord64And(Node* node) { } Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { + // Recognize rotation, we are matching and transforming as follows: + // x << y | x >>> (32 - y) => x ror (32 - y) + // x << (32 - y) | x >>> y => x ror y + // x << y ^ x >>> (32 - y) => x ror (32 - y) if y & 31 != 0 + // x << (32 - y) ^ x >>> y => x ror y if y & 31 != 0 + // (As well as the commuted forms.) + // Note the side condition for XOR: the optimization doesn't hold for + // multiples of 32. + DCHECK(IrOpcode::kWord32Or == node->opcode() || IrOpcode::kWord32Xor == node->opcode()); Int32BinopMatcher m(node); Node* shl = nullptr; Node* shr = nullptr; - // Recognize rotation, we are matching: - // * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y - // * x << (32 - y) | x >>> y => x ror y - // * x << y ^ x >>> (32 - y) => x ror (32 - y), i.e. x rol y - // * x << (32 - y) ^ x >>> y => x ror y - // as well as their commuted form. if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { shl = m.left().node(); shr = m.right().node(); @@ -1863,8 +1878,13 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { if (mshl.right().HasResolvedValue() && mshr.right().HasResolvedValue()) { // Case where y is a constant. - if (mshl.right().ResolvedValue() + mshr.right().ResolvedValue() != 32) + if (mshl.right().ResolvedValue() + mshr.right().ResolvedValue() != 32) { return NoChange(); + } + if (node->opcode() == IrOpcode::kWord32Xor && + (mshl.right().ResolvedValue() & 31) == 0) { + return NoChange(); + } } else { Node* sub = nullptr; Node* y = nullptr; @@ -1880,6 +1900,9 @@ Reduction MachineOperatorReducer::TryMatchWord32Ror(Node* node) { Int32BinopMatcher msub(sub); if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); + if (node->opcode() == IrOpcode::kWord32Xor) { + return NoChange(); // Can't guarantee y & 31 != 0. + } } node->ReplaceInput(0, mshl.left().node()); |