Fix a bug in the handling of moves in register allocator.

Change-Id: Iaf1f34b0bece4f252290a97c3b73cc06e365985a
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index 7862611..9ba75b8 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -796,6 +796,10 @@
       // This is a parallel move for connecting siblings in a same block. We need to
       // differentiate it with moves for connecting blocks, and input moves.
       if (previous->GetLifetimePosition() != position) {
+        // If the previous instruction of the previous instruction is not a parallel
+        // move, we have to insert the new parallel move before the input or connecting
+        // block moves.
+        at = previous;
         previous = previous->GetPrevious();
       }
     }
diff --git a/test/408-move-bug/expected.txt b/test/408-move-bug/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/408-move-bug/expected.txt
diff --git a/test/408-move-bug/info.txt b/test/408-move-bug/info.txt
new file mode 100644
index 0000000..27a3dbc
--- /dev/null
+++ b/test/408-move-bug/info.txt
@@ -0,0 +1,2 @@
+Regression test for the register allocator in the optimizing
+compiler. Input moves where being overridden by sibling moves.
diff --git a/test/408-move-bug/src/Main.java b/test/408-move-bug/src/Main.java
new file mode 100644
index 0000000..420298b
--- /dev/null
+++ b/test/408-move-bug/src/Main.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+
+  public static void main(String[] args) {
+    crash();
+    npe();
+  }
+
+  static void crash() {
+    boolean b = baz();
+    // Create many objects to starve registers.
+    Main foo1 = create();
+    Main foo2 = create();
+    Main foo3 = create();
+    Main foo4 = create();
+    foo1.otherField = null;
+    // On X86, we would force b to be in a byte register, which
+    // would generate moves. This code exposed a bug in the
+    // register allocator, where an input move was not just before
+    // the instruction itself, and its destination was overridden
+    // by another value.
+    foo1.field = b;
+    foo2.field = b;
+    foo3.field = b;
+    foo4.field = b;
+    foo1.lastField = b;
+  }
+
+  // Similar to `crash` but generated an NPE.
+  static void npe() {
+    boolean b = baz();
+    Main foo1 = create();
+    Main foo2 = create();
+    Main foo3 = create();
+    Main foo4 = create();
+    foo1.field = b;
+    foo2.field = b;
+    foo3.field = b;
+    foo4.field = b;
+    foo1.lastField = b;
+  }
+
+  static Main create() {
+    return new Main();
+  }
+
+  static boolean baz() {
+    return false;
+  }
+
+  boolean field;
+  Object otherField;
+  boolean lastField;
+}