Snap for 4486962 from 564fd39d34f27fb87978907d2f3a9083ff10ef78 to pi-release

Change-Id: I1a5332a8ca0ecf7c251c5234b75a12d0f141cab8
diff --git a/dx/src/com/android/dx/Version.java b/dx/src/com/android/dx/Version.java
index 239270f..8bc56d1 100644
--- a/dx/src/com/android/dx/Version.java
+++ b/dx/src/com/android/dx/Version.java
@@ -21,5 +21,5 @@
  */
 public class Version {
     /** {@code non-null;} version string */
-    public static final String VERSION = "1.15";
+    public static final String VERSION = "1.16";
 }
diff --git a/dx/src/com/android/dx/ssa/SsaBasicBlock.java b/dx/src/com/android/dx/ssa/SsaBasicBlock.java
index 9c2137f..0ac618b 100644
--- a/dx/src/com/android/dx/ssa/SsaBasicBlock.java
+++ b/dx/src/com/android/dx/ssa/SsaBasicBlock.java
@@ -566,6 +566,13 @@
      * @param source move source
      */
     public void addMoveToEnd(RegisterSpec result, RegisterSpec source) {
+        /*
+         * Check that there are no other successors otherwise we may
+         * insert a move that affects those (b/69128828).
+         */
+        if (successors.cardinality() > 1) {
+            throw new IllegalStateException("Inserting a move to a block with multiple successors");
+        }
 
         if (result.getReg() == source.getReg()) {
             // Sometimes we end up with no-op moves. Ignore them here.
diff --git a/dx/src/com/android/dx/ssa/SsaConverter.java b/dx/src/com/android/dx/ssa/SsaConverter.java
index 1fd6f78..a7d044c 100644
--- a/dx/src/com/android/dx/ssa/SsaConverter.java
+++ b/dx/src/com/android/dx/ssa/SsaConverter.java
@@ -254,9 +254,12 @@
 
     /**
      * Returns {@code true} if block and successor need a Z-node
-     * between them. Presently, this is {@code true} if the final
-     * instruction has any sources or results and the current
+     * between them. Presently, this is {@code true} if either:
+     * <p><ul>
+     * <li> there is a critical edge between block and successor.
+     * <li> the final instruction has any sources or results and the current
      * successor block has more than one predecessor.
+     * </ul></p>
      *
      * @param block predecessor node
      * @param succ successor node
@@ -267,6 +270,16 @@
         ArrayList<SsaInsn> insns = block.getInsns();
         SsaInsn lastInsn = insns.get(insns.size() - 1);
 
+        // This is to address b/69128828 where the moves associated
+        // with a phi were being propagated along a critical
+        // edge. Consequently, the move instruction inserted was
+        // positioned before the first instruction in the predecessor
+        // block. The generated bytecode was rejected by the ART
+        // verifier.
+        if (block.getSuccessors().cardinality() > 1 && succ.getPredecessors().cardinality() > 1) {
+            return true;
+        }
+
         return ((lastInsn.getResult() != null)
                     || (lastInsn.getSources().size() > 0))
                 && succ.getPredecessors().cardinality() > 1;