summaryrefslogtreecommitdiff
path: root/chromium/v8/src/compiler/machine-operator-reducer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/compiler/machine-operator-reducer.cc')
-rw-r--r--chromium/v8/src/compiler/machine-operator-reducer.cc57
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());