[instruction-selector-x64] Optimize truncating loads

Change-Id: Ia970b1281d73289812c4f83c722eea87c31863ba
Bug: v8:8344
Reviewed-on: https://chromium-review.googlesource.com/c/1304534
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57088}
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index cad689f..5555da79 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -536,6 +536,43 @@
 
 namespace {
 
+bool TryMergeTruncateInt64ToInt32IntoLoad(InstructionSelector* selector,
+                                          Node* node, Node* load) {
+  if (load->opcode() == IrOpcode::kLoad && selector->CanCover(node, load)) {
+    LoadRepresentation load_rep = LoadRepresentationOf(load->op());
+    MachineRepresentation rep = load_rep.representation();
+    InstructionCode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl;
+        break;
+      case MachineRepresentation::kWord32:
+      case MachineRepresentation::kWord64:
+      case MachineRepresentation::kTaggedSigned:
+      case MachineRepresentation::kTagged:
+        opcode = kX64Movl;
+        break;
+      default:
+        UNREACHABLE();
+        return false;
+    }
+    X64OperandGenerator g(selector);
+    InstructionOperand outputs[] = {g.DefineAsRegister(node)};
+    size_t input_count = 0;
+    InstructionOperand inputs[3];
+    AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
+        node->InputAt(0), inputs, &input_count);
+    opcode |= AddressingModeField::encode(mode);
+    selector->Emit(opcode, 1, outputs, input_count, inputs);
+    return true;
+  }
+  return false;
+}
+
 // Shared routine for multiple 32-bit shift operations.
 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic?
 void VisitWord32Shift(InstructionSelector* selector, Node* node,
@@ -1359,6 +1396,12 @@
         }
         break;
       }
+      case IrOpcode::kLoad: {
+        if (TryMergeTruncateInt64ToInt32IntoLoad(this, node, value)) {
+          return;
+        }
+        break;
+      }
       default:
         break;
     }