[turbofan] Reduce redundant ChangeInt32ToInt64

If Int64Constant[value] can be casted from an Int32Constant(value>=int32_min and value<=int32_max), we can reduce the redundant Int32ToInt64:
-------------------------------------------------
Int64LessThan(Int32ToInt64(a), Int64Constant[value])
====>
Int32LessThan(a,Int32Constant[value])
-------------------------------------------------

Otherwise, if value<int32_min:
-------------------------------------------------
Int64LessThan(Int32ToInt64(a), Int64Constant[value])
====>
# Always false
Int32Constant[0]
-------------------------------------------------

If value>int32_max:
-------------------------------------------------
Int64LessThan(Int32ToInt64(a), Int64Constant[value])
====>
# Always true
Int32Constant[1]
-------------------------------------------------

Change-Id: Id0de1dacad99d1f17b8e652472c2f4bc9ae79c15
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3967835
Commit-Queue: Jianxiao Lu <jianxiao.lu@intel.com>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84281}
This commit is contained in:
JianxiaoLuIntel 2022-11-16 13:22:30 +08:00 committed by V8 LUCI CQ
parent ad46317053
commit ae042381b9
2 changed files with 167 additions and 5 deletions

View File

@ -194,7 +194,6 @@ MachineOperatorReducer::MachineOperatorReducer(Editor* editor,
MachineOperatorReducer::~MachineOperatorReducer() = default;
Node* MachineOperatorReducer::Float32Constant(float value) {
return graph()->NewNode(common()->Float32Constant(value));
}
@ -639,13 +638,13 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
Float64BinopMatcher m(node);
if (allow_signalling_nan_ && m.right().Is(1))
return Replace(m.left().node()); // x * 1.0 => x
if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x
if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x
node->ReplaceInput(0, Float64Constant(-0.0));
node->ReplaceInput(1, m.left().node());
NodeProperties::ChangeOp(node, machine()->Float64Sub());
return Changed(node);
}
if (m.right().IsNaN()) { // x * NaN => NaN
if (m.right().IsNaN()) { // x * NaN => NaN
return ReplaceFloat64(SilenceNaN(m.right().ResolvedValue()));
}
if (m.IsFoldable()) { // K * K => K (K stands for arbitrary constants)
@ -664,7 +663,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
if (allow_signalling_nan_ && m.right().Is(1))
return Replace(m.left().node()); // x / 1.0 => x
// TODO(ahaas): We could do x / 1.0 = x if we knew that x is not an sNaN.
if (m.right().IsNaN()) { // x / NaN => NaN
if (m.right().IsNaN()) { // x / NaN => NaN
return ReplaceFloat64(SilenceNaN(m.right().ResolvedValue()));
}
if (m.left().IsNaN()) { // NaN / x => NaN
@ -1759,6 +1758,132 @@ Reduction MachineOperatorReducer::ReduceWord64Comparisons(Node* node) {
}
}
/*
If Int64Constant(c) can be casted from an Int32Constant:
-------------------------------------------------
Int64LessThan(Int32ToInt64(a), Int64Constant(c))
====>
Int32LessThan(a,Int32Constant(c))
-------------------------------------------------
*/
if (node->opcode() == IrOpcode::kInt64LessThan ||
node->opcode() == IrOpcode::kInt64LessThanOrEqual) {
// Int64LessThan(Int32ToInt64(a), Int64Constant(c))
if (m.left().IsChangeInt32ToInt64() && m.right().HasResolvedValue()) {
int64_t right_value = static_cast<int64_t>(m.right().ResolvedValue());
// Int64Constant can be casted from an Int32Constant
if (right_value == static_cast<int32_t>(right_value)) {
const Operator* new_op;
if (node->opcode() == IrOpcode::kInt64LessThan) {
new_op = machine()->Int32LessThan();
} else {
new_op = machine()->Int32LessThanOrEqual();
}
NodeProperties::ChangeOp(node, new_op);
node->ReplaceInput(0, m.left().InputAt(0));
node->ReplaceInput(1, Int32Constant(static_cast<int32_t>(right_value)));
return Changed(node);
} else if (right_value < std::numeric_limits<int32_t>::min()) {
// left > right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(0));
return Changed(node);
} else if (right_value > std::numeric_limits<int32_t>::max()) {
// left < right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(1));
return Changed(node);
}
}
// Int64LessThan(Int64Constant(c), Int32ToInt64(a))
if (m.right().IsChangeInt32ToInt64() && m.left().HasResolvedValue()) {
int64_t left_value = static_cast<int64_t>(m.left().ResolvedValue());
// Int64Constant can be casted from an Int32Constant
if (left_value == static_cast<int32_t>(left_value)) {
const Operator* new_op;
if (node->opcode() == IrOpcode::kInt64LessThan) {
new_op = machine()->Int32LessThan();
} else {
new_op = machine()->Int32LessThanOrEqual();
}
NodeProperties::ChangeOp(node, new_op);
node->ReplaceInput(1, m.right().InputAt(0));
node->ReplaceInput(0, Int32Constant(static_cast<int32_t>(left_value)));
return Changed(node);
} else if (left_value < std::numeric_limits<int32_t>::min()) {
// left < right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(1));
return Changed(node);
} else if (left_value > std::numeric_limits<int32_t>::max()) {
// left > right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(0));
return Changed(node);
}
}
}
/*
If Uint64Constant(c) can be casted from an Uint32Constant:
-------------------------------------------------
Uint64LessThan(Uint32ToInt64(a), Uint64Constant(c))
====>
Uint32LessThan(a,Uint32Constant(c))
-------------------------------------------------
*/
if (node->opcode() == IrOpcode::kUint64LessThan ||
node->opcode() == IrOpcode::kUint64LessThanOrEqual) {
// Uint64LessThan(Uint32ToInt64(a), Uint32Constant(c))
if (m.left().IsChangeUint32ToUint64() && m.right().HasResolvedValue()) {
uint64_t right_value = static_cast<uint64_t>(m.right().ResolvedValue());
// Uint64Constant can be casted from an Uint32Constant
if (right_value == static_cast<uint32_t>(right_value)) {
const Operator* new_op;
if (node->opcode() == IrOpcode::kUint64LessThan) {
new_op = machine()->Uint32LessThan();
} else {
new_op = machine()->Uint32LessThanOrEqual();
}
NodeProperties::ChangeOp(node, new_op);
node->ReplaceInput(0, m.left().InputAt(0));
node->ReplaceInput(1,
Uint32Constant(static_cast<uint32_t>(right_value)));
return Changed(node);
} else {
// left < right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(1));
return Changed(node);
}
}
// Uint64LessThan(Uint64Constant(c), Uint32ToInt64(a))
if (m.right().IsChangeUint32ToUint64() && m.left().HasResolvedValue()) {
uint64_t left_value = static_cast<uint64_t>(m.left().ResolvedValue());
// Uint64Constant can be casted from an Uint32Constant
if (left_value == static_cast<uint32_t>(left_value)) {
const Operator* new_op;
if (node->opcode() == IrOpcode::kUint64LessThan) {
new_op = machine()->Uint32LessThan();
} else {
new_op = machine()->Uint32LessThanOrEqual();
}
NodeProperties::ChangeOp(node, new_op);
node->ReplaceInput(1, m.right().InputAt(0));
node->ReplaceInput(0,
Uint32Constant(static_cast<uint32_t>(left_value)));
return Changed(node);
} else {
// left > right always
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(0));
return Changed(node);
}
}
}
return NoChange();
}
@ -1984,7 +2109,7 @@ Reduction MachineOperatorReducer::ReduceWordNAnd(Node* node) {
return a.ReplaceIntN(0);
}
}
if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP
if (m.left().IsComparison() && m.right().Is(1)) { // CMP & 1 => CMP
return Replace(m.left().node());
}
if (m.IsFoldable()) { // K & K => K (K stands for arbitrary constants)
@ -2425,6 +2550,30 @@ Reduction MachineOperatorReducer::ReduceWord64Equal(Node* node) {
node->ReplaceInput(1, Uint64Constant(replacements->second));
return Changed(node);
}
/*
If Int64Constant(c) can be casted from an Int32Constant:
-------------------------------------------------
Word64Equal(Int32ToInt64(a), Int64Constant(c))
====>
Word32Equal(a,Int32Constant(c))
-------------------------------------------------
*/
if (m.left().IsChangeInt32ToInt64()) {
int64_t right_value = m.right().ResolvedValue();
// Int64Constant can be casted from an Int32Constant
if (right_value == static_cast<int32_t>(right_value)) {
NodeProperties::ChangeOp(node, machine()->Word32Equal());
node->ReplaceInput(0, m.left().InputAt(0));
node->ReplaceInput(1, Int32Constant(static_cast<int32_t>(right_value)));
return Changed(node);
} else {
// Always false, change node op to zero(false).
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Int32Constant(0));
return Changed(node);
}
}
}
return NoChange();

View File

@ -1149,6 +1149,19 @@ class MachineOptimizationReducer : public Next {
rep_w);
}
}
// Map 64bit to 32bit equals.
if (rep_w == WordRepresentation::Word64()) {
base::Optional<bool> left_sign_extended;
base::Optional<bool> right_sign_extended;
if (IsWord32ConvertedToWord64(left, &left_sign_extended) &&
IsWord32ConvertedToWord64(right, &right_sign_extended)) {
if (left_sign_extended == right_sign_extended) {
return Asm().Equal(UndoWord32ToWord64Conversion(left),
UndoWord32ToWord64Conversion(right),
WordRepresentation::Word32());
}
}
}
}
}
return Next::ReduceEqual(left, right, rep);