Commit 59c55c1c authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

[turbofan][x64] Avoid TruncateInt64ToInt32 when possible

Turbofan optimizes TruncateInt64ToInt32 by trying to merge it into
its input. This can avoid generating a movl instruction. However, when
the input is BitcastTaggedToWordForTagAndSmiBits, it fails to apply
this optimization and this results in a redundant move:

  Turbofan IR:
  149: Load[kRepTaggedSigned|kTypeInt32](...)
  150: BitcastTaggedToWordForTagAndSmiBits(149)
  151: TruncateInt64ToInt32(150)
  152: Word32And(151, 558)

  Assembly:
  103  movl r11,[r8+0x1f]
  107  movl r11,r11
  10a  andl r11,0x4

This CL fixes this and avoids the redundant movl instruction.

Change-Id: Id59d1ce1e3b139344f750e903726dd9f338cfdba
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3787681Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Cr-Commit-Position: refs/heads/main@{#82156}
parent e553a440
...@@ -884,55 +884,50 @@ void InstructionSelector::VisitStackPointerGreaterThan( ...@@ -884,55 +884,50 @@ void InstructionSelector::VisitStackPointerGreaterThan(
namespace { namespace {
bool TryMergeTruncateInt64ToInt32IntoLoad(InstructionSelector* selector, void TryMergeTruncateInt64ToInt32IntoLoad(InstructionSelector* selector,
Node* node, Node* load) { Node* node, Node* load) {
if ((load->opcode() == IrOpcode::kLoad || LoadRepresentation load_rep = LoadRepresentationOf(load->op());
load->opcode() == IrOpcode::kLoadImmutable) && MachineRepresentation rep = load_rep.representation();
selector->CanCover(node, load)) { InstructionCode opcode;
LoadRepresentation load_rep = LoadRepresentationOf(load->op()); switch (rep) {
MachineRepresentation rep = load_rep.representation(); case MachineRepresentation::kBit: // Fall through.
InstructionCode opcode; case MachineRepresentation::kWord8:
switch (rep) { opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl;
case MachineRepresentation::kBit: // Fall through. break;
case MachineRepresentation::kWord8: case MachineRepresentation::kWord16:
opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl;
break; break;
case MachineRepresentation::kWord16: case MachineRepresentation::kWord32:
opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; case MachineRepresentation::kWord64:
break; case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kWord32: case MachineRepresentation::kTagged:
case MachineRepresentation::kWord64: case MachineRepresentation::kCompressed: // Fall through.
case MachineRepresentation::kTaggedSigned: opcode = kX64Movl;
case MachineRepresentation::kTagged: break;
case MachineRepresentation::kCompressed: // Fall through. default:
opcode = kX64Movl; UNREACHABLE();
break; }
default: X64OperandGenerator g(selector);
UNREACHABLE();
}
X64OperandGenerator g(selector);
#ifdef V8_IS_TSAN #ifdef V8_IS_TSAN
// On TSAN builds we require one scratch register. Because of this we also // On TSAN builds we require one scratch register. Because of this we also
// have to modify the inputs to take into account possible aliasing and use // have to modify the inputs to take into account possible aliasing and use
// UseUniqueRegister which is not required for non-TSAN builds. // UseUniqueRegister which is not required for non-TSAN builds.
InstructionOperand temps[] = {g.TempRegister()}; InstructionOperand temps[] = {g.TempRegister()};
size_t temp_count = arraysize(temps); size_t temp_count = arraysize(temps);
auto reg_kind = OperandGenerator::RegisterUseKind::kUseUniqueRegister; auto reg_kind = OperandGenerator::RegisterUseKind::kUseUniqueRegister;
#else #else
InstructionOperand* temps = nullptr; InstructionOperand* temps = nullptr;
size_t temp_count = 0; size_t temp_count = 0;
auto reg_kind = OperandGenerator::RegisterUseKind::kUseRegister; auto reg_kind = OperandGenerator::RegisterUseKind::kUseRegister;
#endif // V8_IS_TSAN #endif // V8_IS_TSAN
InstructionOperand outputs[] = {g.DefineAsRegister(node)}; InstructionOperand outputs[] = {g.DefineAsRegister(node)};
size_t input_count = 0; size_t input_count = 0;
InstructionOperand inputs[3]; InstructionOperand inputs[3];
AddressingMode mode = g.GetEffectiveAddressMemoryOperand( AddressingMode mode =
node->InputAt(0), inputs, &input_count, reg_kind); g.GetEffectiveAddressMemoryOperand(load, inputs, &input_count, reg_kind);
opcode |= AddressingModeField::encode(mode); opcode |= AddressingModeField::encode(mode);
selector->Emit(opcode, 1, outputs, input_count, inputs, temp_count, temps);
return true; selector->Emit(opcode, 1, outputs, input_count, inputs, temp_count, temps);
}
return false;
} }
// Shared routine for multiple 32-bit shift operations. // Shared routine for multiple 32-bit shift operations.
...@@ -1891,7 +1886,14 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -1891,7 +1886,14 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
// have to satisfy that condition. // have to satisfy that condition.
X64OperandGenerator g(this); X64OperandGenerator g(this);
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
if (CanCover(node, value)) { bool can_cover = false;
if (value->opcode() == IrOpcode::kBitcastTaggedToWordForTagAndSmiBits) {
can_cover = CanCover(node, value) && CanCover(value, value->InputAt(0));
value = value->InputAt(0);
} else {
can_cover = CanCover(node, value);
}
if (can_cover) {
switch (value->opcode()) { switch (value->opcode()) {
case IrOpcode::kWord64Sar: case IrOpcode::kWord64Sar:
case IrOpcode::kWord64Shr: { case IrOpcode::kWord64Shr: {
...@@ -1909,10 +1911,8 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { ...@@ -1909,10 +1911,8 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
} }
case IrOpcode::kLoad: case IrOpcode::kLoad:
case IrOpcode::kLoadImmutable: { case IrOpcode::kLoadImmutable: {
if (TryMergeTruncateInt64ToInt32IntoLoad(this, node, value)) { TryMergeTruncateInt64ToInt32IntoLoad(this, node, value);
return; return;
}
break;
} }
default: default:
break; break;
......
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