Commit 6b565a04 authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

[x64] Narrow operand for comparing WordAnd with a constant

In x64, the result of WordAnd with a positive integer constant is known
to be sign(zero)-extended. Comparing this result with another positive
integer constant can have narrowed op according to the value of the
constants.

This CL do this narrow for WordAnd. It also makes the narrow in Word
comparison to deal with X64Cmp and X64Test.

Bug: v8:12650
Change-Id: I77f4ada9a9f94d78b3a78911e279a647c561cce4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3462081Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Cr-Commit-Position: refs/heads/main@{#79361}
parent 960cac97
...@@ -2092,9 +2092,14 @@ MachineType MachineTypeForNarrow(Node* node, Node* hint_node) { ...@@ -2092,9 +2092,14 @@ MachineType MachineTypeForNarrow(Node* node, Node* hint_node) {
return hint; return hint;
} }
} else if (hint == MachineType::Int32()) { } else if (hint == MachineType::Int32()) {
return hint; if (constant >= std::numeric_limits<int32_t>::min() &&
constant <= std::numeric_limits<int32_t>::max()) {
return hint;
}
} else if (hint == MachineType::Uint32()) { } else if (hint == MachineType::Uint32()) {
if (constant >= 0) return hint; if (constant >= std::numeric_limits<uint32_t>::min() &&
constant <= std::numeric_limits<uint32_t>::max())
return hint;
} }
} }
} }
...@@ -2104,21 +2109,81 @@ MachineType MachineTypeForNarrow(Node* node, Node* hint_node) { ...@@ -2104,21 +2109,81 @@ MachineType MachineTypeForNarrow(Node* node, Node* hint_node) {
: MachineType::None(); : MachineType::None();
} }
bool IsIntConstant(Node* node) {
return node->opcode() == IrOpcode::kInt32Constant ||
node->opcode() == IrOpcode::kInt64Constant;
}
bool IsWordAnd(Node* node) {
return node->opcode() == IrOpcode::kWord32And ||
node->opcode() == IrOpcode::kWord64And;
}
// The result of WordAnd with a positive interger constant in X64 is known to
// be sign(zero)-extended. Comparing this result with another positive interger
// constant can have narrowed operand.
MachineType MachineTypeForNarrowWordAnd(Node* and_node, Node* constant_node) {
Node* and_left = and_node->InputAt(0);
Node* and_right = and_node->InputAt(1);
Node* and_constant_node = IsIntConstant(and_right)
? and_right
: IsIntConstant(and_left) ? and_left : nullptr;
if (and_constant_node != nullptr) {
int64_t and_constant =
and_constant_node->opcode() == IrOpcode::kInt32Constant
? OpParameter<int32_t>(and_constant_node->op())
: OpParameter<int64_t>(and_constant_node->op());
int64_t cmp_constant = constant_node->opcode() == IrOpcode::kInt32Constant
? OpParameter<int32_t>(constant_node->op())
: OpParameter<int64_t>(constant_node->op());
if (and_constant >= 0 && cmp_constant >= 0) {
int64_t constant =
and_constant > cmp_constant ? and_constant : cmp_constant;
if (constant <= std::numeric_limits<int8_t>::max()) {
return MachineType::Int8();
} else if (constant <= std::numeric_limits<uint8_t>::max()) {
return MachineType::Uint8();
} else if (constant <= std::numeric_limits<int16_t>::max()) {
return MachineType::Int16();
} else if (constant <= std::numeric_limits<uint16_t>::max()) {
return MachineType::Uint16();
} else if (constant <= std::numeric_limits<int32_t>::max()) {
return MachineType::Int32();
} else if (constant <= std::numeric_limits<uint32_t>::max()) {
return MachineType::Uint32();
}
}
}
return MachineType::None();
}
// Tries to match the size of the given opcode to that of the operands, if // Tries to match the size of the given opcode to that of the operands, if
// possible. // possible.
InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left,
Node* right, FlagsContinuation* cont) { Node* right, FlagsContinuation* cont) {
// TODO(epertoso): we can probably get some size information out phi nodes. MachineType left_type = MachineType::None();
// If the load representations don't match, both operands will be MachineType right_type = MachineType::None();
// zero/sign-extended to 32bit. if (IsWordAnd(left) && IsIntConstant(right)) {
MachineType left_type = MachineTypeForNarrow(left, right); left_type = MachineTypeForNarrowWordAnd(left, right);
MachineType right_type = MachineTypeForNarrow(right, left); right_type = left_type;
} else if (IsWordAnd(right) && IsIntConstant(left)) {
right_type = MachineTypeForNarrowWordAnd(right, left);
left_type = right_type;
} else {
// TODO(epertoso): we can probably get some size information out phi nodes.
// If the load representations don't match, both operands will be
// zero/sign-extended to 32bit.
left_type = MachineTypeForNarrow(left, right);
right_type = MachineTypeForNarrow(right, left);
}
if (left_type == right_type) { if (left_type == right_type) {
switch (left_type.representation()) { switch (left_type.representation()) {
case MachineRepresentation::kBit: case MachineRepresentation::kBit:
case MachineRepresentation::kWord8: { case MachineRepresentation::kWord8: {
if (opcode == kX64Test32) return kX64Test8; if (opcode == kX64Test || opcode == kX64Test32) return kX64Test8;
if (opcode == kX64Cmp32) { if (opcode == kX64Cmp || opcode == kX64Cmp32) {
if (left_type.semantic() == MachineSemantic::kUint32) { if (left_type.semantic() == MachineSemantic::kUint32) {
cont->OverwriteUnsignedIfSigned(); cont->OverwriteUnsignedIfSigned();
} else { } else {
...@@ -2129,8 +2194,8 @@ InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, ...@@ -2129,8 +2194,8 @@ InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left,
break; break;
} }
case MachineRepresentation::kWord16: case MachineRepresentation::kWord16:
if (opcode == kX64Test32) return kX64Test16; if (opcode == kX64Test || opcode == kX64Test32) return kX64Test16;
if (opcode == kX64Cmp32) { if (opcode == kX64Cmp || opcode == kX64Cmp32) {
if (left_type.semantic() == MachineSemantic::kUint32) { if (left_type.semantic() == MachineSemantic::kUint32) {
cont->OverwriteUnsignedIfSigned(); cont->OverwriteUnsignedIfSigned();
} else { } else {
...@@ -2139,6 +2204,17 @@ InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, ...@@ -2139,6 +2204,17 @@ InstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left,
return kX64Cmp16; return kX64Cmp16;
} }
break; break;
case MachineRepresentation::kWord32:
if (opcode == kX64Test) return kX64Test32;
if (opcode == kX64Cmp) {
if (left_type.semantic() == MachineSemantic::kUint32) {
cont->OverwriteUnsignedIfSigned();
} else {
CHECK_EQ(MachineSemantic::kInt32, left_type.semantic());
}
return kX64Cmp32;
}
break;
#ifdef V8_COMPRESS_POINTERS #ifdef V8_COMPRESS_POINTERS
case MachineRepresentation::kTaggedSigned: case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kTaggedPointer: case MachineRepresentation::kTaggedPointer:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment