Merge V8 5.3.332.45.  DO NOT MERGE

Test: Manual

FPIIM-449

Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc
index 477f139..4753d15 100644
--- a/src/compiler/move-optimizer.cc
+++ b/src/compiler/move-optimizer.cc
@@ -24,16 +24,38 @@
   }
 };
 
-struct OperandCompare {
-  bool operator()(const InstructionOperand& a,
-                  const InstructionOperand& b) const {
-    return a.CompareCanonicalized(b);
-  }
-};
-
 typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap;
 typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet;
 
+bool Blocks(const OperandSet& set, const InstructionOperand& operand) {
+  if (set.find(operand) != set.end()) return true;
+  // Only FP registers on archs with non-simple aliasing need extra checks.
+  if (!operand.IsFPRegister() || kSimpleFPAliasing) return false;
+
+  const LocationOperand& loc = LocationOperand::cast(operand);
+  MachineRepresentation rep = loc.representation();
+  MachineRepresentation other_fp_rep = rep == MachineRepresentation::kFloat64
+                                           ? MachineRepresentation::kFloat32
+                                           : MachineRepresentation::kFloat64;
+  const RegisterConfiguration* config = RegisterConfiguration::Turbofan();
+  if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) {
+    // Overlap aliasing case.
+    return set.find(LocationOperand(loc.kind(), loc.location_kind(),
+                                    other_fp_rep, loc.register_code())) !=
+           set.end();
+  }
+  // Combine aliasing case.
+  int alias_base_index = -1;
+  int aliases = config->GetAliases(rep, loc.register_code(), other_fp_rep,
+                                   &alias_base_index);
+  while (aliases--) {
+    int aliased_reg = alias_base_index + aliases;
+    if (set.find(LocationOperand(loc.kind(), loc.location_kind(), other_fp_rep,
+                                 aliased_reg)) != set.end())
+      return true;
+  }
+  return false;
+}
 
 int FindFirstNonEmptySlot(const Instruction* instr) {
   int i = Instruction::FIRST_GAP_POSITION;
@@ -138,8 +160,8 @@
   ParallelMove* from_moves = from->parallel_moves()[0];
   if (from_moves == nullptr || from_moves->empty()) return;
 
-  ZoneSet<InstructionOperand, OperandCompare> dst_cant_be(local_zone());
-  ZoneSet<InstructionOperand, OperandCompare> src_cant_be(local_zone());
+  OperandSet dst_cant_be(local_zone());
+  OperandSet src_cant_be(local_zone());
 
   // If an operand is an input to the instruction, we cannot move assignments
   // where it appears on the LHS.
@@ -172,7 +194,7 @@
   // destination operands are eligible for being moved down.
   for (MoveOperands* move : *from_moves) {
     if (move->IsRedundant()) continue;
-    if (dst_cant_be.find(move->destination()) == dst_cant_be.end()) {
+    if (!Blocks(dst_cant_be, move->destination())) {
       MoveKey key = {move->source(), move->destination()};
       move_candidates.insert(key);
     }
@@ -187,7 +209,7 @@
       auto current = iter;
       ++iter;
       InstructionOperand src = current->source;
-      if (src_cant_be.find(src) != src_cant_be.end()) {
+      if (Blocks(src_cant_be, src)) {
         src_cant_be.insert(current->destination);
         move_candidates.erase(current);
         changed = true;